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

Обновлено 6 июля 2026 · Справочник · Версия в Markdown
Содержание
  1. Схема жизненного цикла
  2. Что происходит на каждом шаге
  3. «Странные», но законные переходы
  4. Какой вебхук на каком переходе
  5. Частые вопросы

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

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

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

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

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 и лимиты»).

Отмена в боевом режиме проходит через техническое 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). Требования к ответу обработчика и правила ретраев — в «Настройке вебхуков».

«Вебхука нет» не значит «оплаты нет»: сверяйте статус через GET /invoices/{id} или раздел «Счета» в кабинете, а причины молчания разбирайте по статье «Вебхук не приходит».

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

Счёт был cancelled, а стал paid — это ошибка?

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

Есть ли статус refunded?

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

Интеграция с ИИ

Не настраивайте вручную — поручите ИИ

Скопируйте готовый промпт и вставьте своему ИИ-ассистенту — он настроит интеграцию за вас: получит доступы, создаст тестовый счёт в песочнице и подключит вебхуки. Техническую часть делает ИИ, а не вы.

Остались вопросы — напишите нам в WhatsApp: +7 700 307 65 12. Отвечаем быстро, без звонков.

Написать в WhatsApp

Для разработчика. Полная спецификация API — apipay.kz/docs. Эта статья в Markdown — /guides/zhiznennyy-tsikl-scheta.md. Справочник фактов для ИИ-агента — apipay.kz/llms.txt.