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

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

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

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

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. Подробнее про идемпотентную обработку — в настройке вебхуков.

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

  • 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.

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

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

Скопируйте готовый промпт и вставьте своему ИИ-ассистенту — он подключит приём платежей примерно за 15 минут. Настраивает ИИ, а не вы.

Остались вопросы — напишите нам в WhatsApp: +7 708 516 74 89. Отвечаем быстро, без звонков.

Написать в WhatsApp

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