Тема
03.06 Merchant Webhooks
Статус: черновик для обсуждения
1. Назначение документа
Этот документ описывает outbound webhooks, которые система отправляет merchant после изменения transaction status.
Merchant webhook flow должен:
- отправлять merchant notification на нужные transaction statuses;
- отправлять webhook на все URLs, переданные при создании transaction;
- использовать стандартный payload;
- скрывать provider/internal execution details;
- подписывать webhook через HMAC;
- поддерживать retry через exponential backoff;
- сохранять delivery history;
- позволять manual resend пользователям с permission;
- показывать webhook delivery information в Back Office и Merchant Portal;
- гарантировать порядок событий по transaction.
2. Когда отправляем webhook
Merchant webhook отправляется на:
PROCESSING, если этот status пришел от provider как meaningful intermediate status;COMPLETED;FAILED;CANCELED;REJECTED.
Webhook не отправляется на:
CREATED;WAITING_CUSTOMER_DATA.
Важно: PROCESSING webhook нельзя отправлять после факта отправки request в provider. Его можно отправлять только если provider callback/status явно означает processing/in-progress в бизнес-смысле.
3. Webhook URLs
Merchant обязан передать список webhook URLs при создании transaction.
Если webhook URLs не переданы, create deposit request должен быть отклонен без создания transaction.
При наступлении webhook event система отправляет webhook на все URLs, которые были переданы для этой transaction.
4. Webhook Payload
Webhook payload должен иметь стандартную схему.
Schema одинаковая для всех statuses, но значения fields могут отличаться.
Минимальные поля:
transactionId;merchantTransactionId;providerTransactionId;status;userId;amount;currency;paymentMethodId;brandId;merchantId;accountReference;corrected;type;sentAt;errorCode;errorDescription.
transactionId - это internal transaction ID в нашей системе.
merchantTransactionId - это transaction ID, который merchant передал при создании transaction.
errorCode и errorDescription всегда присутствуют в payload:
- если ошибка есть, fields содержат safe merchant-facing values;
- если ошибки нет, fields равны
null.
5. Provider/Internal Data
Webhook не должен содержать:
- provider name;
- SUB MID;
- SUB MID GROUP;
- SUB MID AGGREGATOR;
- raw provider response;
- provider credentials;
- internal routing trace.
Merchant получает только merchant-facing transaction data.
6. Error Data
Если transaction завершилась с ошибкой, была rejected или canceled, webhook должен содержать:
errorCode;errorDescription.
Webhook payload не должен содержать raw provider error.
errorCode и errorDescription должны быть safe merchant-facing values.
Если ошибки нет, errorCode и errorDescription отправляются как null.
7. Signature
Webhook должен быть подписан через HMAC.
Exact HMAC format должен предложить development team.
Документация для merchant должна описывать:
- какие headers используются;
- как считается signature;
- какие payload fields входят в signature;
- как merchant должен валидировать signature.
8. Delivery Success Criteria
Webhook считается успешно доставленным, если merchant endpoint вернул любой 2xx response.
Не только 200 OK, а любой status code из диапазона 2xx.
Response body при успешном 2xx не влияет на delivery success.
9. Retry Policy
Если webhook delivery failed, система должна делать retry.
Retry strategy:
- exponential backoff.
Любой non-2xx response считается failed delivery attempt и должен уйти в retry policy.
Exact intervals, max attempts, max duration и timeout должен предложить development team.
10. Failed Delivery
Если webhook delivery failed:
- delivery attempt сохраняется;
- event пишется в transaction timeline;
- система планирует retry;
- delivery status виден в Back Office;
- delivery status виден в Merchant Portal;
- после max attempts может быть alert / operational signal, exact policy должна быть предложена development team.
11. Manual Resend
Manual resend может делать:
- platform user с permission;
- merchant user с permission.
При manual resend user обязан указать reason/comment.
При manual resend система отправляет webhook на все webhook URLs transaction.
Manual resend должен быть записан:
- в transaction timeline;
- в audit log.
Reason/comment manual resend должен быть сохранен в transaction timeline and audit log.
Если manual correction изменила status и user выбрал resend, система должна отправить webhook по всем webhook URLs transaction.
В таком payload:
corrected = true;statusсодержит corrected status;errorCodeиerrorDescriptionзаполнены или равныnullпо текущему transaction error state.
12. Webhook History Visibility
Webhook delivery history должна быть видна:
- в Platform transaction details;
- в Merchant transaction details;
- в отдельной вкладке / разделе Webhooks.
Точный UI placement должен быть описан в Back Office / Merchant Portal IA.
13. Merchant Visibility
Merchant user с нужной permission может видеть:
- payload, который система отправила;
- response code;
- response body;
- delivery attempts;
- attempt timestamps;
- signature headers.
Ничего из этих webhook delivery details дополнительно скрывать от merchant не нужно.
Provider/internal data все равно не должно попадать в webhook payload.
14. Merchant Response Body
Merchant response body нужно сохранять.
Response body видят:
- platform users с permission;
- merchant users с permission.
15. Webhook Timeout
Webhook delivery request должен иметь timeout.
Exact timeout должен предложить development team.
16. Ordering
Если по transaction быстро произошли несколько webhook events, например:
text
PROCESSING -> COMPLETEDсистема должна гарантировать порядок отправки webhooks по одной transaction.
Также нужен delay между последовательными webhooks по одной transaction, чтобы merchant endpoint мог обработать их корректно.
Exact delay должен предложить development team.
17. Duplicate Prevention
Система должна избегать accidental duplicate webhooks.
Retry того же webhook event возможен только если delivery не была успешной.
Если webhook был успешно доставлен, система не должна повторно отправлять его автоматически.
Manual resend является отдельным user action и должен быть явно записан в timeline/audit.
18. Webhook Event ID
Отдельный webhookEventId в payload для MVP не требуется.
Система может иметь internal event ID для хранения и расследований, но merchant-facing payload не обязан его содержать.
19. Public Documentation
Public merchant documentation для webhook schema нужна в MVP.
Документация должна описывать:
- webhook events;
- payload schema;
- statuses;
- HMAC signature validation;
- retry behavior;
- expected merchant response;
- delivery success criteria.
20. Timeline Events
Transaction timeline должна сохранять:
- webhook event created;
- webhook delivery attempt started;
- webhook delivered;
- webhook delivery failed;
- webhook retry scheduled;
- webhook retry exhausted;
- webhook manual resend requested;
- webhook manual resend delivered;
- webhook manual resend failed.
21. Metrics And Alerts
Метрики:
- webhook events created;
- webhook delivery attempts;
- webhook delivered count;
- webhook failed count;
- webhook retry count;
- webhook retry exhausted count;
- webhook delivery latency;
- webhook queue lag.
Alerts:
- spike webhook failures;
- retry exhausted;
- webhook queue lag too high;
- merchant endpoint unavailable, если видно по delivery failures.
22. Acceptance Criteria
Merchant webhooks считаются реализованными для MVP, если:
- Merchant передает список webhook URLs при create deposit.
- Если webhook URLs отсутствуют, transaction не создается.
- Webhook отправляется на все URLs transaction.
- Webhook отправляется на
PROCESSING, еслиPROCESSINGпришел от provider. - Webhook отправляется на final statuses.
- Payload имеет стандартную схему.
- Payload schema одинаковая для всех statuses.
- Payload содержит transactionId, merchantTransactionId, providerTransactionId, status, userId, amount, currency, paymentMethodId, brandId, merchantId, accountReference, corrected, type, sentAt, errorCode, errorDescription.
- transactionId является internal transaction ID.
- merchantTransactionId является transaction ID, который merchant передал при создании transaction.
- Webhook payload всегда содержит errorCode и errorDescription.
- errorCode и errorDescription равны null, если ошибки нет.
- Payload не содержит statusChangedAt, createdAt, updatedAt, amountInEur.
- Payload не содержит provider/internal execution data.
- Merchant metadata не отправляется по умолчанию.
- Webhook подписывается через HMAC.
- Delivery считается успешной на любой
2xx. - Любой non-2xx уходит в retry.
- Response body не влияет на success, если status code
2xx. - Failed delivery уходит в retry через exponential backoff.
- Delivery attempts сохраняются.
- Delivery attempts видны в transaction details.
- Webhook history доступна в отдельной вкладке / разделе Webhooks.
- Manual resend доступен platform user и merchant user с permission.
- Manual resend требует reason/comment.
- Manual resend отправляет webhook на все URLs transaction.
- Merchant response body сохраняется и виден platform/merchant users с permission.
- По одной transaction порядок webhook events гарантируется.
- Между последовательными webhook events по одной transaction есть delay.
- Accidental duplicate webhooks нужно предотвращать.
- Public merchant webhook documentation существует в MVP.