# Счёт завис в статусе pending

> Pending — не ошибка, а нормальное состояние: счёт выставлен, покупатель ещё не подтвердил. Сколько он живёт, когда станет expired, как мы его проверяем и когда действительно стоит волноваться.

## Коротко

`pending` — это **состояние ожидания, а не ошибка**. Оно означает «счёт выставлен, покупатель пока не подтвердил оплату». В этом статусе счёт живёт до конца своего срока, а затем сам переходит в `expired`. Делать ничего не нужно: мы постоянно проверяем счёт в фоне, и в момент оплаты статус меняется на `paid`, а вам уходит вебхук. Волноваться стоит только в одном случае — если в pending застревают **все** ваши счета подряд.

## Статусы счёта

```
new → pending → paid
              → cancelled
              → expired
```

Оплаченный счёт позже может стать `refunded` или `partially_refunded`.

| Статус | Что значит | Открыт |
|---|---|---|
| `new` | Счёт создан, ещё не показан покупателю | Да |
| `pending` | Показан покупателю, ждёт подтверждения | Да |
| `paid` | Покупатель оплатил, деньги на вашем счёте Kaspi | Нет |
| `cancelled` | Вы отменили счёт | Нет |
| `expired` | Срок истёк, оплаты не было | Нет |

`new` и `pending` считаются открытыми — они ещё могут быть оплачены. `paid`, `refunded` и `partially_refunded` считаются оплаченными.

## Сколько он живёт

Зависит от вида счёта, и срок задаёт Kaspi — продлить его со своей стороны мы не можем.

| Вид | Что это | Срок |
|---|---|---|
| `qr` | QR-код и ссылка на оплату | Окно сканирования короткое, около трёх минут |
| `phone` | Push в приложение Kaspi покупателя | Дольше: покупатель может открыть уведомление позже |

**Не зашивайте конкретное число в код.** В ответе на создание счёта приходит поле `expiresAt` — берите срок оттуда. Если Kaspi изменит окно, ваш код подстроится сам.

Когда окно QR истекает, покупатель при сканировании видит сообщение «попробуйте позже». Об этом отдельная статья: [QR показывает «попробуйте позже»](/kb/ru/qr-expired).

## Как мы это проверяем

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

| Возраст счёта | Частота проверки |
|---|---|
| До 3 минут | В каждом цикле |
| До 30 минут | Раз в 20 секунд |
| Старше | Раз в 90 секунд |

Очередь начинается с самых свежих счетов — то есть оплата покупателя, который стоит у кассы прямо сейчас, проверяется в первую очередь. На практике вебхук после оплаты приходит обычно в пределах **пяти секунд**.

Важная оговорка: **Kaspi не передаёт точное время оплаты.** Поэтому измерить по данным Kaspi, сколько прошло от подтверждения покупателем до момента, когда мы узнали об оплате, невозможно.

## Когда действительно стоит волноваться

Сам по себе pending — не проблема. Проблема — вот это:

- **Все счета остаются в pending и ни один не становится paid.** Скорее всего включён тестовый режим: [Оплата не приходит покупателю](/kb/ru/payment-not-arriving).
- **Покупатель говорит, что оплатил, а счёт всё ещё pending.** Подождите минуту. Если не изменился, уточните операцию в приложении Kaspi: оплата могла уйти по совсем другому счёту.
- **Счёт стал paid, но вебхук до вас не дошёл.** Это отдельная проблема: [Вебхук не приходит](/kb/ru/webhook-not-arriving).
- **Счета в pending копятся сотнями.** Возможно, ваш код выставляет лишние счета, которые никто не собирается оплачивать.

## Чего делать не надо

- **Не считайте pending оплатой.** Выдавайте товар или услугу только после статуса `paid`.
- **Не создавайте одному покупателю счёт за счётом.** Пока старый в pending, новый может быть оплачен вдобавок к нему — человек заплатит дважды.
- **Не опрашивайте статус слишком часто.** Мы и так проверяем его сами, а частый опрос упрётся в ограничение частоты запросов.
- **Не пытайтесь вернуть деньги по pending-счёту.** Он ещё не оплачен, возвращать нечего.

## Поздняя оплата

Бывает, что деньги приходят по счёту, который уже стал `expired` или `cancelled`. Тогда событие `invoice.paid` приходит вам позже и с пометкой **`late: true`**.

Это настоящая оплата — деньги на вашем счёте Kaspi. Дальше выбор из двух: оказать услугу или вернуть деньги. Правильнее всего сразу научить обработчик замечать признак `late` и складывать такие счета в отдельный список для разбора.

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

**Можно ли отменить счёт в pending?** Да, через `POST /api/v1/invoices/{id}/cancel`. Если покупатель ещё не оплатил, счёт закроется.

**Можно ли оживить expired-счёт?** Нет, создаётся новый.

**Считаются ли pending-счета в лимит тарифа?** Месячный лимит считается по количеству созданных счетов, а не оплаченных.

**Покупатель отсканировал QR, но не заплатил — статус изменится?** Нет, статус становится `paid` только после реального подтверждения. Само сканирование оплатой не является.

**Как вывести счёт из pending в песочнице?** Через `POST /api/v1/invoices/{id}/simulate` вы сами задаёте нужный статус. Этот метод работает только в песочнице.
