CEX Pay's Payment Widget Client
CEX Pay's Payment Widget client library.
Builds
local
release/snapshot
Usage
Test Console
Для тестирование библиотеки разработана тест-консоль.
Запуск
npx ts-node test.manual/test-console.ts
Choose WidgetServiceClient implementation (1 - WidgetServiceClientMock, 2 - WidgetServiceClientImpl): 2
Creating an instance... done.
The application is ready to use. You will see all events in the console. Also you may raw JSON to call invoke.
....
Embed into a web application
Для локального тестирования используется mock реализация клиента. Подключение библиотеки выполняется с помощью следующей команды:
yarn add @cexiolabs/cexpay.gate.widget.client-mock
Использование библиотеки выглядит следующим образом:
JavaScript
const widgetClient = new WidgetServiceClientMock();
widgetClient.onStateChanged = async (state) => {
// do something with new state
};
TypeScript
const widgetClient: WidgetServiceClient = new WidgetServiceClientMock();
widgetClient.onStateChanged = async (state: WidgetServiceClient.State) => {
// do something with new state
};
Конструктор также принимает дополнительный параметр:
const widgetClient = new WidgetServiceClientMock(responseDelayMultiplier: 1);
Это число задаёт значение, на которое будет умножаться задержка всех команд,
которая равна 1 секунде.
Используйте этот параметр, чтобы сделать эмуляцию слабого интернет-соединения,
когда сервер отвечает не моментально, а лишь спустя какое-то время. Этот параметр
повлияет на скорость ответа после вызова widgetClient.invoke(action)
.
Как уже сказано выше, вызов widgetClient.invoke(action)
запускает триггер
события widgetClient.onStateChanged
с задержкой в 1 секунду по умолчанию. Флоу
виджета получается следующий:
- Создаём инстанс класса
WidgetServiceClientMock
- Через секунду приходит обновление
widgetClient.onStateChanged
со страницейstate.step === CHOOSE_INPUT_CURRENCY
. Это означает, что рисуем страницу выбора валюты. - Как только валюта выбрана, отправляем её:
const selectedCurrency: string = "USDT"; // selected currency here
const selectedNetwork: string = "erc20"; // selected network here, optional, for multi-network currencies
await widgetClient.invoke({
step: "SELECT_INPUT_CURRENCY",
callbackMethodName: this.globalStateVariable.callbackMethodName,
fromCurrency: selectedCurrency,
fromNetwork: selectedNetwork
});
- Через секунду приходит обновление
widgetClient.onStateChanged
со страницейstate.step === ASK_FOR_EMAIL
. Это означает, что рисуем страницу ввода email. - Как только email введён, отправляем его:
const inputEmail = "email@example.com"; // input value here
await widgetClient.invoke({
step: "SET_EMAIL",
callbackMethodName: this.globalStateVariable.callbackMethodName,
email: inputEmail
});
- Через секунду приходит обновление
widgetClient.onStateChanged
со страницейstate.step === PROCESS_PAYMENT
. Это означает, что рисуем страницу с QR кодом и просьбой оплатить. - Поскольку у mock реализации отсутствует бэкенд, который следит за изменением
состояния оплаты по QR коду, нам необходимо вручную запросить смену страницы в
консоли разработчика в браузере.
Нам нужно найти глобально и вызвать метод
widgetClient.switchState("...")
. Например, для Vue.js SPA это будет выглядеть примерно так: https://stackoverflow.com/a/51848743 Поддерживаемые state значения, которые можно передать в этот метод, следующие:
- CHOOSE_INPUT_CURRENCY - окно выбора валюты
- ASK_FOR_EMAIL - окно ввода эл.почты
- PROCESS_PAYMENT - окно проведения оплаты с QR кодом
- PAYMENT_RECEIVE - окно получения платежа, частичного или полного, ожидание подтверждений от сети блокчейн
- PAYMENT_COMPLETED - окно успешного завершения ордера
Также хочу обратить внимание, что PAYMENT_RECEIVE эмулирует вызов сразу двух-трёх событий с задержкой в 10 секунд. Это сделано потому, что между AWAIT_DEPOSIT и COMPLETED есть промежуточные события EXCHANGE/EXCHANGED которые не имеют своей собственной страницы для отображения, поэтому при их возникновении всё ещё будет отображаться страница PAYMENT_RECEIVE, нужно чтобы код был к этому готов.
Для развертывания на сервере используется реализация клиента, которая уже
непосредственно общается через SignalR с бэкендом.
Использование библиотеки выглядит следующим образом:
JavaScript
const options = {
gatewayId: "...",
orderId: "order-123456",
baseApiUrl: "https://localhost:8443"
};
const widgetClient = new WidgetServiceClientImpl(options);
widgetClient.onStateChanged = async (state) => {
// do something with new state
};
// Client is listening to callbacks at the moment
// ...
await client.dispose(); // optional call, this method will disconnect from the server
TypeScript
const options: WidgetServiceClient.WidgetServiceClientOptions = {
gatewayId: "...",
orderId: "order-123456",
baseApiUrl: "https://localhost:8443"
};
const widgetClient: WidgetServiceClient = new WidgetServiceClient.WidgetServiceClientImpl(options);
widgetClient.onStateChanged = async (state: WidgetServiceClient.State) => {
// do something with new state
};
// Client is listening to callbacks at the moment
// ...
await client.dispose(); // optional call, this method will disconnect from the server