Гарантия доставки
Доставка идёт по паттерну transactional‑outbox: строка доставки пишется в той же транзакции, что и зачисление платежа — уведомление не потеряется. Доставка — как минимум один раз (at‑least‑once). Успех = ответ2xx; любой не‑2xx или сетевая
ошибка считается провалом, и доставка переносится с ретраем.
Заголовки доставки
Где
secret — тот, что вернул POST /v1/webhooks.
Как считается подпись вебхука
timestamp + точка . + сырое тело как есть. Никаких метода, пути или переводов строк —
в отличие от подписи запроса.
Типы событий (X-Webhook-Event)
Возможные события выплат:
payout.pending, payout.approved, payout.awaiting_cosign (при 2‑of‑2), payout.broadcasting, payout.sent, payout.confirmed (успех), payout.failed, payout.cancelled. Подтверждённая выплата — payout.confirmed, не payout.paid (подробнее — в заметке к примеру вебхука выплаты ниже).
У выплатных ссылок (чеков) собственных событий нет: когда получатель
забирает средства, порождённая выплата шлёт обычные
payout.* события, а её order_id равен
payoutlink:<link_id> — по нему сопоставляйте событие со ссылкой. Возврат из
/v1/payment/resolve тоже приходит событиями payout.*.Пример тела платёжного вебхука
Пример тела вебхука пополнения кошелька (wallet.paid)
Приходит при поступлении средств на статический кошелёк. Поле type — wallet.
Пример тела вебхука выплаты (payout.<статус>)
Приходит при смене статуса выплаты. Поле type — payout.
Статус в заголовке и в теле — разного «уровня». В заголовке
X-Webhook-Event суффикс —
внутренний статус (payout.confirmed, payout.sent, …), а поле status в теле —
укрупнённый (check / process / paid / fail / cancel). Подтверждённая выплата придёт как
X-Webhook-Event: payout.confirmed с "status": "paid" в теле. Ветвитесь по тому, что вам удобнее,
но не ждите payout.paid в заголовке — такого события нет. См. статусы выплаты.Проверка подписи
Берите именно сырое тело запроса (raw body), до любого JSON‑парсинга/пересериализации. Если
тело переупаковать, байты изменятся и подпись не сойдётся.
Ретраи и dead‑letter
Backoff экспоненциальный: от 10 секунд с удвоением, потолок 1 час; всего до 12 попыток (в сумме ~3,5 часа). Исчерпав попытки, доставка получает статусdead — она видна в
POST /v1/webhooks/deliveries.
Идемпотентность на вашей стороне (обязательно)
Из‑за at‑least‑once один вебхук может прийти несколько раз (в том числе послеpayment/resend). Правила:
- Дедуплицируйте по паре
uuid+statusи обрабатывайте повтор как no‑op. - Не полагайтесь на порядок доставок — он не гарантирован. Опирайтесь на
status/is_final, а не на очерёдность прихода. - Отвечайте
2xxтолько после успешной обработки — иначе диспетчер повторит доставку.
Связанные страницы
POST /v1/webhooks
регистрация URL и получение
secret.POST /v1/webhooks/deliveries
журнал доставок.
Тестовые вебхуки
POST /v1/payment/resend
Настройка и приём вебхуков
пошагово.