Перейти к основному содержимому

Webhook уведомления

Работа с Webhook-уведомлениями — это ключевой этап интеграции, который позволяет вашей системе оперативно реагировать на изменения статуса платежа в реальном времени.

При регистрации в системе необходимо указать URL, на который будут поступать уведомления о статусе транзакций (успешных и неуспешных). В личном кабинете можно указать отдельный вебхук для каждого терминала, и, при необходимости, выбрать какие типы вебхуков вы хотите получать.

Общая логика работы

Webhook используется для оперативной синхронизации статусов между WATA и системой мерчанта.

Типовой сценарий:

  1. В WATA меняется статус платёжной транзакции или возврата
  2. WATA отправляет HTTP-запрос на webhook URL мерчанта
  3. Система мерчанта обрабатывает уведомление
  4. В ответ необходимо вернуть HTTP 200 OK

Если webhook не был успешно доставлен, дальнейшее поведение зависит от типа уведомления.


Типы уведомлений

Webhook-уведомления бывают трех типов:

Тип webhookКогда приходитДля чего используется
ПредоплатныйСразу после того, как клиент нажал «Оплатить», но до запроса в банкПроверка наличия товара, актуальности цены, фрод-мониторинг или другая проверка заказа на стороне мерчанта
ПостоплатныйПосле успешного подтверждения транзакции банком или после ошибки оплатыРеализация бизнес-сценария: открытие доступа, смена статуса заказа в БД, отправка чека и т.д. В личном кабинете, в настройках терминала, можно отключить получение вебхука со статусом Ошибка (Declined), при необходимости
ВозвратПосле успешного возврата либо после ошибки возвратаКорректировка баланса, отмена заказа или деактивация услуги

Правила обработки и тайм-ауты

Ваш сервер должен возвращать HTTP 200 OK на каждое webhook-уведомление.

Если ответ не получен или отличен от 200:

Тип webhookПоведение при ошибке ответаТайм-аут ожидания ответа
ПредоплатныйТранзакция считается несогласованной и автоматически отклоняется. Запрос в банк не отправляется10 секунд
ПостоплатныйWATA будет повторять отправку с увеличивающимся интервалом в течение следующих 32 часов1 минута
ВозвратныйWATA будет повторять отправку с увеличивающимся интервалом в течение следующих 32 часов1 минута

Параметры webhook-уведомления

ПараметрТипКомментарий
transactionTypeСтрокаТип транзакции: CardCrypto — рублевые и валютные карты, SBP — система быстрых платежей, TPay — метод Т-Банка, SberPay – метод Сбербанка
kindСтрокаТип транзакции: Payment – оплата, Refund - возврат
idUUIDИдентификатор транзакции в системе WATA. (Не является идентификатором платежной ссылки)
transactionIdUUIDИдентификатор созданной транзакции возврата в системе WATA
originalTransactionIdUUIDИспользуется при возвратах. Идентификатор исходной транзакции по которой производится частичный или полный возврат
terminalPublicIdUUIDПубличный идентификатор терминала мерчанта
transactionStatusСтрокаСтатус транзакции (Created, Pending, Paid, Declined) См. раздел Статусы транзакций
errorCodeСтрокаКод ошибки в случае неуспешного запроса (см. справочник кодов ошибок)
errorDescriptionСтрокаОписание ошибки в случае неуспешного запроса
terminalNameСтрокаНазвание терминала мерчанта
amountЧислоСумма платежа. Всего после точки может быть 2 цифры для копеек или центов. Пример: 1188.00
currencyСтрокаВалюта платежа (RUB, USD, EUR)
orderIdСтрокаУникальный идентификатор заказа в системе мерчанта
orderDescriptionСтрокаОписание заказа
commissionЧислоКомиссия за транзакцию
paymentTimeДатаДата и время оплаты транзакции в UTC (перехода в статус Paid или Declined)
emailСтрокаEmail плательщика (если был задан на форме)
paymentLinkIdUUIDИдентификатор платежной ссылки в системе WATA
payerDataОбъектСодержит информацию о плательщике
└ payerIdСтрокаМаскированный номер телефона плательщика по СБП транзакции

Безопасность и проверка подписи

Чтобы гарантировать, что уведомление отправлено системой WATA, каждое сообщение содержит заголовок X-Signature с цифровой RSA-подписью, она нужна, чтобы проверить, что уведомление действительно отправлено WATA и тело запроса не было изменено

X-Signature: <signature>

Алгоритм проверки

  1. Получите публичный ключ: Используйте актуальный ключ (формат PKCS1), доступный по адресу: api.wata.pro/api/h2h/public-key.
  2. Подготовьте данные: В качестве сообщения используйте raw JSON (необработанное тело запроса), полученный в Webhook.
  3. Верифицируйте: Используйте алгоритм SHA512withRSA для проверки соответствия подписи из заголовка X-Signature и тела сообщения.

Важно использовать именно необработанное тело запроса. Если JSON был отформатирован, пересобран или изменен middleware, проверка подписи может не пройти.

Пример проверки подписи на PHP

<?php

class SignatureVerificationService {
public static function verify($rawWebhookJson, $signature, $publicKey) {
$publicSignature = openssl_get_publickey($publicKey);
$signatureBytes = base64_decode($signature);

$result = openssl_verify($rawWebhookJson, $signatureBytes, $publicSignature, OPENSSL_ALGO_SHA512);
openssl_free_key($publicSignature);

return $result === 1;
}
}

Пример проверки подписи на Java

import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;

import static java.nio.charset.StandardCharsets.UTF_8;

public class SignatureVerificationService {
public static boolean verify(String rawWebhookJson, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA512withRSA");
publicSignature.initVerify(publicKey);
publicSignature.update(rawWebhookJson.getBytes(UTF_8));

byte[] signatureBytes = Base64.getDecoder().decode(signature);

return publicSignature.verify(signatureBytes);
}
}

Получение публичного ключа

Публичный ключ для проверки подписи можно получить через API:

GET https://api.wata.pro/api/h2h/public-key
Content-Type: application/json

Пример ответа:

{
"value": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
}

Пример webhook-уведомления

Content-Type: application/json
X-Signature: <signature>
{
"transactionType": "CardCrypto",
"kind": "Payment",
"id": "3a1cf611-abc6-8d30-c4cd-521c9f6eeeb0",
"transactionId": "3a16a4f0-27b0-09d1-16da-ba8d5c63eae3",
"transactionStatus": "Paid",
"terminalPublicId": "3b16a2f1-dead-4e5d-abff-90865d1e13b1",
"errorCode": null,
"errorDescription": null,
"terminalName": "string",
"amount": 1188.00,
"currency": "RUB",
"orderId": "string",
"orderDescription": "string",
"paymentTime": "2024-12-04T17:41:44.434598Z",
"commission": 10,
"email": null,
"paymentLinkId": null
}

Рекомендации по обработке

  • Возвращайте 200 OK только после успешной обработки уведомления.
  • Обрабатывайте webhook-уведомления идемпотентно: повторная доставка одного и того же события не должна ломать бизнес-логику.
  • Сохраняйте transactionId и transactionStatus для последующей сверки.
  • Проверяйте подпись X-Signature до выполнения бизнес-операций.
  • Не используйте polling как основной способ получения статусов. Для обновлений статусов используйте webhook-уведомления.

Техническая документация