Вебхук
Уведомления на URL мерчанта при изменении статуса транзакции. Настройка webhookUrl и webhookMethod, проверка подписи, повторы при ошибках.
Вебхук — это HTTP-запрос на ваш URL, который платформа отправляет при изменении статуса транзакции (оплата прошла, отменена, истекла и т.д.). На стороне мерчанта вебхук нужен, чтобы:
- обновить статус заказа или платежа в вашей системе;
- выдать товар или услугу после успешной оплаты;
- отправить уведомление клиенту или в CRM.
URL и метод запроса задаются при создании платежа (поля webhookUrl и webhookMethod) или берутся из настроек магазина по умолчанию.
Настройка
| Параметр | Тип | Описание |
|---|---|---|
webhookUrl | string | URL, на который SigmaPay отправит уведомление |
webhookMethod | "get" | "post" | Метод запроса: GET (payload в query) или POST (JSON в body) |
Требования к URL
- Разрешён только HTTPS.
- Запрещены
localhost,127.0.0.1,::1(для приёма вебхуков нужен публично доступный URL).
Как отправляется запрос
SigmaPay формирует payload с данными транзакции и добавляет поле signature (HMAC-SHA256 от нормализованного payload с вашим private_token). Отправка:
- GET — параметры в query string;
- POST — JSON в теле запроса.
Если ваш сервер вернул код не 2xx или запрос не удался (сеть, таймаут), платформа повторяет отправку:
| Попытка | Когда |
|---|---|
| 1 | Сразу |
| 2 | Через 2 мин |
| 3 | Через 10 мин |
Повторы
Ответьте 200 OK как можно быстрее после проверки подписи и сохранения факта обработки. Тяжёлую логику (выдача товара, списание остатков) лучше выполнять асинхронно после ответа.
Проверка подписи
Каждый вебхук содержит поле signature. Алгоритм проверки такой же, как при подписи запросов к API:
- Взять payload, удалить поле
signatureи пустые значения. - Отсортировать ключи по алфавиту.
- Собрать строку
k1=v1&k2=v2&...(объекты/массивы — черезJSON.stringify). - Вычислить
HMAC-SHA256(строка, private_token)в hex. - Сравнить результат с полем
signature. При несовпадении — отклонить запрос (например, 401).
Безопасность
Не обрабатывайте вебхук без проверки подписи. Иначе возможна подмена данных и повторная обработка от третьих лиц.
Идемпотентность
Обрабатывайте вебхуки идемпотентно по transactionId: один и тот же статус по одной транзакции не должен дважды менять заказ или повторно начислять бонусы. Сохраняйте обработанные transactionId + status (или только transactionId, если статус обновляется) и при повторной доставке вебхука возвращайте 200 без повторных действий.
Значения статуса
Поле status в payload может принимать значения:
pending | success | failed | canceled | expired | processing | proof_requested
Используйте их для перехода заказа в нужное состояние в вашей системе.
Формат payload (поля)
Ниже перечислены поля, которые приходят в вебхуке до добавления signature (подпись считается по этим же полям после нормализации).
Основные поля
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
createdAt | string | да | Дата создания транзакции (ISO) |
updatedAt | string | да | Дата обновления (ISO) |
expiresAt | string | да | Время истечения (ISO) |
merchantId | number | да | ID мерчанта |
externalId | string | нет | Внешний ID платежа (ваш) |
transactionId | string | да | UUID транзакции |
status | string | да | Текущий статус транзакции |
amount | number | да | Сумма |
currency | string | да | Валюта |
exchangeRate | number | да | Курс |
description | string | нет | Описание |
isTest | boolean | нет | Признак тестового платежа |
paymentPage | string | да | URL платёжной страницы |
Блок payment
Данные способа оплаты (карта, банк, телефон, QR, счёт, IBAN). Все поля опциональны.
| Поле | Тип | Пример |
|---|---|---|
payment.cardName | string | IVAN IVANOV |
payment.bankName | string | HDFC |
payment.cardNumber | string | 411111****1111 |
payment.phoneNumber | string | +91... |
payment.qrCode | string | data:image/... |
payment.accountNumber | string | 40817... |
payment.ibanNumber | string | DE89... |
Блок client
Данные клиента (если передавались при создании платежа). Все поля опциональны.
| Поле | Тип | Пример |
|---|---|---|
client.id | string | 1001 |
client.email | string | a@b.com |
client.name | string | Alex |
client.ip | string | 1.2.3.4 |
client.userAgent | string | Mozilla/... |
client.country | string | IN |
client.city | string | Mumbai |
Пример тела вебхука (POST, фрагмент)
{
"transactionId": "f6d4a1b2-3c4d-5e6f-7890-abcd1234ef56",
"status": "success",
"amount": 1000,
"currency": "RUB",
"merchantId": 12,
"externalId": "order-123",
"createdAt": "2026-03-04T10:00:00.000Z",
"updatedAt": "2026-03-04T10:05:00.000Z",
"expiresAt": "2026-03-04T10:15:00.000Z",
"paymentPage": "https://pay.example.com/...",
"payment": { "cardNumber": "411111****1111", "bankName": "Tinkoff" },
"client": { "email": "client@example.com" },
"signature": "a1b2c3d4..."
}