SigmaPay

Вебхук

Уведомления на URL мерчанта при изменении статуса транзакции. Настройка webhookUrl и webhookMethod, проверка подписи, повторы при ошибках.

Вебхук — это HTTP-запрос на ваш URL, который платформа отправляет при изменении статуса транзакции (оплата прошла, отменена, истекла и т.д.). На стороне мерчанта вебхук нужен, чтобы:

  • обновить статус заказа или платежа в вашей системе;
  • выдать товар или услугу после успешной оплаты;
  • отправить уведомление клиенту или в CRM.

URL и метод запроса задаются при создании платежа (поля webhookUrl и webhookMethod) или берутся из настроек магазина по умолчанию.

Настройка

ПараметрТипОписание
webhookUrlstringURL, на который 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:

  1. Взять payload, удалить поле signature и пустые значения.
  2. Отсортировать ключи по алфавиту.
  3. Собрать строку k1=v1&k2=v2&... (объекты/массивы — через JSON.stringify).
  4. Вычислить HMAC-SHA256(строка, private_token) в hex.
  5. Сравнить результат с полем signature. При несовпадении — отклонить запрос (например, 401).

Безопасность

Не обрабатывайте вебхук без проверки подписи. Иначе возможна подмена данных и повторная обработка от третьих лиц.

Идемпотентность

Обрабатывайте вебхуки идемпотентно по transactionId: один и тот же статус по одной транзакции не должен дважды менять заказ или повторно начислять бонусы. Сохраняйте обработанные transactionId + status (или только transactionId, если статус обновляется) и при повторной доставке вебхука возвращайте 200 без повторных действий.

Значения статуса

Поле status в payload может принимать значения:

pending | success | failed | canceled | expired | processing | proof_requested

Используйте их для перехода заказа в нужное состояние в вашей системе.

Формат payload (поля)

Ниже перечислены поля, которые приходят в вебхуке до добавления signature (подпись считается по этим же полям после нормализации).

Основные поля

ПолеТипОбязательноеОписание
createdAtstringдаДата создания транзакции (ISO)
updatedAtstringдаДата обновления (ISO)
expiresAtstringдаВремя истечения (ISO)
merchantIdnumberдаID мерчанта
externalIdstringнетВнешний ID платежа (ваш)
transactionIdstringдаUUID транзакции
statusstringдаТекущий статус транзакции
amountnumberдаСумма
currencystringдаВалюта
exchangeRatenumberдаКурс
descriptionstringнетОписание
isTestbooleanнетПризнак тестового платежа
paymentPagestringдаURL платёжной страницы

Блок payment

Данные способа оплаты (карта, банк, телефон, QR, счёт, IBAN). Все поля опциональны.

ПолеТипПример
payment.cardNamestringIVAN IVANOV
payment.bankNamestringHDFC
payment.cardNumberstring411111****1111
payment.phoneNumberstring+91...
payment.qrCodestringdata:image/...
payment.accountNumberstring40817...
payment.ibanNumberstringDE89...

Блок client

Данные клиента (если передавались при создании платежа). Все поля опциональны.

ПолеТипПример
client.idstring1001
client.emailstringa@b.com
client.namestringAlex
client.ipstring1.2.3.4
client.userAgentstringMozilla/...
client.countrystringIN
client.citystringMumbai
Пример тела вебхука (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..."
}

On this page