> Источник: https://apipay.kz/guides/kak-sozdat-schet-kaspi-po-nomeru · Обновлено: 2026-08-26 · apipay.kz
> ApiPay — независимый сервис приёма платежей поверх вашего Kaspi Pay.

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

**TL;DR.** Один запрос `POST /invoices` с заголовком `X-API-Key`: передаёте номер покупателя в формате `8XXXXXXXXXX` и сумму — покупатель получает push-уведомление в приложении Kaspi и оплачивает в одно касание. Счёт живёт **24 часа**. API отвечает мгновенно со статусом `processing`: выставление в Kaspi асинхронное, итог принесёт вебхук. После оплаты статус `paid` обычно виден за **10–30 секунд**.

## Коротко

| Вопрос | Ответ |
|---|---|
| Эндпоинт | `POST https://api.apipay.kz/api/v1/invoices` |
| Авторизация | Заголовок `X-API-Key` (ключ — в кабинете, показывается один раз) |
| Обязательные поля | `phone_number` (формат `8XXXXXXXXXX`) + `amount` (или `cart_items` вместо суммы) |
| Сумма | Только целые тенге, от `1`. Дробная — `422 amount_must_be_whole_tenge` |
| Описание счёта | `description` до 60 символов — Kaspi показывает покупателю только первые 60 |
| Ответ | `201` со статусом `processing` — Kaspi вызывается асинхронно, итог принесёт вебхук |
| Сколько живёт счёт | 24 часа |
| Как узнать об оплате | Вебхук `invoice.status_changed` со статусом `paid`; обычно за 10–30 секунд |
| Защита от дублей | `external_order_id_idempotency` → повтор даёт `409` |
| Лимит запросов | 200 запросов в минуту на API-ключ |

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

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

```bash
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-ключ и вебхук-секрет](/guides/api-klyuch-i-webhook-secret)».

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

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

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

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

Покупателю приходит push-уведомление в приложении Kaspi: счёт с вашим описанием и суммой, кнопка «Оплатить». Деньги идут напрямую на ваш Kaspi-счёт.

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

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

**Не пересоздавайте счёт, пока он в `processing`**: получатся два живых счёта, и покупатель может оплатить оба. Бывают законные «странные» переходы — `cancelled → paid`, `expired → paid`, `error → pending`, — их надо заложить в обработчик. Что означает каждый статус и как обрабатывать поздний `paid` — «[Жизненный цикл счёта](/guides/zhiznennyy-tsikl-scheta)».

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

Передавайте `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 и лимиты](/guides/qr-schet-ttl-i-limity)»). В рабочем режиме ответ `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 не приходит: для реальных оплат включите «Рабочий режим» в Настройках (см. «[Песочница и рабочий режим](/guides/pesochnitsa-i-rabochiy-rezhim)»).

Смотрите также: [Счета с корзиной (cart_items)](/guides/scheta-s-korzinoy-cart-items-ofd) · [QR-счёт: TTL и лимиты](/guides/qr-schet-ttl-i-limity) · [Вебхуки ApiPay](/guides/nastroyka-webhookov-apipay) · пиллар «[Как принимать оплату Kaspi через API](/kaspi-api)» · страница «[Счёт по номеру телефона](/invoice-by-phone)».

---

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