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

Интеграции

На странице

Low-Code SDK для JavaScript

Добавьте на страницу настраиваемую кнопку оплаты, выберите источник суммы и оформление и откройте Paymos без собственной формы.

Low-Code SDK позволяет встроить кнопку оплаты прямо на ваш сайт. При нажатии SDK определяет сумму, создаёт инвойс через публичный SDK-ключ (pk_...) и открывает форму оплаты — модальным окном в iframe или переходом на всю страницу.

Сниппет работает только в проекте, у которого способ подключения — Low-Code. Способ вы выбираете при создании проекта, и потом он не меняется; в проекте с любым другим способом POST /public/v1/sdk отвечает 403 embed_not_enabled.

Low-Code SDK — удобная обёртка над той же платёжной страницей, которую POST /v1/invoices возвращает в payment_url; в режиме iframe SDK открывает её с ?embed=true. Ручное перенаправление и ручное встраивание в iframe описаны на Платёжной странице.

SDK отправляет POST на https://paymos.io/public/v1/sdk — тот же origin, что отдаёт paymos-widget.js — и передаёт ключ в заголовке X-Sdk-Key.

Если сумма не определена, а вы передали pos_url, кнопка открывает Терминал по этому адресу — интерфейс с нампадом для ввода суммы вручную. Без pos_url клик без суммы завершается ошибкой и событием paymos:error.

Как это работает

  • 01Добавьте скрипт SDK и элемент для монтирования на страницу
  • 02Вызовите PaymosWidget.mount() с api_key, project_id и параметрами
  • 03Клиент нажимает кнопку
  • 04SDK определяет сумму (фиксированная, функция обратного вызова или селектор поля ввода)
  • 05Если сумма есть — SDK создаёт инвойс и открывает страницу оплаты
  • 06Если суммы нет, но задан pos_url — SDK открывает Терминал с нампадом по этому адресу
  • 07Если суммы нет и pos_url не задан — SDK выбрасывает ошибку и шлёт событие paymos:error
  • 08Оплата обрабатывается — вебхук отправляется на зарегистрированный URL вебхука

Установка

<script src="https://paymos.io/v1/paymos-widget.js"></script>
<div id="paymos-widget"></div>

Определение суммы

SDK определяет сумму в момент нажатия на кнопку, используя первый доступный источник:

  • 01amount — фиксированная десятичная строка в настройках. Подходит для страниц с одним товаром или фиксированной ценой.
  • 02get_amount() — функция обратного вызова, возвращающая сумму десятичной строкой. Используйте, когда итог вычисляется динамически (например, из корзины).
  • 03amount_selector — CSS-селектор, указывающий на элемент <input>. SDK читает его .value в момент клика. Удобно, когда сумму вводит сам клиент.

Если ни один из источников не вернул корректную положительную десятичную строку, SDK открывает Терминал по адресу из pos_url — нампад для ручного ввода суммы. Если pos_url не задан, клик завершается ошибкой PaymosWidget requires an amount, amountSelector, or price_id. и страница оплаты не открывается.

// Fixed price (price_id) — RECOMMENDED for fixed products.
// Create the price once in the dashboard; the server resolves the amount and
// currency from it, so a buyer cannot change them in DevTools. No amount in the embed.
PaymosWidget.mount('#paymos-widget', {
  api_key: 'YOUR_PUBLIC_KEY',
  price_id: 'price_YOUR_PRICE_ID'
});

// Fixed amount — client-supplied (editable in the browser; use for donations / free-amount)
PaymosWidget.mount('#paymos-widget', {
  api_key: 'YOUR_PUBLIC_KEY',
  project_id: 'prj_YOUR_PROJECT_ID',
  amount: '25.00',
  currency: 'USD'
});

// Dynamic amount — computed at click time
PaymosWidget.mount('#paymos-widget', {
  api_key: 'YOUR_PUBLIC_KEY',
  project_id: 'prj_YOUR_PROJECT_ID',
  get_amount: () => calculateCartTotal().toFixed(2),
  currency: 'USD'
});

// Input selector — reads value from an <input> element
PaymosWidget.mount('#paymos-widget', {
  api_key: 'YOUR_PUBLIC_KEY',
  project_id: 'prj_YOUR_PROJECT_ID',
  amount_selector: '#donation-amount',
  currency: 'USD'
});

Два режима интеграции

SDK предоставляет две точки входа. Выбирайте по задаче:

mount(selector, opts) — кнопку рисует SDK

SDK сам вставляет в указанный элемент готовую стилизованную кнопку оплаты (её текст берётся из параметра label, по умолчанию "Support with crypto"). Подходит для страниц с одним товаром, простых лендингов, виджетов донатов — везде, где не хочется писать CSS.

<script src="https://paymos.io/v1/paymos-widget.js"></script>
<div id="paymos-widget"></div>
<script>
  PaymosWidget.mount('#paymos-widget', {
    api_key: 'pk_live_…',
    project_id: 'prj_…',
    amount: '25.00',
    currency: 'USD',
    label: 'Support with crypto'
  });
</script>

open(opts) — кнопку рисуете вы, SDK открывает оверлей

Вы полностью владеете разметкой кнопки (ваша дизайн-система, ваш CSS, ваши иконки) и вызываете PaymosWidget.open(opts) из обработчика клика. Подходит для страниц с несколькими тарифами, корзин и собственных UI-фреймворков (React, Vue, Svelte).

<button id="buy-growth">Subscribe to Growth — $79/mo</button>
<script>
  document.getElementById('buy-growth').addEventListener('click', function () {
    PaymosWidget.open({
      api_key: 'pk_live_…',
      project_id: 'prj_…',
      amount: 79,
      currency: 'USD',
      client_id: 'plan:growth'
    });
  });
</script>

Оба режима обращаются к одному серверу, отправляют те же вебхуки и те же события в window. Разница только в том, кто отвечает за стили кнопки — на open() построена ссылка Открыть демо в дашборде (три независимо оформленные кнопки на одном общем оверлее).

Когда использовать SDK, а когда REST API

Low-Code SDK — браузерный инструмент. Он ставит кнопку оплаты на статическую HTML-страницу, без серверной части. Подходит для:

  • пожертвований и чаевых (сумму выбирает клиент)
  • касс и точек продаж (сумму вводит сотрудник)
  • виджетов с произвольной суммой («заплатите сколько хотите»)
  • демонстраций в тестовой и промежуточной среде

Для случаев, где цена фиксирована на вашей стороне (подписки, цифровые товары, физические заказы, курсы, лицензии), сумма в примере ниже редактируется из инструментов разработчика в браузере — клиент может отправить 0.01 за тариф 99 $. В таких случаях создавайте инвойс через REST API на сервере, секретным ключом. SDK тут ни при чём: так устроена любая оплата, начинающаяся в браузере (Stripe, LemonSqueezy, PayPal) — публичный ключ на странице, секретный на сервере.

Параметры

Параметр Тип Обязателен Описание
api_key string Да Публичный SDK-ключ из дашборда (pk_...)
project_id string Да, если не передан price_id Идентификатор проекта (prj_...)
price_id string Нет Фиксированная цена, созданная в дашборде (price_...). Сумму и валюту сервер берёт из неё, покупатель их не изменит — рекомендуемый вариант для товаров с фиксированной ценой. Имеет приоритет над всеми источниками суммы ниже
amount string | number Нет Фиксированная сумма оплаты — десятичная строка или число
get_amount function Нет Функция обратного вызова, возвращающая сумму десятичной строкой в момент клика
amount_selector string Нет CSS-селектор поля ввода с суммой
currency string Нет Код фиатной валюты (USD, EUR и т.д.). По умолчанию: USD
client_id string Нет Ваш внутренний ID клиента (прикрепляется к инвойсу)
mode string Нет "iframe" (по умолчанию) — модальное окно. "redirect" — полностраничный переход
label string Нет Текст кнопки. По умолчанию: "Support with crypto"
width string Нет "auto" (по умолчанию) или "full" для 100 % ширины
accent_color string Нет Цвет акцента кнопки (hex). По умолчанию: #ff6b35
text_color string Нет Цвет текста кнопки (hex). По умолчанию: #ffffff. Контраст проверяется только если вы задали и свой accent_color: при контрасте 4,5
и выше SDK оставит ваш цвет, иначе возьмёт чёрный или белый — что контрастнее. На штатном акцентном цвете проверки нет, значение берётся как есть
radius number Нет Скругление кнопки, 0–32 px. По умолчанию: 18
frame_title string Нет Доступное название для iframe-элемента. По умолчанию: "Paymos checkout"
aria_label string Нет Доступное название модального окна. По умолчанию: "Paymos checkout"
pos_url string Нет Адрес вашей страницы POS/Терминала. Если задан, кнопка открывает Терминал, когда сумма не определилась
target string Нет "_self" (по умолчанию) или "_blank" (только при переходе на всю страницу)
auto_close_delay number Нет Миллисекунды, в течение которых экран успешной оплаты остаётся видимым перед автоматическим закрытием окна. По умолчанию: 0 (выключено). Отменяется любым действием пользователя внутри окна.
haptics boolean Нет Включить короткую тактильную отдачу на поддерживающих платформах (Android, некоторые PWA). iOS Safari игнорирует Vibration API — там отдача не сработает. Уважает prefers-reduced-motion. По умолчанию: true
timeout number Нет Через сколько миллисекунд прервать запрос на создание инвойса. Значение должно быть положительным, иначе берётся значение по умолчанию: 30000
debug boolean Нет Писать в консоль полные объекты Error, а не только текст сообщения. По умолчанию: false

Полный пример

<script src="https://paymos.io/v1/paymos-widget.js"></script>

<div id="paymos-widget"></div>

<script>
  PaymosWidget.mount('#paymos-widget', {
    api_key: 'YOUR_PUBLIC_KEY',
    project_id: 'prj_YOUR_PROJECT_ID',
    amount: '25.00',
    currency: 'USD',
    label: 'Support with crypto',
    mode: 'iframe',
    accent_color: '#FF6B35',
    text_color: '#FFFFFF',
    radius: 20
  });
</script>

Программный API

Страницу оплаты можно открыть и без кнопки:

// Open checkout programmatically (no button)
await PaymosWidget.open({
  api_key: 'YOUR_PUBLIC_KEY',
  project_id: 'prj_YOUR_PROJECT_ID',
  amount: '50.00',
  currency: 'USD',
  mode: 'iframe'
});

// Close the modal
PaymosWidget.close();

// Remove the button and clean up
PaymosWidget.destroy('#paymos-widget');

События

SDK отправляет события CustomEvent в window, чтобы страница могла реагировать на ход оплаты. Все данные лежат в event.detail.

Событие Когда срабатывает event.detail
paymos:opened Модальное окно смонтировано, URL для iframe установлен. { url }
paymos:closed Модальное окно удалено (по любой причине, включая срабатывание необязательного таймера auto_close_delay). { reason: 'escape' | 'iframe' | 'replaced' | 'api' | 'success' }
paymos:succeeded Оплата перешла в paid или paid_over. Отправляется из iframe через postMessage. { invoiceId }
paymos:failed Терминальное состояние с неуспехом (underpaid, expired, cancelled). { invoiceId, reason }
paymos:error SDK не смог создать инвойс (сеть/авторизация/CORS/таймаут). { message }

succeeded / failed приходят только в режиме iframe — их отправляет страница оплаты через window.parent.postMessage. SDK принимает сообщение только с origin той платёжной страницы, которую сам встроил, и только из её contentWindow, поэтому посторонние скрипты на странице мерчанта подделать их не могут.

При переходе на всю страницу браузер уходит с сайта до получения результата — подтверждение берите из вебхука на сервере.

// 1. The customer paid — auto-close the modal and redirect to a thank-you page.
window.addEventListener('paymos:succeeded', (e) => {
  console.log('Paid:', e.detail.invoiceId);
  PaymosWidget.close();
  // Absolute and on your own domain: a root-relative path in a published
  // code sample gets crawled as one of OUR URLs — Googlebot did exactly that
  // and filed /thank-you?order= as a 404 against paymos.io.
  window.location.href = 'https://your-shop.example/thank-you?order=' + e.detail.invoiceId;
});

// 2. Payment failed (underpaid / expired / cancelled).
window.addEventListener('paymos:failed', (e) => {
  console.warn('Payment failed:', e.detail.invoiceId, e.detail.reason);
  // e.detail.reason: 'underpaid' | 'expired' | 'cancelled'
});

// 3. Modal lifecycle.
window.addEventListener('paymos:opened',  (e) => console.log('Opened',  e.detail.url));
window.addEventListener('paymos:closed',  (e) => console.log('Closed',  e.detail.reason));
//   e.detail.reason: 'escape' | 'iframe' | 'replaced' | 'api' | 'success'

// 4. Invoice creation failed (network down, bad config, server error).
window.addEventListener('paymos:error', (e) => {
  console.error('SDK error:', e.detail.message);
});

Разрешённый домен

SDK сверяет Origin страницы с полем Разрешённый origin в настройках виджета. Не совпал — запрос отклоняется до того, как появится инвойс.

Значение одно, не список, и по умолчанию оно пустое. Пустое поле означает «отовсюду»: пока вы его не заполнили, кнопку с вашим публичным ключом pk_... можно встроить на любой чужой странице. Заполните его до выхода в рабочую среду. Запросы с того же домена, откуда отдаётся сама платёжная страница — например, экран терминала, — проверку пропускают всегда.

Режим Терминала

Режим включается параметром pos_url — укажите в нём адрес страницы Терминала. Тогда, если сумма не определена (нет amount, get_amount() вернул null, поле по amount_selector пусто), SDK откроет этот адрес — нампад для ввода суммы вручную. Подходит для точек продаж, где сумма меняется от транзакции к транзакции.

Без pos_url тот же случай завершается ошибкой PaymosWidget requires an amount, amountSelector, or price_id. — она приходит на страницу событием paymos:error.