# Вебхук или опрос статуса: что когда

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

## Коротко

**Вебхук — основной способ.** Когда клиент оплатил, мы сами приходим на ваш адрес, вам ничего не нужно спрашивать.

Но вебхук идёт по сети, а сеть не идеальна: ваш сервер может перезагружаться, хостинг — не ответить. Поэтому в сценариях, **чувствительных к задержке** (шлагбаум, вендинг, касса, прямой эфир), ведите оба механизма параллельно: если вебхук не пришёл за отведённое время, спросите статус сами через `GET /api/v1/invoices/{id}`.

Там, где несколько секунд ничего не решают — интернет-магазин, CRM, отчётность — достаточно одного вебхука.

## Чем они отличаются

| | Вебхук | Опрос статуса (polling) |
|---|---|---|
| Кто инициирует | Мы | Вы |
| Что нужно с вашей стороны | Доступный извне адрес на `https` | Только исходящий интернет |
| Задержка | Обычно в пределах 5 секунд | Равна вашей частоте опроса |
| Гарантия доставки | Высокая, но не абсолютная | Ответ приходит на каждый ваш запрос |
| Проверка подписи | Нужна | Не нужна |
| Работает без своего сервера | Нет | Да |

## Почему вебхук всё-таки основной

После оплаты наш поллер забирает статус у Kaspi и в тот же момент уведомляет вас. **На практике вебхук приходит в пределах 5 секунд.**

Поллер работает с учётом возраста счёта — свежие проверяются чаще:

| Возраст счёта | Частота проверки |
|---|---|
| Младше 3 минут | Каждый проход, то есть примерно раз в 3 секунды |
| До 30 минут | Примерно раз в 20 секунд |
| Старше | Примерно раз в 90 секунд |

Очередь начинается с самых свежих счетов: счёт, рядом с которым прямо сейчас стоит покупатель, никогда не ждёт позади вчерашних.

Если вебхук не получил ответ 2xx, доставка **повторяется 11 раз** — с паузой, растущей от 10 секунд до 1 часа. А когда адрес отвечает ошибками подряд, он временно ставится на паузу (5 неудач — 5 минут, 10 — 30 минут, 20 — 2 часа, 50 — отключение). Это защита и вашего сервера, и очереди, но знать о ней нужно: пока адрес на паузе, вебхуки не приходят вовсе.

Подробно: [Настройка вебхуков](/kb/ru/webhook-setup).

## Когда нужны оба механизма

Не полагайтесь на один вебхук в таких сценариях:

- **Шлагбаум, турникет, дверь.** Клиент сидит в машине, ждать полминуты неприемлемо
- **Вендинговый автомат.** Человек стоит перед автоматом
- **Офлайн-касса.** За спиной очередь
- **Прямой эфир, быстрые продажи.** Десятки секунд — это потерянная продажа
- **Курьер доставки.** Стоит у двери

Общий признак: **человек ждёт, и десятки секунд стоят дорого**.

Одного вебхука достаточно там, где:

- Интернет-магазин (заказ собирается позже)
- Перевод сделки по этапам в CRM
- Отчётность и бухгалтерия
- Открытие доступа к подписочному сервису

## Как совместить

Схема простая: ждёте вебхук, не дождались — спрашиваете сами.

1. Создаёте счёт, получаете `id`
2. Показываете клиенту QR или ссылку
3. **Запускаете таймер.** Например, на 5 секунд
4. Пришёл вебхук за это время — готово, опрашивать не нужно
5. Не пришёл — отправляете `GET /api/v1/invoices/{id}` и читаете статус
6. Статус `paid` — продолжаете работу
7. Всё ещё `pending` — ждёте дальше

Важно: **вебхук и опрос приводят к одному и тому же результату**, и прийти они могут одновременно. Обработчик должен быть идемпотентным — не обрабатывайте пару `(invoice.id, status)` дважды. Подробно: [Идемпотентность](/kb/ru/idempotency).

## Какую частоту опроса выбрать

«Чаще спрашиваю — быстрее узнаю» здесь не работает: наш поллер забирает статус у Kaspi по своему расписанию, а ваш запрос возвращает лишь то, что у нас уже есть. Десять запросов в секунду ничего не ускорят, зато приведут к 429 (`rate_limited`).

Разумное расписание:

| Возраст счёта | Частота опроса |
|---|---|
| Первые 3 минуты | Раз в 3-5 секунд |
| 3-30 минут | Раз в 20-30 секунд |
| Старше | Раз в 1-2 минуты или прекратить |

Оно совпадает с расписанием нашего поллера: свежие счета и так проверяются часто, а по старым частый опрос бессмыслен.

Дополнительные правила:

- **Опрашивайте только открытые счета.** `paid`, `cancelled`, `expired` — конечные статусы, переспрашивать их не нужно
- **Ограничьте время ожидания.** Прошёл `expiresAt` — прекращайте опрос
- **Забирайте список одним запросом.** Если открытых счетов сотни, вместо опроса каждого используйте `GET /api/v1/invoices`
- **Получили 429** — смотрите заголовок `Retry-After`: [Ограничения частоты запросов](/kb/ru/rate-limits)

## А можно только опрашивать

Да, можно — если у вас нет сервера, доступного снаружи (локальная кассовая программа, система в закрытой сети). Тогда вебхук просто не подключается, и вы работаете через `GET /api/v1/invoices/{id}`.

Минус: запросов больше, а задержка равна вашей частоте опроса. Плюс: не нужны ни входящий адрес, ни проверка подписи, ни сертификат HTTPS.

## Вопросы и ответы

**Если вебхук не пришёл сразу, значит он потерян?** Нет. Он повторится 11 раз, то есть будет пытаться доставиться около часа. Но если ваш бизнес-сценарий не может столько ждать — нужен опрос.

**Если придут оба, я обработаю заказ дважды?** При наличии идемпотентности — нет. Проверяйте по паре `(invoice.id, status)`.

**Опрос расходует лимит тарифа?** Нет. Месячный лимит считается по **количеству счетов**, а не запросов. Но у частоты запросов есть отдельное ограничение, оно отвечает 429.

**Оплата подтверждается медленно — может, опрашивать чаще?** Сначала разберитесь в причине: [Оплата подтверждается медленно](/kb/ru/slow-payments). Учащение не поможет, потому что узкое место — на стороне получения статуса из Kaspi.

**Как проверить, что сам сервис жив?** Для этого есть `GET /api/v1/status`: [Проверка состояния сервиса](/kb/ru/status-endpoint).
