> Источник: https://apipay.kz/guides/apipay-dlya-taksoparka-i-billinga · Обновлено: 2026-07-06 · apipay.kz
> ApiPay — независимый сервис приёма платежей поверх вашего Kaspi Pay.

# Как таксопарку выставлять сотни счетов Kaspi водителям автоматически?

**TL;DR.** ApiPay закрывает сценарий массового биллинга: таксопарки, логистика, аренда — все, кому надо регулярно выставлять десятки и сотни счетов физлицам по спискам. Водитель получает push в Kaspi (либо платит по QR-счёту) — вам приходит вебхук `paid`, баланс водителя пополняется в вашей системе. Деньги идут напрямую на счёт парка; ApiPay берёт фиксированный тариф, не процент. Два обязательных инструмента: **идемпотентность** `external_order_id_idempotency` (защита от дублей) и **bulk-выставление** (`POST /invoices/bulk`, до 100 счетов за запрос).

## Как это работает у вас

В терминах парка:

**Ваша система биллинга формирует список «водитель → сумма за смену» → выставляет счета через API (по одному или пачкой) → каждый водитель получает push в своём Kaspi → оплатил → ApiPay шлёт вебхук `paid` → ваша система закрывает задолженность водителя.**

Для массового биллинга важна равномерность потока во времени, а не только дневной объём: Kaspi ограничивает частоту запросов кассира, и плотный залп в этот троттлинг упирается. Пачка `POST /invoices/bulk` экономит сетевые обращения и даёт один общий ответ, но темп выставления в Kaspi не меняет — разносите биллинг волнами сами.

Создание счёта асинхронное: `201` со `status: processing`, дальше вебхук переводит счёт в `pending` либо в `error`. Счёт, который так и не доехал до Kaspi, система сама закрывает в `error` с `error_code: network_unavailable`.

## Компоненты ApiPay для массового биллинга

Массовый биллинг опирается на несколько частей [Kaspi API](/kaspi-api):

| Компонент | Зачем парку |
|---|---|
| Счёт по номеру | Водитель получает push; счёт живёт 24 часа |
| Идемпотентность (`external_order_id_idempotency`) | Один период = один счёт: повтор запроса не создаст дубль (409) |
| Bulk-выставление | `POST /invoices/bulk`: до 100 счетов одним запросом вместо ста запросов, общий ответ с результатом по каждой позиции |
| Вебхук `paid`/`error` | Автозакрытие задолженности; перевыставление только по `error` |
| Тариф по объёму | Фиксированная подписка под ваш дневной объём счетов — [тарифы и комиссия](/guides/tarify-i-komissiya-apipay) |

## Пошаговый сетап

1. **Зарегистрируйтесь на apipay.kz** и опишите объём поддержке: большие объёмы — обсудите лимит тарифа заранее ([лимит счетов по тарифу](/guides/limit-schetov-po-tarifu)).
2. **Отладьте цикл в песочнице** по apipay.kz/docs: список → счета → вебхуки → закрытие задолженности.
3. **Сразу заложите идемпотентность**: `external_order_id_idempotency` = стабильный ID начисления. Если ваш внутренний ID длинный и «грязный» (например, `A000AA00 за 03.06…`) — возьмите от него md5-хэш и передавайте его: ключ ограничен 191 символом и должен быть одинаковым при всех повторах запроса.
4. **Подключите номер кассира** ([требования](/guides/trebovaniya-k-nomeru-kassira)) и включите рабочий режим. **До одобрения анкеты «Расскажите о бизнесе»** ([зачем](/guides/anketa-o-biznese-i-limit)) организация ограничена **одним реальным платежом в сутки**: в `POST /invoices/bulk` остальные позиции вернутся в `failed[]` с `error_code: kyc_daily_limit_reached`. Массовый биллинг запускайте после одобрения.
5. **Постройте обработку статусов**: `paid` → закрыть долг; `error` → перевыставить самим; `processing` → ждать, ничего не делать.
6. **Спланируйте расписание**: списки отправляйте bulk-запросами, а сам биллинг разносите на волны (например, по сменам) — темп задаёте вы, bulk его не сглаживает.

## Грабли именно массового биллинга

- **Двойное списание без идемпотентности.** Типичный инцидент: два одинаковых POST с одного ключа, оба получили 201, водитель получил 2 push и оплатил оба. Без `external_order_id_idempotency` каждый POST — новый живой платёж. С ним повтор получает 409.
- **Пересоздание счетов в `processing`.** Не пересоздавайте счёт, пока он в `processing`: получатся два живых счёта, и водитель может оплатить оба. Ждите терминального статуса — счёт либо перейдёт в `pending`, либо система сама закроет его в `error` с вебхуком.
- **Плотный залп ловит троттлинг Kaspi.** Такие счета уходят не в `cancelled`, а в терминальный `error` с `error_code: kaspi_throttled` («попробуйте через 2–3 минуты») — их надо перевыставлять новым счётом, ждать бесполезно. Решение — разносить выставление во времени волнами.
- **Один номер — один кошелёк.** Если в списке ошибочный номер, Kaspi может срезолвить его в реальный чужой аккаунт — все счета упадут в один кошелёк, а настоящие водители их не увидят. Валидируйте номера водителей при онбординге.

## Контракт bulk-выставления

`POST /api/v1/invoices/bulk` — до 100 счетов за запрос, все на одного кассира, лимит 20 запросов/мин; элементы — те же поля, что у `POST /invoices`.

Ответ `201`: `{created, duplicates, failed, invoices:[{index, status:"created"|"duplicate"|"failed", ...}]}` — разбирайте поэлементно по `index`. Структурная ошибка тела отклоняет весь батч атомарно (`422`).

Лимиты приходят поэлементно в `failed[]` (`kyc_daily_limit_reached`, `tariff_limit_reached` — только `error_code` и `message`, без `Retry-After` и `meta`), а `403 tariff_inactive` отбивает весь запрос целиком: причина не в позиции, а в организации.

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

**Можно ли спокойно выставлять сотни счетов в день?**
Да, в пределах дневного лимита вашего тарифа — но ровным потоком, а не залпом: частоту ограничивает Kaspi.

**Нужна ли заявка на официальное партнёрство Kaspi?**
Нет. ApiPay — независимый сервис, не официальная интеграция; нужен только открытый счёт Kaspi Pay вашего парка.

**Водители без Kaspi есть — что с ними?**
Счёт уйдёт только владельцу Kaspi-аккаунта; для остальных предусмотрите другой канал оплаты и обрабатывайте ошибку `client_not_found` из вебхука.

---

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