Вебхуки
Push-события биллинга и задач с подписью HMAC-SHA256.
Вебхуки
Вебхуки — push-уведомления о событиях биллинга и задач. Регистрируйте HTTPS-эндпоинт, подписывайтесь на типы событий — и получайте POST-запросы с подписью HMAC-SHA256.
Быстрый старт
# зарегистрировать эндпоинт (секрет показывается один раз!)
curl -X POST -H "X-API-Key: $FRANKLAB_KEY" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/franklab-hook","eventTypes":["billing.settled","task.succeeded"]}' \
https://apergrex.ru/franklab/api/v1/webhooks/endpoints
# тестовая доставка
curl -X POST -H "X-API-Key: $FRANKLAB_KEY" \
https://apergrex.ru/franklab/api/v1/webhooks/endpoints/<id>/test
Типы событий
| Событие | Когда |
|---|---|
billing.settled | подтверждено списание (с финальной суммой) |
billing.refunded | возврат резерва при неудаче задачи |
billing.topup.confirmed | зачислено пополнение |
billing.low_balance | баланс ниже 1 000 ₣ (не чаще раза в 24 ч) |
billing.invoice.status_changed | счёт юрлица сменил статус/оплачен |
task.succeeded / task.failed / task.refunded | терминальный статус задачи генерации |
webhook.test | тестовое событие (по команде) |
Формат доставки
Заголовки:
X-Franklab-Event: billing.settled
X-Franklab-Event-Id: <uuid события — ключ идемпотентности>
X-Franklab-Timestamp: <unix-секунды>
X-Franklab-Signature: sha256=<HMAC-SHA256(secret, "{timestamp}.{body}")>
Тело — общий конверт:
{
"eventId": "…",
"eventType": "billing.settled",
"occurredAt": "2026-09-04T12:00:00.000Z",
"partnerId": "…",
"schemaVersion": 1,
"data": { "transactionId": "…", "amountFranks": 84 }
}
Проверка подписи
const expected = crypto.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
// сравните с X-Franklab-Signature (без префикса sha256=) и проверите,
// что timestamp не старше ~5 минут (анти-replay)
Гарантии доставки
- At-least-once: дубликаты возможны — идемпотентируйте по
eventId. - Дубликаты возможны и после рестарта поллера — надёжный ключ дедупликации:
eventType+data.transactionId/data.taskId/data.invoiceId. - Задержка — до минуты (поллер).
- Повторы при неудаче: 1 мин → 5 мин → 30 мин → 2 ч → 6 ч, затем dead-letter (виден в
GET /v1/webhooks/deliveries?status=dead_lettered). - Статус
uncertain— запрос отправлен, но исход неизвестен: такие доставки не повторяются автоматически — повторите их черезPOST /v1/webhooks/deliveries/{id}/replay. - Отвечайте 2xx быстро; таймаут — 10 секунд.
Управление
| Операция | Эндпоинт |
|---|---|
| Список | GET /v1/webhooks/endpoints |
| Регистрация | POST /v1/webhooks/endpoints |
| Удаление | DELETE /v1/webhooks/endpoints/{id} |
| Ротация секрета | POST /v1/webhooks/endpoints/{id}/rotate-secret |
| Тест | POST /v1/webhooks/endpoints/{id}/test |
| История доставок | GET /v1/webhooks/deliveries?endpointId=…&status=… |
| Повтор доставки | POST /v1/webhooks/deliveries/{id}/replay |
Ограничения: до 10 эндпоинтов на партнёра; URL — только публичный HTTPS (внутренние адреса и IP-литералы отклоняются); редиректы не следуются.
Для AI-агентов/docs/webhooks.md