Руководства → Вебхук не приходит: что проверить
Вебхук не приходит: что проверить
Разбор по шагам, от самого частого к редкому. Почти все случаи закрываются первыми тремя пунктами.
1. Посмотрите, что мы думаем о доставке
Первым делом спросите нас, а не свои логи:
curl -s https://kazpayment.kz/api/v1/webhook \
-H "Authorization: Bearer $KAZPAYMENT_KEY"
В ответе — адрес приёмника и судьба последней доставки: статус, число попыток и текст последней ошибки. Дальше два разных мира:
- есть попытки и ошибка — мы стучимся, ваш сервер не принимает. Идите к пункту 4.
- попыток нет вовсе — события до отправки не дошли. Пункты 2 и 3.
2. Адрес вообще настроен?
Если GET /api/v1/webhook возвращает пусто — приёмник не настроен. Это самая
частая причина «вебхук не приходит»: настраивали на тестовом ключе, а
работаете боевым, или адрес удалили при отладке.
Требования к адресу жёсткие, и несоответствующий мы не примем при настройке:
- только https;
- публичное доменное имя —
localhost, IP-адреса и внутренние имена отвергаются; - без логина/пароля в адресе и без
#фрагмента.
Для локальной разработки используйте туннель (ngrok и аналоги) — он даёт публичное https-имя.
3. Проверьте приёмник тестовым событием
Не ждите настоящей оплаты:
curl -s -X POST https://kazpayment.kz/api/v1/webhook/test \
-H "Authorization: Bearer $KAZPAYMENT_KEY"
В течение минуты придёт событие webhook.test — тем же путём и с той же
подписью, что настоящие. Не пришло — проблема в доставке (пункт 4), пришло —
значит канал жив, и дело в самой оплате (пункт 6).
4. Что считается недоставкой
Мы ждём 2xx в течение 10 секунд. Всё остальное — недоставка:
| Что у вас | Как выглядит у нас |
|---|---|
| 500, 502, 404, 403 | не-2xx, будем повторять |
| обработчик думает 30 секунд | таймаут |
| редирект (301/302) на другой адрес | недоставка: мы не ходим по редиректам |
| просроченный TLS-сертификат | ошибка соединения |
| firewall режет чужие адреса | ошибка соединения |
Два самых частых самострела: долгий обработчик (ответьте 2xx сразу, работу
делайте после) и редирект — например, с example.kz на www.example.kz.
Указывайте в настройке конечный адрес.
5. Повторы и «мёртвая» доставка
Если не получилось, мы повторяем: через 1 минуту, 5 минут, 30 минут, 2 часа, 8 часов, 24 часа. Семь попыток примерно за полтора суток.
После этого доставка помечается мёртвой, а владелец бизнеса получает
уведомление в Telegram (если он подключён). Текст последней ошибки виден в
GET /api/v1/webhook.
Важно: у мёртвого события нет кнопки «отправить заново». Если ваш приёмник
лежал дольше полутора суток, восстановите состояние опросом статусов:
GET /api/v1/orders/<ваш_номер>.
6. Событие приходит, но обработчик его отвергает
Тогда виновата обычно проверка подписи. Три классические ошибки:
Подпись считается не от сырых байт. Многие фреймворки разбирают JSON до
вашего кода, и JSON.stringify(req.body) даёт уже другую строку — порядок
ключей и пробелы не совпадут. Нужен именно сырой буфер тела (в Express —
express.raw() или сохранение rawBody до парсера).
Не тот секрет. Повторный PUT /api/v1/webhook — даже с тем же адресом —
выпускает новый секрет, старый перестаёт работать сразу. Если вы
перенастраивали адрес и не обновили секрет в окружении, все события пойдут
мимо.
Сравнение строк «на глаз». Сравнивайте с защитой от утечки по времени
(crypto.timingSafeEqual и аналоги), предварительно проверив длину.
Совет для отладки: логируйте отдельно «пришло событие с неверной подписью» — эта строка сразу отделяет проблему секрета от проблемы сети.
7. Оплаты действительно не было
Бывает и так. Проверьте статус заказа:
curl -s https://kazpayment.kz/api/v1/orders/SHOP-1042 \
-H "Authorization: Bearer $KAZPAYMENT_KEY"
Если статус не paid — события и не должно было быть. Смотрите в кабинете
раздел «Расхождения»: туда попадают поступления, которым не нашлось нашего
счёта — например, клиент заплатил по старой ссылке или другой суммой.
Помните и про режим: в тестовом режиме настоящих оплат не бывает, статус меняется, только когда вы сами отмечаете оплату в кабинете (событие при этом уходит по-настоящему — это удобно для отладки).
Короткий чек-лист
GET /api/v1/webhook— адрес есть? попытки есть? какая ошибка?- Адрес https, публичный, без редиректа?
POST /api/v1/webhook/test— тестовое событие доходит?- Обработчик отвечает 2xx за 10 секунд?
- Секрет актуальный, подпись считается от сырых байт?
- Заказ вообще оплачен (
GET /api/v1/orders/<ref>)?
Не сошлось — напишите на support@kazpayment.kz, приложив номер заказа и время: по ним видно всю историю доставок с нашей стороны.
Не помогло? Напишите на support@kazpayment.kz — отвечает разработчик сервиса.