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

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

**TL;DR.** Счёт ApiPay проходит путь **created → processing → pending → paid / cancelled / expired**. Сразу после создания по номеру счёт в статусе `processing` — Kaspi ещё не вызван; обычно за секунды он становится `pending` (ждёт оплаты). Счёт живёт в Kaspi **24 часа**: за это время он либо `paid` (оплачен), либо `cancelled` (отменён), либо `expired` (истёк). Деньги при оплате идут **напрямую на ваш Kaspi-счёт** — ApiPay их не держит. На каждом значимом переходе приходит вебхук `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 часа) | `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` нет):

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

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

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

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

### processing — счёт создаётся
Когда вы вызываете `POST /invoices`, ApiPay сразу отвечает **201** со статусом `processing`. Это значит: запрос принят, но Kaspi ещё **не** вызван — создание идёт в фоне. Система сама повторяет обращение к Kaspi (до 200 попыток, интервал пробуждения ≤30 с), обрабатывая сеть, сессию и троттлинг Kaspi. Обычно это секунды.

Важно понимать про анти-панику: при большой очереди у кассира счёт может держаться в `processing` **дольше 60 минут** — это **не** зависание, а легитимный бэклог под троттлингом Kaspi. **Не пересоздавайте счёт, пока он в `processing`** — иначе получите два живых счёта. Вебхука на `processing` нет.

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

### paid — оплачен, деньги пришли
Покупатель оплатил. Приходит вебхук со статусом `paid`, а деньги поступают **напрямую на ваш Kaspi-счёт** — ApiPay к ним доступа не имеет. Скорость, с которой ApiPay замечает оплату, зависит от активности организации: у «горячей» — 10–30 секунд, у «спящей» детект может занять **до ~10 минут**. Сами деньги при этом уже у вас в Kaspi — задержка только в том, когда ApiPay узнает об оплате и пришлёт вебхук.

### cancelled / expired — не оплачен
`cancelled` — счёт отменён: вами через API/кабинет или покупателем (закрыл/свернул приложение). `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`. Ошибочный счёт оплаченным не становится.

Практический вывод для интеграторов: **не считайте `cancelled`/`expired` окончательными деньгами-мимо** — дождитесь, что статус устоялся, и всегда обрабатывайте поздний `paid`. Подробнее про идемпотентную обработку — в [настройке вебхуков](/guides/nastroyka-webhookov-apipay).

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

- **`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.status_changed` приходит ровно один раз (есть гейт). Отвечайте на вебхук **2xx до 5 секунд**, а обработку делайте асинхронно.

## Частые ошибки

- **Пересоздавать счёт, «зависший» в `processing`.** Это почти всегда легитимный бэклог под троттлингом Kaspi — пересоздание даёт два живых счёта. Дождитесь `pending` или `error`.
- **Считать `cancelled`/`expired` финалом.** Возможен поздний `paid` (покупатель успел оплатить). Обрабатывайте его.
- **Ждать вебхук на `processing` или `cancelling`.** Их нет. Ориентируйтесь на `pending`/`paid`/`cancelled`/`expired`.
- **Думать, что деньги идут через ApiPay.** Оплата поступает напрямую на ваш Kaspi-счёт; ApiPay лишь сообщает вам о ней вебхуком.
- **Искать статус `refunded` у счёта.** Его нет: после возврата счёт остаётся `paid` или становится `partially_refunded`.

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

**Почему счёт долго в статусе processing?**
`processing` означает, что счёт ещё создаётся в Kaspi. Обычно это секунды, но при большой очереди у кассира счёт может держаться дольше 60 минут под троттлингом Kaspi — это не зависание. Не пересоздавайте его, дождитесь `pending` или `error`.

**Когда приходят деньги за оплаченный счёт?**
Сразу при оплате — напрямую на ваш Kaspi-счёт. ApiPay деньги не держит. Вебхук `paid` приходит, когда ApiPay заметил оплату: у активных организаций за 10–30 секунд, у «спящих» — до ~10 минут. Деньги при этом уже у вас.

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

**На какие статусы приходит вебхук?**
На `pending`, `paid`, `cancelled`, `expired`, `error`, `partially_refunded` — событие `invoice.status_changed`. Технические `processing` и `cancelling` вебхуков не порождают.

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

---

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