Skip to content

Payment Flow

Serhii edited this page Sep 25, 2020 · 1 revision

Minter Link Payment Flow

Шаг нулевой: подготовить БД (back end)

Создадим модели для товаров и заказов. У каждого товара буду поля price и coin, у заказа — itemId и hash.

Шаг первый: запросить orderId (front end)

Сделаем запрос на backend c itemId товара, который мы хотим оплатить и получим назад уникальный orderId заказа.

Порядок действия такой:

  • проверяем наличие расширения (установлено или нет)
  • проверяем статус расширения (разблокировано или нет)
  • если кошелек разблокирован — делаем запрос на backend, получаем назад orderId

Шаг третий: сформировать запрос (front end)

Сформируем paymentData, чтобы сделать запрос к расширению: payload (ID заказа), адрес для оплаты, сумму и монету оплаты.

Шаг четвертый: отправить запрос на оплату (front end)

Отправим запрос в расширение, куда передадим paymentData При успешной оплате получим назад хеш транзакции в блокчейне.

Шаг пятый: подготовим обработчик транзакций (back end)

На стороне сервера создадим сервис, который будет слушать все транзакции из блокчейна, нас интересуют транзакции с типом 0x01 (Send) и адресатом — нашим кошельком, который мы указали в четвертом шаге.

У каждой транзакции мы проверим payload и ищем там наш orderId. Если транзакция найдена, у нее совпадает адрес, payload, сумма и монета — обновим у заказа hash.

Примеры кода

HTML

<!-- Расширение не установлено -->
<p if="!isMinterLinkInstalled">Minter Link is not installed</p>

<!-- Расширение заблокировано -->
<p if="isMinterLinkInstalled && !isMinterLinkUnlocked">Minter Link is locked</p>

<button onclick="pay(1)" if="isMinterLinkInstalled && isMinterLinkUnlocked">Purchase</button>

JavaScript

import MinterConnect, { MinterLinkObservableProps } from 'minter-connect'

let isMinterLinkInstalled = false
let isMinterLinkUnlocked = false
let minterPublicAddress = ''
let isAuthenticated = false

// Устанавливаем соединение с расширением
const minterConnect = new MinterConnect('My awesome application')

// Подписываемся на события
minterConnect.subscribe(MinterLinkObservableProps.IsInstalled, (value) => {
  isMinterLinkInstalled = value
})

minterConnect.subscribe(MinterLinkObservableProps.IsUnlocked, (value) => {
  isMinterLinkUnlocked = value
})

async function pay (itemId) {
  if (!isMinterLinkInstalled) return
  if (!isMinterLinkUnlocked) return

  try {
    const orderId = await api.makeOrder(itemId)
    const paymentData = {
      address: 'Mx...',          // наш адрес для оплаты
      amount: '999',             // цена
      coin: 'BIP',               // монета
      payload: response.data.id  // orderId
    }
    
    await minterConnect.paymentRequest(paymentData)
  } catch (e) {
    console.error(e)
  }
}

Node.JS

async function makeOrder (itemId) {
  const item = await getItemById(itemId)
  const order = new Order({
    itemId,
    price: item.price,
    coin: item.coin
  })

  order.save()

  return order.id
}

// Функция, которая будет перебирать транзакции из блокчейна
async function handleTransaction (transaction) {
  // Тип транзакции должен быть Send
  if (transcation.type !== '0x01') return
  // Адресат должен быть нашим кошельком
  if (transcation.data.to !== 'Mx...') return

  const orderId = transaction.payload.trim()
  const order = await getOrderById(orderId)

  // Несуществующий заказ
  if (!order) return
  // Заказ уже оплачен
  if (order.hash) return
  // Сумма не совпадает
  if (order.price !== tx.data.value) return
  // Монета не совпадает
  if (order.coin !== tx.data.coin) return

  // Все хорошо, это наш заказ!
  order.hash = transaction.hash
  order.save()
  
  // Дальше ваша бизнес логика: отправляем письмо об успешной оплате, начисляем бонусные баллы, уведомляем frontend о смене статуса заказа и т.д.
}

async function getItemById (itemId) {
  return db.getItemById(itemId)
}

async function getOrderById (orderId) {
  return db.getOrderById(orderId)
}