Как создать счёт Kaspi по номеру телефона через API?

Обновлено 6 июля 2026 · Справочник · Версия в Markdown
Содержание
  1. Три шага: запрос → ответ → покупатель платит
  2. Какие статусы проходит счёт?
  3. «Странные» переходы статусов, которые НЕ баг
  4. Как не выставить два счёта за один заказ?
  5. Почему счёт ушёл в error?
  6. Частые ошибки
  7. Вопросы и ответы

Три шага: запрос → ответ → покупатель платит

Шаг 1. Отправьте запрос

curl -X POST https://api.apipay.kz/api/v1/invoices \
  -H "X-API-Key: ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "87001234567",
    "amount": 5000,
    "description": "Оплата заказа №123",
    "external_order_id": "order-123",
    "external_order_id_idempotency": "order-123"
  }'

Номер — 11 цифр, начинается с 8: 8XXXXXXXXXX. API-ключ берётся в кабинете apipay.kz (Настройки → API-ключи); полный ключ показывается только один раз при создании — подробнее в статье «API-ключ и вебхук-секрет».

Шаг 2. Получите ответ 201 со статусом processing

{
  "id": 1,
  "amount": "5000.00",
  "status": "processing",
  "phone": "77001234567",
  "created_at": "2026-07-02T10:25:00+06:00"
}

processing означает «принято в работу»: выставление счёта в Kaspi происходит асинхронно, в фоне. Ничего опрашивать в цикле не нужно — итоговый статус придёт вебхуком (настройка — «Как настроить вебхуки ApiPay»). Для отладки текущее состояние можно посмотреть запросом GET /invoices/{id} — там же видны поля last_kaspi_error_code и last_kaspi_error_message, если Kaspi отвечал ошибкой между повторами.

Шаг 3. Что видит покупатель

Покупателю приходит push-уведомление в приложении Kaspi: счёт с вашим описанием и суммой, кнопка «Оплатить» — оплата в одно касание, деньги идут напрямую на ваш Kaspi-счёт. Счёт доступен к оплате 24 часа. После оплаты вам приходит вебхук invoice.status_changed со статусом paid — обычно в течение 10–20 секунд.

Какие статусы проходит счёт?

Статус Что значит
processing Принят, выставляется в Kaspi (асинхронно, с автоповторами)
pending Выставлен, ждёт оплаты (до 24 часов)
paid Оплачен — финальный «хороший» статус
cancelled Отменён (вами через API или покупателем)
expired Истекли 24 часа без оплаты
error Выставить не удалось; в вебхуке будет error_code с причиной
cancelling Отмена в процессе (прод: 202 на запрос отмены); вебхука на этот статус нет
partially_refunded Был частичный возврат

Вебхуки приходят на переходы в pending, paid, cancelled, expired, error, partially_refunded. На технические статусы processing и cancelling вебхуков не бывает.

«Странные» переходы статусов, которые НЕ баг

Это самый важный раздел — он экономит обращения в поддержку. Все переходы ниже легитимны, закладывайте их в код:

  • processing дольше 60 минут — не зависание. Если Kaspi временно ограничил частоту запросов (троттлинг), система выдерживает паузы и повторяет выставление — до 200 попыток. Легитимная очередь кассира может держать счёт в processing больше часа. Не пересоздавайте счёт в processing — получите два живых счёта и двойную оплату.
  • cancelledpaid и expiredpaid. Покупатель оплатил в последний момент, и оплата «выиграла гонку» у отмены/истечения. Придёт корректирующий вебхук paid — засчитайте оплату.
  • errorpending. Система сверилась с Kaspi и обнаружила, что счёт всё-таки выставлен, — придёт корректирующий вебхук.
  • errorpaid невозможен. Если счёт в error, без промежуточного pending оплаты не будет.
  • Детект оплаты у «спящей» организации — до ~10 минут. Частота сверки адаптивная: у активно продающих организаций оплата видна за 10–30 секунд, у организации после долгой паузы первая оплата может подтянуться в пределах 10 минут.

Как не выставить два счёта за один заказ?

Передавайте external_order_id_idempotency (до 191 символа, уникален в пределах организации — удобно класть туда ID заказа). Повторный запрос с тем же значением вернёт 409 duplicate_idempotency_key с invoice_id и status уже существующего счёта — дубль не создастся, даже при гонке двух параллельных запросов.

Исключение по смыслу: если прежний счёт уже мёртв (expired, cancelled, error), повторный запрос с тем же ключом создаст новый счёт — это осознанное поведение для перевыставления неоплаченного заказа. Для живых статусов (processing, pending, paid, partially_refunded) всегда будет 409.

Почему счёт ушёл в error?

В вебхуке и в GET /invoices/{id} будет машиночитаемый error_code. Самые частые:

error_code Причина Что делать
client_not_found Номер не зарегистрирован в Kaspi Уточнить номер у покупателя; счёт на этот номер невозможен
Ошибка авторизации кассира Привязка кассира разорвалась Переподключить за 1 минуту: Настройки → «Авторизация Kaspi»
kaspi_throttled Kaspi ограничил частоту Подождать 2–3 минуты; система замедлится сама
network_unavailable Kaspi временно недоступен Повторить через 1–2 минуты
unknown_error Попытки исчерпаны без диагноза Написать в поддержку с id счёта

Важно: если статус уже error — система свои повторы исчерпала, счёт финален. «Повторить» = создать новый счёт.

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

  • Поллить GET /invoices/{id} в цикле вместо вебхука. Работает, но это лишняя нагрузка и задержка; рекомендуемый канал — вебхук. Лимит API — 200 запросов/мин на ключ.
  • Пересоздавать счёт, пока он в processing. Получите два живых счёта. Ждите терминального статуса или используйте идемпотентность.
  • Передавать номер с +7 или 10 цифр. Формат строго 8XXXXXXXXXX (11 цифр, первая — 8). В ответах API номер возвращается нормализованным (77001234567) — это нормально.
  • Считать processing в ответе ошибкой. Это штатный ответ: выставление асинхронное.
  • Не передавать external_order_id_idempotency. При сетевом таймауте ваш повторный запрос создаст второй счёт — покупатель получит два push.
  • Ждать оплату в песочнице. В тестовом режиме счета в Kaspi не уходят — push не приходит. Переключите «Рабочий режим» в Настройках.

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

Сколько живёт счёт по номеру телефона?

24 часа с момента выставления. Не оплачен за 24 часа — перейдёт в expired (придёт вебхук). QR-счёт — отдельный формат со временем жизни 5 минут: «QR-счёт: TTL и лимиты».

Через сколько после оплаты я узнаю о ней?

Обычно за 10–20 секунд приходит вебхук paid. У организации, которая долго не выставляла счета, первая сверка может занять до ~10 минут.

Что будет, если у покупателя нет Kaspi?

Счёт уйдёт в error с кодом client_not_found. Заранее проверить номер можно запросом POST /clients/check (лимит 60/мин на ключ).

Можно ли отменить выставленный счёт?

Да: POST /invoices/{id}/cancel — только для pending/processing. В рабочем режиме ответ 202, отмена асинхронная; если покупатель успел оплатить, придёт error с invoice_already_paid или счёт останется оплаченным.

Обязательно ли указывать amount?

Либо amount, либо корзина cart_items (тогда сумма считается по позициям каталога): «Счета с корзиной (cart_items)».

Счёт висит в processing уже час — это зависание?

Чаще всего нет: при троттлинге со стороны Kaspi система замедляется и повторяет — хвост очереди легитимно живёт больше 60 минут. «Зависшие» счета контролируются автоматикой: мёртвый процесс финализируется в error с осмысленным кодом и вебхуком.

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

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

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

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

Написать в WhatsApp

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