Skip to Content
SDKJavaScript / Браузер

JavaScript / Браузерный SDK

@lartech/infraio-checkout-js — единственный SDK, который мы публикуем сегодня. Он работает в браузере и открывает наш размещённый checkout. Backend-SDK (Node, Go, Python) в roadmap; до их публикации общайтесь с gateway напрямую — см. Быстрый старт для хелпера HMAC-подписи.

  • Текущая версия: 0.1.1-beta.17 (pre-1.0; возможны минорные ломки)
  • Форматы: ESM (index.js), CJS (index.cjs), IIFE (index.global.js)
  • Типы в комплекте (index.d.ts)
  • Нулевые runtime-peers — нет React, jQuery или других зависимостей

Серверной точки входа нет. Хелперы проверки подписи для webhook’ов не поставляются в бандле — реализуйте их сами через crypto (на странице проверки подписи есть copy-paste код на 4 языках).

Установка

npm install @lartech/infraio-checkout-js

loadInfraIo(publicKey, options?)

Возвращает Promise<InfraIoInstance>.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere", { // Опционально. Переопределяйте только при указании на non-prod окружение. checkoutUrl: "https://checkout-dev.infraio.xyz", });
ПараметрТипОбязательныйЗаметки
publicKeystringДолжен соответствовать pk_(live|test)_…
options.checkoutUrlstringПереопределение базового URL checkout. По умолчанию: https://checkout.infraio.xyz. Соответствующий URL gateway определяется страницей checkout в runtime — каждый деплой checkout(-dev).infraio.xyz несёт свой compile-time NEXT_PUBLIC_API_URL, поэтому выбор правильного hostname здесь автоматически выбирает правильный backend. Отдельной опции gatewayUrl нет.

sdk.checkout({ … })

Открывает размещённый checkout. Возвращает void (используйте callback’и для состояния).

ПолеТипОбязательноеЗаметки
sessionIdstringsession_key, возвращённый POST /b2b/v1/checkout-sessions/quick
checkoutUrlstringПолный URL, возвращённый тем же endpoint’ом. Если опущен, SDK конструирует его из checkoutUrl loadInfraIo() (или дефолта) + sessionId
mode"popup" | "redirect" | "embed"По умолчанию "popup"
containerstring | HTMLElementтолько embedCSS-селектор или DOM-элемент, куда монтируется iframe
widthnumberТолько popup. По умолчанию 560. Ограничен [320, 1280]
heightnumberТолько popup. По умолчанию 780. Ограничен [400, 1000]
timeoutMsnumberТолько popup. Таймаут загрузки iframe. По умолчанию 30000. Передайте 0, чтобы отключить
localestringBCP-47 тег, передаётся как ?locale= на страницу checkout (en, ja, zh-CN, zh-TW)
hideSummarybooleanСкрыть колонку со сводкой заказа. По умолчанию false
hideHeaderbooleanСкрыть заголовок InfraIO и встроенную кнопку wallet-connect. По умолчанию false. Сочетайте с walletAddress для полного white-label
walletAddressstringПредподключить кошелёк покупателя. Требует onSignRequest
walletChainIdnumberEVM chain ID для предподключённого кошелька
onReady() => voidСрабатывает, когда iframe становится интерактивным. Только popup/embed
onSignRequest(req: { method: string; params: unknown[] }) => Promise<string>при заданном walletAddressSDK проксирует wallet RPC к вашему обработчику; возвращайте подписанный hex
onSuccess({ sessionId }) => voidСрабатывает при успешной оплате. Не авторитетно — webhook авторитетен
onCancel() => voidСрабатывает, когда покупатель закрывает popup/embed без оплаты
onError(err: InfraIoError) => voidСрабатывает при сбое загрузки iframe (режимы popup + embed). Некорректные аргументы выбрасываются синхронно, они не доставляются сюда. У redirect нет runtime-уровня ошибок — сбой наблюдается на редиректнутой странице.

onSuccess не авторитетен. Он может сработать, даже когда webhook позже определит, что платёж не прошёл (реорги testnet’а, тайминги на стороне покупателя). Используйте его только для UX (показать «Спасибо!», редирект). Всегда подтверждайте через webhook до обработки заказа.

sdk.close()

Программно закрыть открытый popup или embed. No-op для режима redirect.

sdk.checkout({ sessionId, mode: "popup", /* … */ }); // позже, например когда пользователь уходит со страницы sdk.close();

sdk.openRefundRequest({ … })

Открывает размещённую форму refund-request для одноразового токена, который ваш backend выпустил через POST /b2b/v1/merchants/{merchant_id}/refund-requests. Покупатель вводит адрес назначения возврата + причину + (опциональные) метаданные на нашей странице; ваша страница только обрабатывает жизненный цикл открыть/закрыть. Возвращает функцию close() — вызовите её, чтобы программно закрыть popup или открепить embed iframe. В режиме redirect возвращаемая функция — no-op.

Форма живёт по адресу https://checkout.infraio.xyz/refund-request/:token. Этот метод просто обёртывает этот URL в popup / redirect / embed, чтобы покупатель никогда не покидал ваш домен (в popup / embed) или возвращался автоматически (в redirect). Endpoint, на который обращается ваш backend для выпуска токена — POST /b2b/v1/merchants/{merchant_id}/refund-requests — подписан HMAC вашим secret-ключом, та же аутентификация, что и у остального B2B-уровня. См. Концепции → Возвраты.

import { loadInfraIo } from "@lartech/infraio-checkout-js"; const sdk = await loadInfraIo("pk_live_yourkeyhere"); // Выпустите токен на сервере, затем передайте в SDK в браузере. const { token } = await fetch("/api/mint-refund-token", { method: "POST" }).then(r => r.json()); const close = sdk.openRefundRequest({ token, mode: "popup", onSuccess: ({ linkToken, refundId }) => { // Покупатель отправил форму. // linkToken → /r/:linkToken страница статуса (поделитесь с покупателем). // refundId → используйте с B2B API для approve / reject. window.location.href = `/r/${linkToken}`; }, onCancel: () => { /* покупатель закрыл без отправки */ }, }); // Программно закрыть popup позже, если нужно: // close();
ПолеТипОбязательноеЗаметки
tokenstringТокен rfqt_…, возвращённый POST /b2b/v1/merchants/{merchant_id}/refund-requests
mode"popup" | "redirect" | "embed"По умолчанию "popup". Та же семантика поверхности, что и у sdk.checkout() — см. Заметки по режимам
containerstring | HTMLElementтолько embedCSS-селектор или DOM-элемент, куда монтируется iframe
localestringBCP-47 тег, передаётся как ?locale= (en, ja, zh-CN, zh-TW)
hideHeaderbooleanСкрыть заголовок InfraIO внутри iframe. В popup/embed SDK рисует собственный modal chrome, поэтому заголовок страницы обычно лишний. По умолчанию false
hideSummarybooleanСкрыть колонку Order Summary, показав только форму возврата. По умолчанию false
walletAddressstringПредзаполнить поле адреса назначения (?wallet_address=). Позволяет мерчанту, уже знающему кошелёк покупателя, пропустить ручной ввод
onSuccess(data: { linkToken: string; refundId: string }) => voidСрабатывает после того, как покупатель отправил форму. linkToken/r/:linkToken страница статуса для покупателя. refundId → используйте с B2B API для approve / reject
onCancel() => voidСрабатывает, когда покупатель закрывает popup/embed без отправки
onError(err: InfraIoError) => voidСрабатывает при сбое загрузки iframe или некорректных аргументах. Истечение/отмена токена обрабатывается размещённой страницей, не через onError

Состояния токена, всплывающие через onError

Если покупатель открывает устаревший токен, страница сама обрабатывает отображение (отрисовывает приглашение «Истёк — запросите новую ссылку» и т. д.), и SDK не отправляет onError для этих случаев — покупатель внутри потока формы, и вашему коду не нужно реагировать. onError срабатывает только для того, на что ваш код может реагировать (плохие аргументы, сетевой сбой при загрузке iframe).

openRefundRequest записывает намерение возврата — он не двигает средства. После onSuccess строка возврата в PENDING (или APPROVED, если ваша мерчантская конфигурация авто-одобряет клиентские возвраты). Вам всё ещё нужно подписать и транслировать on-chain перевод с вашего мерчантского кошелька, затем отправить tx hash на POST /b2b/v1/refunds/:id/submit-tx. См. Концепции → Возвраты для полного жизненного цикла.

Класс ошибки

import { InfraIoError } from "@lartech/infraio-checkout-js"; sdk.checkout({ sessionId, onError: (err: InfraIoError) => { switch (err.code) { case "invalid_request_error": /* плохой sessionId / аргументы */ break; case "iframe_load_error": /* iframe не загрузился */ break; case "iframe_timeout_error": /* превышен timeoutMs */ break; case "already_open_error": /* другой checkout уже открыт */ break; case "network_error": /* временная сетевая проблема при общении с origin checkout */ break; case "api_error": /* backend вернул non-2xx для вызова, инициированного SDK */ break; } }, });

sdk.openRefundRequest() выбрасывает только invalid_request_error (отсутствующий или некорректный токен / аргументы), синхронно. iframe_load_error (iframe refund-request не загрузился) доставляется асинхронно через onError, а не выбрасывается. Он не отправляет iframe_timeout_error или already_open_error — у popup refund-request нет load-timeout, и разрешено несколько одновременных popup’ов.

Заметки по режимам

  • Центрированный overlay с тёмным полупрозрачным backdrop
  • z-index: 2147483647 (максимум int32) — сидит над всем остальным
  • Скролл body заблокирован пока открыт; восстанавливается при закрытии
  • Кнопка закрытия получает начальный фокус; Tab захвачен в popup
  • Закрывается через: кнопку закрытия, Escape, клик снаружи, sdk.close(). Все они вызывают onCancel
  • Страница checkout может запросить resize через postMessage — SDK обрезает в пределах ограничений width/height

Redirect

  • Жёсткая навигация через window.location.href
  • Автоматически добавляет ?return_url=<current-page>, чтобы покупатель вернулся туда, откуда пришёл. Если success_url / cancel_url в сессии уже покрывают это, round-trip игнорирует return_url

Embed

  • iframe с allow="payment; clipboard-write" (директивы HTML5 Feature Policy — не атрибут sandbox). iframe обслуживается с origin checkout, поэтому wallet popup’ы и запись в clipboard со стороны покупателя работают без дополнительного opt-in.
  • Ширина контейнера 100%; высота авто-настраивается через INFRAIO_RESIZE postMessage, ограничена [200, 2000]px
  • Никакой CSS-изоляции за границей iframe — стили вашей родительской страницы не протекают внутрь
  • Всегда подключайте onReady, чтобы скрыть собственный loading-state, когда checkout становится интерактивным

TypeScript

Все типы в комплекте. Самые полезные экспорты:

import type { CheckoutOptions, RefundRequestOptions, LoadOptions, InfraIoInstance, InfraIoErrorCode, } from "@lartech/infraio-checkout-js"; import { loadInfraIo, InfraIoError, VERSION } from "@lartech/infraio-checkout-js";

VERSION — строка версии самого SDK — полезна в bug-репортах.

Что дальше

  • Обёртки для React / Vue — запланированы на пост-launch итерацию, как только vanilla JS-поверхность стабилизируется по пилотным мерчантам. Vanilla SDK сегодня нормально работает внутри React; обёртки просто уберут ручной useRef + lifecycle-боилерплейт.
  • Возобновление сессии между вкладками — открыть checkout во вкладке A, завершить в B. Полезно, когда покупатель идёт по magic-link посреди потока. В планах на следующий минорный релиз.
  • Темизация через CSS-переменные — показать небольшой набор design-токенов (радиус, акцентный цвет) на iframe, чтобы мерчанты могли соответствовать своему бренду без форка страницы.
  • Серверные хелперы — крошечный пакет @lartech/infraio-server, экспортирующий verifyWebhook() + signedRequest(), чтобы backend-коду не приходилось копировать ритуал HMAC. До его выпуска на странице проверки подписи есть готовые реализации на TypeScript, Go, Python и Ruby.