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

Webhooks

После изменения статуса платежа или выплаты Cobrex отправляет HTTP-запрос на URL из настроек мерчанта или на callback, переданный при создании операции.

Тело запроса​

Тип операцииТело
ПлатежJSON объекта платежа (см. модель).
ВыплатаJSON объекта выплаты (см. модель).

Метод и заголовки уточняйте в актуальной спецификации; для безопасности используйте проверки ниже.

Ответ вашего сервера​

Если вебхук принят и обработан (или поставлен во внутреннюю очередь так, что вы гарантируете обработку), endpoint должен вернуть HTTP 200. Cobrex трактует это как успешную доставку.

Любой другой код (включая 5xx, 4xx, таймаут или обрыв соединения) считается неуспехом — тогда срабатывает логика повторных отправок ниже.

Повторные отправки при неуспехе​

Если доставка не признана успешной, Cobrex планирует следующую попытку с нарастающей задержкой.

Таблица задержек до следующей попытки:

Повторная попыткаЗадержка до следующей отправки
110 секунд
230 секунд
31 минута
45 минут
515 минут
61 час
74 часа
816 часов

Вы можете самостоятельно отправить повторный Webhook через панель Cobrex.

Проверка 1 — IP-адрес​

Разрешайте только доверенные IP. На момент документации:

46.166.162.83

При миграции инфраструктуры список может меняться — уточняйте актуальный список у поддержки перед продакшеном.

Проверка 2 — заголовок x-signature​

  1. Сохраните сырое тело запроса как строку/буфер до JSON.parse.
  2. Вычислите HMAC-SHA256 с вашим секретом (тем же, что для API, или отдельным секретом вебхуков — уточните у Cobrex).

Ожидаемое соответствие с примером из панели интеграции:

signature_hex = HMAC-SHA256( key = api_secret, message = JSON.stringify(data) ).toString('hex')

где data — объект из распарсенного тела. На практике надёжнее сверять HMAC от того же байтового тела, что пришло в запросе (строка rawBody), чтобы не зависеть от пересборки JSON:

const crypto = require('crypto');

function verifyWebhookSignature(rawBodyString, receivedHex, apiSecret) {
const expected = crypto.createHmac('sha256', apiSecret).update(rawBodyString).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(receivedHex, 'hex'));
}

Уточните у Cobrex, идентичен ли алгоритм буквально JSON.stringify(data) или сырому телу — и используйте ровно тот вариант, который подтверждён для продакшена.

Рекомендации​

  • Отвечайте HTTP 200 быстро после валидации и постановки в очередь; тяжёлую работу выполняйте асинхронно.
  • Делайте обработку идемпотентной по payment_id / payout_id.
  • Логируйте заголовки и тело при отладке (без утечки секретов).

Дополнительно: раздел Авторизация и подпись.