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

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

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

Шаг 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-ключ и вебхук-секрет».

Шаг 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-счёт.

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

Путь счёта: processingpendingpaid / cancelled / expired; если выставить не удалось — error. Вебхуки приходят на переходы в pending, paid, cancelled, expired, error, partially_refunded; на технические processing и cancelling вебхуков не бывает.

Не пересоздавайте счёт, пока он в processing: получатся два живых счёта, и покупатель может оплатить оба. Бывают законные «странные» переходы — cancelled → paid, expired → paid, error → pending, — их надо заложить в обработчик. Что означает каждый статус и как обрабатывать поздний paid — «Жизненный цикл счёта».

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

Передавайте 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 Уточнить номер у покупателя; счёт на этот номер невозможен
session_transient Проблема с авторизацией кассира Kaspi Создать счёт заново; если повторяется — переподключить кассира: Настройки → «Авторизация Kaspi»
kaspi_throttled Kaspi ограничил частоту запросов кассира Счёт финален, автоповторов нет: подождать 2–3 минуты, снизить темп выставления и создать новый счёт
network_unavailable Kaspi временно недоступен Повторить через 1–2 минуты
unknown_error Попытки исчерпаны без диагноза Написать в поддержку с id счёта

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

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

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

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

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

Да: POST /invoices/{id}/cancel — только для pending/processing и только для счёта на номер телефона. QR-счёт отменить нельзя — запрос отвечает 409 qr_cancel_unsupported, статус не меняется, QR гаснет сам (см. «QR-счёт: TTL и лимиты»). В рабочем режиме ответ 202 и статус cancelling. После 202 счёт отменённым не считайте — исходов три: вебхук cancelled; вебхук error с invoice_already_paid; либо тихий откат в pending без вебхука (обычно «уже оплачен») — реальный статус в этом случае принесёт следующий вебхук синхронизации или GET /invoices/{id}.

Почему сумма с копейками не проходит?

Счёт на номер телефона принимает только целые тенге: дробная сумма отбивается сразу с 422 amount_must_be_whole_tenge, и счёт не создаётся. Проверяется и голая amount, и итог корзины после скидокdiscount_percentage считается построчно, поэтому даже при целых ценах итог может стать дробным (999 ₸ со скидкой 10 % дают 899.10). Округлите цены позиций или процент скидки. Нужны копейки — выставляйте счёт через POST /invoices/qr: там суммы с тиынами принимаются. То же правило действует на списания по подписке и на оплату с печатного листа по номеру телефона — там дробная сумма даёт статус error.

Оплата не приходит — что проверить?

В песочнице счета в Kaspi не уходят и push не приходит: для реальных оплат включите «Рабочий режим» в Настройках (см. «Песочница и рабочий режим»).

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

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

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

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

Написать в WhatsApp

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