← Вернуться в блог

Headless-платежи: депозитный чекаут за один вызов

· 3 min read
api headless интеграция функция

Если вы строите собственный чекаут — мобильное приложение, партнёрскую платформу, кастомный магазин — hosted-страница /pay/{id} не всегда подходит. У вас уже есть свой кошельковый флоу. Вы уже знаете, в какой сети и каким токеном хочет заплатить клиент. Что вам на самом деле нужно — один вызов API, возвращающий адрес депозита и точную сумму для отправки.

Именно для этого существует POST /api/payments/headless.

Как это выглядит

Один вызов на входе. Один — на выходе.

curl -X POST https://mutopay.com/api/payments/headless \
  -H "X-API-Key: ep_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 25.00,
    "currency": "USD",
    "description": "Order #1042",
    "external_id": "order_1042",

    "src_token_symbol": "USDT",
    "src_token_address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
    "src_chain_id": "137",
    "src_decimals": 6,
    "src_address": "0xCustomerWallet..."
  }'
{
  "id": "pay_abc123...",
  "status": "awaiting_payment",
  "route_type": "bridge",
  "protocol": "rubic",
  "deposit": {
    "address": "0xRubicDepositAddress...",
    "chain_id": "137",
    "chain_type": "evm",
    "token_symbol": "USDT",
    "token_address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
    "token_decimals": 6,
    "amount_raw": "25100000",
    "amount_human": "25.10",
    "payment_uri": "ethereum:0x...@137?value=25100000"
  },
  "bridge": {
    "name": "Across",
    "estimated_time_ms": 60000,
    "src_usd": "25.10",
    "bridge_fee_usd": "0.10"
  },
  "order_id": "rubic_exchange_id...",
  "expires_at": "2026-04-14T15:30:00Z"
}

Ваше приложение теперь имеет всё необходимое: скажите клиенту отправить ровно amount_raw исходного токена на address. Если хотите, отрендерите QR из payment_uri. Опрашивайте GET /api/payments/{id}/status до терминального состояния.

Два типа маршрутов, одна структура

  • Прямой — тот же токен, та же сеть (клиент платит USDT в Polygon, вы получаете USDT в Polygon). Адрес депозита — ваш кошелёк. Нет комиссий бриджа, нет ожидания.
  • Своп / депозит с бриджем — кросс-токенный или кросс-чейн маршрут, где клиент отправляет одну транзакцию на входящий адрес, а расчётный токен поступает в ваш кошелёк. Подписание ордера не требуется.

Маршруты, требующие от клиента подписи типизированного ордера или отправки on-chain-свопа, этим эндпоинтом не поддерживаются — если доступен только такой маршрут, вы получаете 422. Для них используйте hosted-страницу /pay/{id} или связку более низкого уровня /quotes + /build-order + /submit-order.

Что остаётся сделать вам

Два момента:

1. Получите tx hash, если можете. Для депозитов с бриджем ничего делать не нужно — фоновый монитор подхватывает депозит и отмечает платёж завершённым. Для прямых маршрутов монитор верифицирует только после получения tx hash, поэтому вызовите POST /api/payments/{id}/confirm с { "tx_hash": "0x..." } после того, как клиент транслирует транзакцию. Если ваш кошельковый UI возвращает hash (большинство так и делают), это одна строка кода.

2. Опрашивайте статус. GET /api/payments/{id}/status возвращает текущее состояние и tx hash после поступления платежа. Вебхук, настроенный на вашем канале, отправляет те же события (payment.completed, payment.failed и др.) — используйте тот вариант, что подходит вашей архитектуре.

Когда что использовать

Что вы строитеИспользуйте
Интеграцию в стиле WooCommerce / Shopify с редиректомPOST /api/payments/pay/{id}
Кастомный чекаут, где вы управляете кошельковым флоуPOST /api/payments/headless
Нужно предложить несколько вариантов свопа и дать пользователю выборPOST /api/payments + /quotes + /build-order

Headless-эндпоинт намеренно уже по возможностям. Он автоматически выбирает лучший маршрут с депозитом, фиксирует его и возвращает адрес депозита. Если вам нужен контроль сверх этого — компромисс между скоростью и ценой, несколько вариантов маршрутов, флоу с подписью ордера — гранулярные эндпоинты по-прежнему доступны.

Полная документация в API docs. Вопросы приветствуются.