Информация

forma · Merchant API

Документация интеграции

Что в API

Методы сгруппированы по трём блокам: мерчанты (профиль и счета), транзакции (публичные и защищённые маршруты), выплаты. Ниже — быстрые ссылки на карточки методов на этой странице; подробные описания, пути и примеры тел запросов — в соответствующих разделах ниже.

Базовый URL

База API: api.formapay.io. Все пути с префиксом /v1.

https://api.formapay.io/v1

Заголовки авторизации

Пример для защищённых маршрутов мерчанта.

X-API-Key: sp_your_public_key

Авторизация

Для методов мерчанта передавайте X-API-Key (публичный или приватный ключ). Ключ можно получить и перевыпустить в кабинете мерчанта.

Публичные маршруты /v1/public/… не требуют ключа мерчанта; действует ограничение частоты запросов по IP.

Webhook'и (исходящие события)

Forma шлёт POST с подписанным JSON на merchant.webhook_url (общий) или transaction.callback_url (per-tx — если задан при POST /v1/transactions). Доставка — с retry на 5xx/408/429 и таймауте; 4xx не повторяется.

Заголовки запроса

ЗаголовокОписание
X-Forma-Event-IdUUID конкретной попытки доставки — нужен для идемпотентности на стороне мерчанта.
X-Forma-EventИмя события (см. список ниже).
X-Forma-TimestampUnix-секунды момента подписания.
X-Forma-Signaturesha256=<hex> от HMAC-SHA256(webhook_secret, "<ts>.<raw_body>"). Проверяйте при |now − ts| ≤ tolerance, иначе ловите replay.
User-Agentforma-webhook/1.
Content-Typeapplication/json.

События

  • transaction.completed — оплата пришла полностью или с переплатой.
  • transaction.expired — срок жизни инвойса истёк без оплаты.
  • transaction.chargeback — диспут / возврат со шлюза.
  • payout.broadcasted — заявка на вывод отправлена в сеть.
  • payout.success — вывод подтверждён.
  • payout.failed — окончательная ошибка по заявке.

Тело transaction.*

Поля payload'а
event
Имя события (то же, что в X-Forma-Event).
transaction.id
UUID транзакции.
transaction.external_id
Внешний ID заказа (если был сгенерирован).
transaction.merchant_id
UUID мерчанта.
transaction.status
Состояние tx на момент события (completed / expired / chargeback и т.п.).
transaction.currency
Валюта, в которой плательщик видел сумму (RUB для СБП/Card-RUB, USDT для крипто).
transaction.network
Сеть из метода (TRC20, SBP, Card и т.п.).
transaction.amount_expected, transaction.amount_received
Суммы в currency (8 знаков). amount_received — пропорционально доле подтверждённой оплаты.
transaction.amount_expected_usdt, transaction.amount_received_usdt
Те же суммы в USDT-нормировке ledger'а — для сверки с балансом forma.
transaction.tx_hash
Hash транзакции в сети (для крипто) или null.
transaction.address
Адрес кошелька (для address-flow) или null.
transaction.created_at, transaction.updated_at, transaction.target_action_at
Unix-секунды.

Тело payout.*

Поля payload'а
event
Имя события (то же, что в X-Forma-Event).
payout.id, payout.merchant_id, payout.status
Идентификаторы и текущий статус заявки.
payout.amount_requested, payout.amount_to_send, payout.network_fee, payout.service_fee
Суммы в USDT (8 знаков).
payout.tx_hash, payout.broadcasted_at, payout.processed_at
Hash транзакции и unix-секунды отправки/завершения.
payout.error_log, payout.attempts
Диагностика ошибок и счётчик попыток.

Проверка подписи (Python)

import hmac, hashlib, time

def verify_forma_webhook(secret: str, raw_body: bytes, headers: dict) -> bool:
    ts = headers["X-Forma-Timestamp"]
    sig = headers["X-Forma-Signature"]  # "sha256=<hex>"
    # 1) Reject if timestamp too old (e.g. ±5 min).
    if abs(time.time() - int(ts)) > 300:
        return False
    # 2) Recompute HMAC over "<ts>.<raw_body>".
    msg = f"{ts}.".encode() + raw_body
    expected = "sha256=" + hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)