Перейти к основному содержимому

Web3-payments

Описание

Модуль web3-payments.module.ts на основном бекенде предназначен для приема платежей в криптовалюте. Логика модуля является реюзабельной и его можно сконфигурировать и использовать под платежи в любом продукте.

Сами платежи проходят через смарт контракт MagnetPaymentsManger

Логика работы

Если кратко описать процесс платежей то он выглядит так

Создание инвойса (может быть любой триггер в продуктах, например прокачка нфт)→ получение с фронтенда подписи и данных для транзакции → используя полученные параметры оплата через MagnetPaymentsManger → обработка платежа кроном check-payments.job.ts

1. Создание инвойса

Структура инвойса выглядит следующим образом:

invoice.schema.ts
{
userId: number; // user.id пользователя из mysql

action: InvoiceActions; // что будет сделано после оплаты

status: InvoiceStatus; // статус оплачено / ждет оплаты

amount: string; // сумма для оплаты с decimals

tokenAddress?: string; // токен для оплаты или ZeroAddress для оплаты в валюте сети

data?: InvoiceData; // дополнительные данные для обработки оплаты
}

Каждый инвойс должен быть привязан к конкретному продукту или действию, это определяет то, какие действия будут выполнены во время обработки платежа. Это конфигурируется в web3-payments.types.ts

InvoiceActions - определяет то какое действие будет совершено после успешной оплаты

InvoiceData - возможные дополнительные параметры которые необходимы для обработки платежа

InvoiceActionToData - мапинг типов InvoiceActions -> InvoiceData чтобы при обработке корректно определять тип параметров из invoice.data

Инвойс должен создаваться по тригеру продукта, например, нужно чтобы юзер оплатил повышение уровня доступа NFT, тогда используется следующий паттерн:

В web3-payments.types.ts добавляется тип для InvoiceData, например:

export type NftProductUpdateInvoiceData = {
nftId: mongoose.Types.ObjectId;
updateField: keyof NftProductParams;
level: number;
};

Так будет выглятеть метод создания инвойса:

public async foo(): {invoiceId: string} {
// какая-то логика нфт

const data: NftProductUpdateInvoiceData = {
...
}

const invoice = await this.web3PaymentsService.getOrCreateInvoice({
...
action: InvoiceActions.NFT_PRODUCT_UPDATE,
data,
});

return {
invoiceId: invoice._id.toString(),
};
}

invoiceId необходимо вернуть юзеру на фронтенд для последующей оплаты

2. Оплата инвойса

Для оплаты инвойса необходимо получить данные для транзакции через ендпоинт

GET /web3-payments/invoice/signature-to-pay/:invoiceId используя invoiceId из шага 1

Далее нужно с фронтенда вызвать функцию pay из контракта MagnetPaymentsManger и передать в нее полученные параметры. Если оплата в валюте сети, будет необходимо дополнительно передать value

3. Обработка платежа

После успешного завершения транзакции из пункта 2, крон из check-payments.job.ts подтягивает ивент платежа и вызывает метод handlePaymentCompleted из web3-payments.service.ts который в свою очередь выполняет соответствующие действия зависимо от того, какой action был указан при создании инвойса.