> Источник: https://apipay.kz/guides/zhiznennyy-tsikl-scheta · Обновлено: 2026-07-06 · apipay.kz
> ApiPay — независимый сервис приёма платежей поверх вашего Kaspi Pay.

# Жизненный цикл счёта: от создания до денег на счёте

**TL;DR.** Счёт ApiPay проходит путь **processing → pending → paid / cancelled / expired**. Счёт по номеру живёт в Kaspi **24 часа**; у QR-счёта окно на скан своё и заметно короче — см. «[QR-счёт: TTL и лимиты](/guides/qr-schet-ttl-i-limity)».

Деньги при оплате идут **напрямую на ваш Kaspi-счёт**. На каждом значимом переходе приходит вебхук `invoice.status_changed`; технические статусы `processing` и `cancelling` вебхуков **не порождают**. Бывают «странные», но законные переходы — например `cancelled → paid`, если покупатель успел оплатить в последний момент. Что делать, если оплата не приходит, — в статье [«Оплата не приходит»](/guides/oplata-ne-prihodit-kaspi).

## Коротко

| Статус | Что значит | Вебхук |
|---|---|---|
| `processing` | Счёт создаётся, Kaspi ещё вызывается (только для счёта по номеру) | нет |
| `pending` | Счёт в Kaspi, ждёт оплаты | `invoice.status_changed` |
| `paid` | Оплачен, деньги на вашем Kaspi-счёте | `invoice.status_changed` |
| `cancelled` | Отменён (вами или покупателем) | `invoice.status_changed` |
| `expired` | Истёк: счёт по номеру — через 24 часа; QR-счёт — когда Kaspi отдал терминальный статус | `invoice.status_changed` |
| `error` | Не удалось создать в Kaspi | `invoice.status_changed` |
| `cancelling` | Идёт отмена (техническое) | нет |
| `partially_refunded` | Сделан частичный возврат | `invoice.status_changed` |

## Схема жизненного цикла

Счёт по номеру телефона:

```
POST /invoices  →  [processing]  →  [pending]  →  [paid]      деньги на Kaspi-счёте
                       │               │        →  [cancelled] отменён
                       │               │        →  [expired]   истёк (24 ч)
                       │               └─ вебхук pending / paid / cancelled / expired
                       └─ (нет вебхука; если не удалось создать → [error] + вебхук error)
```

QR-счёт создаётся сразу в `pending` (шага `processing` нет), а окно на скан у него своё и заметно короче. Терминальный статус ставит Kaspi — ждите вебхук, а не свой отсчёт. Если оплата нужна «когда покупателю будет удобно» — выставляйте счёт по номеру телефона; про окно, `qr_expires_at` и картинку — «[QR-счёт: TTL и лимиты](/guides/qr-schet-ttl-i-limity)»:

```
POST /invoices/qr  →  [pending]  →  [paid] / [cancelled] / [expired]
                          └─ pending-вебхука нет; есть событие qr_scanned при скане
```

Отмена — только для счёта на номер телефона. QR-счёт (`is_qr_token: true`) отменить нельзя: `POST /invoices/{id}/cancel` отвечает `409 qr_cancel_unsupported`, статус не меняется, QR гаснет сам (см. «[QR-счёт: TTL и лимиты](/guides/qr-schet-ttl-i-limity)»).

Отмена в боевом режиме проходит через техническое `cancelling`:

```
POST /invoices/{id}/cancel  →  [cancelling]  →  [cancelled]   отменён Kaspi, вебхук есть
                                     │        →  [pending]     мягкий отказ (часто «уже оплачен»), вебхука НЕТ
                                     └────────→  [error]       невосстановимая ошибка, вебхук есть
```

Ветка `cancelling → pending` вебхука не порождает: реальный статус (обычно `paid`) принесёт следующий вебхук синхронизации или `GET /invoices/{id}`. После `202` счёт отменённым не считайте.

## Что происходит на каждом шаге

### processing — счёт создаётся
Когда вы вызываете `POST /invoices`, ApiPay сразу отвечает **201** со статусом `processing`: запрос принят, Kaspi вызывается в фоне. Штатно это секунды. Вебхука на `processing` нет.

Задержка дольше нескольких минут означает одно из двух: у организации включён «Режим накопления счетов» (Настройки → Организация — счета копятся и уходят в Kaspi пачкой раз в заданное окно) либо выставить счёт в Kaspi не удалось — тогда сервис сам финализирует счёт в `error` и присылает вебхук. **Не пересоздавайте счёт, пока он в `processing`**: получатся два живых счёта, и покупатель может оплатить оба.

### pending — ждёт оплаты
Счёт создан в Kaspi и отправлен покупателю. Приходит вебхук `invoice.status_changed` со статусом `pending`. С этого момента счёт по номеру живёт **24 часа**. У QR-счёта `pending` наступает сразу при создании, и отдельного pending-вебхука по нему не отправляется.

### paid — оплачен, деньги пришли
Покупатель оплатил. Приходит вебхук со статусом `paid`, деньги поступают **напрямую на ваш Kaspi-счёт**. Вебхук обычно приходит за 10–30 секунд, в отдельных случаях — до 10 минут; деньги при этом уже у вас, задержка только в уведомлении.

### cancelled / expired — не оплачен
`cancelled` — счёт отменён: вами через API/кабинет или покупателем (закрыл/свернул приложение); у QR-счёта — только покупателем, своей отмены у QR нет. `expired` — истекли 24 часа, и Kaspi отдал терминальный статус. На оба перехода приходит вебхук.

### error — не удалось создать
Если после всех попыток счёт не удалось создать в Kaspi, он финализируется в `error` с осмысленным кодом причины (например `client_not_found` — у номера нет Kaspi). Приходит вебхук со статусом `error`.

## «Странные», но законные переходы

Из-за гонок между оплатой и отменой возможны такие последовательности — заложите их в обработчик:

- **`cancelled → paid`** — вы (или система) отменили счёт, но покупатель успел оплатить на долю секунды раньше. Оплата выигрывает: счёт становится `paid`, деньги у вас. Придёт корректирующий вебхук `paid`.
- **`expired → paid`** — то же самое на границе 24 часов: оплата прошла в последний момент.
- **`error → pending`** — реконсиляция: счёт, отмеченный ошибочным, при сверке с Kaspi оказался живым. Придёт корректирующий вебхук.
- **`paid → partially_refunded`** — по оплаченному счёту сделали частичный возврат. Полного статуса `refunded` у счёта **не существует** — после полного возврата счёт остаётся `paid` с признаком «полностью возвращён».

Прямого перехода `error → paid` не бывает: ошибочный счёт сначала должен ожить при сверке (`error → pending`) и только потом может быть оплачен. Не считайте `error`, `cancelled` и `expired` окончательными: обрабатывайте поздний `paid`.

## Какой вебхук на каком переходе

- **`invoice.status_changed`** — на переходах в `pending`, `paid`, `cancelled`, `expired`, `error`, `partially_refunded`.
- **`invoice.qr_scanned`** — покупатель отсканировал QR (счёт ещё `pending`, маркер `qr_substate: scanned`); приходит один раз на QR.
- **`invoice.refunded`** — обработан возврат (`completed` или `failed`).
- Технические `processing` и `cancelling` вебхуков **не порождают** — на них не завязывайтесь.

Один и тот же переход сервис повторно не отправляет, но дубль доставки всё же возможен — делайте обработчик идемпотентным и дедуплицируйте по паре `(invoice.id, invoice.status)`. Требования к ответу обработчика и правила ретраев — в «[Настройке вебхуков](/guides/nastroyka-webhookov-apipay)».

«Вебхука нет» не значит «оплаты нет»: сверяйте статус через `GET /invoices/{id}` или раздел «Счета» в кабинете, а причины молчания разбирайте по статье «[Вебхук не приходит](/guides/webhook-ne-prihodit)».

## Частые вопросы

**Счёт был cancelled, а стал paid — это ошибка?**
Нет, это законно: покупатель оплатил на долю секунды раньше отмены, и оплата выиграла гонку. Придёт корректирующий вебхук `paid`, деньги у вас. То же с `expired → paid` на границе 24 часов.

**Есть ли статус refunded?**
Нет. После полного возврата счёт остаётся `paid` с признаком «полностью возвращён»; после частичного — становится `partially_refunded`.

---

ApiPay — независимый сервис и не аффилирован с АО «Kaspi Bank». Kaspi и Kaspi Pay — товарные знаки их правообладателя.
База знаний: https://apipay.kz/guides
