Гайд
Вебхуки и колбэки криптоплатёжных шлюзов
Платёжный вебхук сообщает вашему серверу, что состояние платежа изменилось. Обработчик обязан проверять подпись, быть идемпотентным, быстро отвечать и сверяться независимо. Колбэки приходят больше одного раза и иногда не по порядку, поэтому считать их надёжной одноразовой доставкой — самая частая ошибка интеграции в категории.
На этой странице
Что такое платёжный колбэк?
HTTP-запрос от провайдера на принадлежащий вам эндпоинт, отправляемый, когда с платежом что-то меняется. Создан, замечен в сети, подтверждён, истёк, недоплачен, возвращён. Точный словарь событий у провайдеров разный, форма проблемы — одна.
Почему это сложнее, чем кажется?
Потому что сеть между двумя серверами ненадёжна, и ни одна сторона не различает режимы отказа.
Когда провайдер отправляет событие и не получает своевременный 200, он не знает, не получил ли ваш сервер его вовсе, получил и упал, или получил и успешно обработал, но не успел ответить. Единственное безопасное предположение — сбой, поэтому он повторяет. А значит, ваш обработчик увидит то же событие снова, возможно, несколько раз.
События могут приходить и не по порядку. Подтверждение может прийти раньше уведомления о том, что платёж замечен, особенно в быстрых сетях, где оба состояния наступают в одну секунду.
Что делает правильный обработчик?
Сначала проверяет подпись. До разбора тела, до логирования, до всего. Провайдеры подписывают колбэки общим секретом; неподписанный или неверно подписанный запрос — не платёжное событие, и относиться к нему как к событию нельзя.
Дедуплицирует по идентификатору события. Записывайте обработанные идентификаторы и делайте повтор пустой операцией. Дедупликация по идентификатору платежа — частая ошибка, потому что один платёж законно порождает несколько разных событий.
Сразу возвращает 200, потом работает. Подтвердите получение, положите событие в очередь и исполняйте асинхронно. Обработчик, исполняющий заказ внутри запроса, однажды не уложится в тайм-аут под нагрузкой, и наказанием за медлительность будет ещё больше трафика.
Проверяет переходы состояний, а не предполагает их. Если событие говорит «подтверждён», а заказ уже помечен подтверждённым, ничего не делайте. Если событие приходит для состояния раньше уже записанного, игнорируйте его, а не откатывайтесь назад.
Всё равно сверяется по расписанию. В полном каталоге видно, кто из провайдеров документирует API событий. Раз в час запросите у провайдера платежи за окно и сравните со своими записями. Это ловит всё, что пропустил путь колбэков, и что-нибудь оно поймает.
Что спросить у провайдера?
Как долго вы повторяете и по какому графику? Могу ли я переотправить доставку из панели? Есть ли эндпоинт для списка событий за окно? Гарантируете ли порядок, а если нет, несёт ли каждое событие номер последовательности или метку времени, по которой можно упорядочить?
Вопрос о переотправке — практический. Провайдер, позволяющий переотправить доставку, превращает неудачный деплой в пятиминутную починку, а не позволяющий — в проект по сверке.
Куда смотреть дальше?
Чек-лист интеграции описывает остальную сборку. Подборка API для разработчиков ранжирует провайдеров по документации и качеству API.
Форма рабочего обработчика
Проверить подпись. Отклонить всё, что не прошло, без разбора. Найти идентификатор события; если уже видели — вернуть 200 и остановиться. Иначе записать, поставить работу в очередь, вернуть 200. Обрабатывать из очереди, где повторы и сбои контролируете вы, а не провайдер.
Такая форма переживает дублированную доставку, медленные системы ниже по потоку и деплой посреди загруженного часа. Обработчики, исполняющие заказ внутри запроса, не переживают ничего из этого.
Порядок, и почему на него нельзя полагаться
События об одном платеже могут приходить не по порядку, особенно в быстрых сетях, где несколько состояний наступают за секунду. Считайте каждое событие утверждением о состоянии, а не шагом последовательности.
Практически: держите конечный автомат на своей стороне, игнорируйте переходы назад и опирайтесь на текущее состояние платежа, а не на последнее событие, которое случилось получить.
Что спросить у провайдера
Как долго вы повторяете, по какому графику и могу ли я переотправить доставку из панели? Есть ли эндпоинт со списком событий за окно времени? Несёт ли каждое событие номер последовательности или метку времени, по которой можно упорядочить?
Вопрос о переотправке — практический. Провайдер, позволяющий переотправить, превращает неудачный деплой в пятиминутную починку; не позволяющий — в проект по сверке с данными сети.
Задача сверки
Раз в час запросите у провайдера платежи за окно и сравните со своими записями. Оповещайте о расхождениях, а не логируйте их. Это ловит всё, что пропустил путь колбэков, и за достаточно долгий срок что-нибудь поймает.
Куда дальше
Чек-лист интеграции описывает остальную сборку вокруг этого обработчика. Гайд по тестированию — как доказать, что он работает, до прихода трафика, а подборка API для разработчиков — кто из провайдеров как следует документирует API событий.
Правильное тестирование обработчика
Отправьте одно событие дважды и убедитесь, что второе — пустая операция. Отправьте события не по порядку и убедитесь, что конечный автомат игнорирует переход назад. Отправьте событие с неверной подписью и убедитесь, что оно отклонено до разбора.
Эти три теста пишутся за полдня и покрывают сбои, которые реально случаются в продакшене. Тест счастливого пути доказывает, что интеграция собирается; эти доказывают, что она выживает.
Если провайдер поддерживает переотправку доставки из панели, используйте её вместо ручного конструирования полезных нагрузок: так проверяется настоящий путь, включая подпись.
Последняя проверка перед запуском
Убедитесь, что эндпоинт доступен снаружи вашей сети, с машины не в вашем VPN. Это звучит тривиально, а это повторяющаяся причина интеграций, которые проходят все внутренние тесты и ничего не получают в продакшене.
Читать дальше
Вопросы, которые задают мерчанты
Почему один и тот же вебхук приходит дважды?
Потому что провайдер не отличает потерянную доставку от медленного обработчика. Если ваш эндпоинт не отвечает достаточно быстро, провайдер считает доставку неудачной и повторяет её. Идемпотентность по идентификатору события — единственная надёжная защита.
Что если мой сервер лежит, когда срабатывает вебхук?
Большинство провайдеров повторяют по графику с нарастающими интервалами в течение нескольких часов. Это страховочная сетка, а не гарантия, и поэтому регулярная сверка по API провайдера не опциональна.
Можно ли опрашивать вместо вебхуков?
При малом объёме — да, и об этом проще рассуждать. Это плохо масштабируется и добавляет задержку между платежом и исполнением. Большинство интеграций в итоге делают и то и другое, с опросом как слоем сверки.
Что делать, если вебхук так и не пришёл?
Ничего, если работает задача сверки: она подхватит платёж на следующем проходе. Именно поэтому задача сверки не опциональна.
Можно ли проверять подпись после разбора тела?
Нет. Ничего не разбирайте, пока подпись не проверена. Неподписанный запрос на платёжном эндпоинте — не платёжное событие, и относиться к нему как к событию нельзя.
- Опубликовано вместе с индексом.