Тема
07.02 Merchant Webhook API
Статус: черновик для обсуждения
1. Назначение документа
Этот документ описывает public merchant webhook schema для MVP.
Merchant webhook нужен, чтобы система уведомляла merchant о важных изменениях transaction status.
2. Когда отправляем webhook
Webhook отправляется на:
PROCESSING;COMPLETED;FAILED;CANCELED;REJECTED.
Webhook не отправляется на:
CREATED;WAITING_CUSTOMER_DATA.
PROCESSING webhook отправляется только если provider callback/status означает meaningful provider-side processing state.
3. Event types
Webhook event types:
text
transaction.processing
transaction.completed
transaction.failed
transaction.canceled
transaction.rejectedEvent type определяется transaction status.
4. Payload schema
Webhook payload schema должна быть одинаковой для всех statuses.
Значения fields могут отличаться в зависимости от status.
Например, errorCode и errorDescription всегда присутствуют, но равны null, если ошибки нет.
Payload fields:
transactionId;merchantTransactionId;providerTransactionId;status;userId;amount;currency;paymentMethodId;brandId;merchantId;accountReference;corrected;type;sentAt;errorCode;errorDescription.
Webhook payload не содержит:
eventId;- merchant metadata;
statusChangedAt;createdAt;updatedAt;amountInEur;- provider name;
- SUB MID;
- SUB MID GROUP;
- SUB MID AGGREGATOR;
- routing details;
- provider raw response;
- FX details;
- conversion fee;
- processing fee;
- retry attempt number.
5. Field descriptions
| Field | Type | Required | Description |
|---|---|---|---|
transactionId | string | Yes | Internal transaction ID в нашей системе. |
merchantTransactionId | string | Yes | Transaction ID, который merchant передал при создании transaction. |
providerTransactionId | string/null | Yes | Transaction ID / payment ID от provider, если известен. null, если неизвестен. |
status | string | Yes | Current transaction status. |
userId | string | Yes | User ID, который merchant передал при создании transaction. |
amount | number/string | Yes | Original transaction amount. Exact numeric format должен быть определен technical design. |
currency | string | Yes | Original transaction currency. |
paymentMethodId | string | Yes | Payment Method / MID configuration ID, который merchant передал при создании transaction. |
brandId | string | Yes | Brand ID из deposit request. |
merchantId | string | Yes | Merchant ID в нашей системе. |
accountReference | string/null | Yes | Account/IBAN/reference, полученный от provider callback, если provider его передал. null, если отсутствует. |
corrected | boolean | Yes | true, если status был установлен через manual correction. |
type | string | Yes | Transaction type: deposit или withdraw. Для MVP используется deposit. |
sentAt | string | Yes | Timestamp отправки webhook. |
errorCode | string/null | Yes | Internal error code, если transaction связана с ошибкой / rejection / cancellation. null, если ошибки нет. |
errorDescription | string/null | Yes | Safe human-readable error description. null, если ошибки нет. |
6. Example payload
json
{
"transactionId": "internal_tx_123",
"merchantTransactionId": "merchant_tx_789",
"providerTransactionId": "provider_tx_456",
"status": "COMPLETED",
"userId": "merchant-user-789",
"amount": "100.00",
"currency": "EUR",
"paymentMethodId": "pm_123",
"brandId": "brand_123",
"merchantId": "merchant_123",
"accountReference": "IBAN123456789",
"corrected": false,
"type": "deposit",
"sentAt": "2026-06-10T12:00:00Z",
"errorCode": null,
"errorDescription": null
}7. Metadata
Merchant metadata не отправляется в webhook payload в MVP.
Payload должен быть стандартным и одинаковым для всех merchants.
8. Error data
Если transaction завершилась с ошибкой, была rejected или canceled, webhook payload должен содержать:
errorCode;errorDescription.
Эти fields всегда присутствуют в payload.
Если ошибки нет:
errorCode = null;errorDescription = null.
Webhook payload не должен содержать:
- provider raw error;
- provider raw response;
- internal exception details;
- hidden routing details.
errorCode и errorDescription должны быть safe merchant-facing values из Error Code Dictionary.
9. Signature
Webhook должен быть подписан через HMAC.
Exact HMAC format должен предложить development/security team.
Webhook documentation должна описывать:
- signature headers;
- timestamp header, если используется;
- payload canonicalization;
- how merchant validates signature.
Webhook signature validation documentation должна быть опубликована в public documentation portal.
Документация должна содержать examples на нескольких programming languages.
Owner документации:
text
Product Owner10. Delivery URLs
Webhook отправляется на все URLs, которые merchant передал при создании transaction.
Если webhook отправляется на несколько URLs, payload должен быть одинаковым для всех URLs.
11. Manual resend
Manual resend не создает merchant-facing eventId.
Payload при manual resend имеет такую же schema.
Field corrected зависит от transaction status source:
true, если status был установлен manual correction;false, если status был установлен normal processing/provider callback/expiration.
sentAt при resend должен отражать фактическое время отправки resend webhook.
Если webhook отправляется после manual correction:
- payload содержит corrected status;
corrected = true;- payload всегда содержит
errorCodeanderrorDescription; - если ошибки нет,
errorCodeanderrorDescriptionравныnull; - webhook отправляется на все webhook URLs transaction, если user выбрал resend.
12. Delivery success
Merchant endpoint считается успешно обработавшим webhook, если вернул любой 2xx HTTP response.
Любой non-2xx response считается failed delivery attempt.
Response body не влияет на delivery success, если HTTP status code находится в диапазоне 2xx.
13. Retry
Retry strategy:
text
exponential backoffExact intervals, max attempts, max duration and timeout should be proposed by development team.
Retry attempt number не отправляется в payload.
Attempt information хранится в delivery history.
14. Provider/internal data
Webhook payload не должен раскрывать provider/internal data.
Запрещено отправлять:
- provider name;
- SUB MID;
- SUB MID AGGREGATOR;
- raw provider request/response;
- raw callback payload;
- hidden routing path;
- provider credentials/config.
providerTransactionId можно отправлять, потому что это transaction reference, а не provider identity/configuration.
15. Acceptance Criteria
Merchant Webhook API считается согласованным для MVP, если:
- Payload schema одинаковая для всех statuses.
- Webhook отправляется на PROCESSING и final statuses.
- Event types: transaction.processing, transaction.completed, transaction.failed, transaction.canceled, transaction.rejected.
- Payload содержит transactionId.
- Payload содержит merchantTransactionId.
- Payload содержит providerTransactionId.
- Payload содержит status.
- Payload содержит userId.
- Payload содержит amount.
- Payload содержит currency.
- Payload содержит paymentMethodId.
- Payload содержит brandId.
- Payload содержит merchantId.
- Payload содержит accountReference.
- Payload содержит corrected.
- Payload содержит type.
- Payload содержит sentAt.
- Payload всегда содержит errorCode и errorDescription.
- errorCode и errorDescription равны null, если ошибки нет.
- Payload не содержит statusChangedAt.
- Payload не содержит createdAt / updatedAt.
- Payload не содержит amountInEur.
- Payload не содержит eventId.
- Payload не содержит merchant metadata.
- Payload не содержит attempt number.
- Payload не содержит provider/sub-mid/routing details.
- Payload не содержит FX/fees.
- Payload подписывается через HMAC.
- Exact HMAC format предлагает development/security team.
- Webhook signature validation описана в public documentation portal.
- Webhook signature validation содержит examples на нескольких programming languages.
- Payload одинаковый для всех webhook URLs transaction.
- Manual resend не создает merchant-facing eventId.
- Merchant success response is any 2xx.
- Any non-2xx response is failed delivery and should be retried.
- Merchant response body does not affect success when status code is 2xx.
16. Open Questions
Product open questions отсутствуют.
Technical/design follow-up:
- Определить exact HMAC signature format.
- Определить exact timestamp/header format.
- Определить exact numeric format for
amount. - Определить exact enum values casing for
type.