ApiPay API v2 Documentation — ApiPay.kz

Полная документация ApiPay REST API v2 — Автоматизация Kaspi Pay (Phone Payments)

REST API для приёма платежей по номеру телефона через Kaspi Pay. Чеки через Kaspi ОФД, webhooks, поддержка каталога, подписок и возвратов. Без скрытых комиссий.

Подключаете через ИИ-ассистента? Начните с пошагового плейбука интеграции — apipay.kz/for-ai: весь сценарий (подключение кассира, ключи, код, вебхуки, отладка) в одном документе.

Быстрый старт

Песочница доступна сразу! При регистрации создаётся sandbox-организация для тестирования API. Вы можете создавать тестовые счета (is_sandbox=true) до подключения Kaspi Business. Переключение в production — через личный кабинет.
  1. Войдите в личный кабинет apipay.kz/login через WhatsApp
  2. Получите API ключ в Настройки → Подключение
  3. Создавайте счета: POST /api/v1/invoices
  4. Для работы с реальными платежами подключите кассира Kaspi: самостоятельно в личном кабинете (Настройки → Авторизация Kaspi, около 1 минуты) или через WhatsApp поддержки
  5. Настройте webhook в личном кабинете для получения уведомлений об оплате

Базовая конфигурация

ПараметрЗначение
Base URLhttps://bpapi.bazarbay.site/api/v1
АутентификацияHeader X-API-Key: ваш_api_ключ
Rate Limit200 req/min на API-ключ (общий лимит Public API; при превышении 429 + Retry-After)
Content-Typeapplication/json

Обзор эндпоинтов

#МетодПутьОписание
Счета (Invoices)
1POST/invoicesСоздать счёт
2POST/invoices/qrСоздать QR-счёт
3GET/invoicesСписок счетов
4GET/invoices/{id}Просмотр счёта
5POST/invoices/{id}/cancelОтменить счёт
6POST/invoices/status/checkПроверить статусы счетов
Other
7POST/clients/checkПроверить номер клиента в Kaspi
Возвраты (Refunds)
8POST/invoices/{id}/refundВозврат по счёту
9GET/invoices/{id}/refundsСписок возвратов по счёту
10GET/refundsСписок возвратов
Каталог (Catalog)
11GET/catalog/unitsСписок единиц измерения
12GET/catalogСписок товаров каталога
13POST/catalog/upload-imageЗагрузить изображение для каталога
14POST/catalogСоздать товар каталога
15PATCH/catalog/{id}Обновить товар каталога
16DELETE/catalog/{id}Удалить товар каталога
Подписки (Subscriptions)
17POST/subscriptionsСоздать подписку
18GET/subscriptionsСписок подписок
19GET/subscriptions/{id}Просмотр подписки
20PUT/subscriptions/{id}Обновить подписку
21POST/subscriptions/{id}/pauseПриостановить подписку
22POST/subscriptions/{id}/resumeВозобновить подписку
23POST/subscriptions/{id}/cancelОтменить подписку
24GET/subscriptions/{id}/invoicesИстория платежей подписки

Health Check


Счета (Invoices)

GET /invoices

Возвращает пагинированный список счетов с возможностью фильтрации.

Параметры запроса (query)

ПолеТипОбяз.Описание
statusstring[]Фильтр по статусу.
date_fromstringДата начала (Y-m-d).
date_tostringДата окончания (Y-m-d).
sort_bystringСортировка: id, amount, client_name, status, created_at, paid_at.
sort_orderstringПорядок: asc, desc.
per_pageintegerКол-во на страницу (1-100).

Поля ответа

ПолеТипОбяз.NullableОписание
current_pageintegerНомер текущей страницы.
dataobject[]Массив записей результата.
data.idintegerID записи.
data.amountstringСумма в тенге.
data.descriptionstringОписание.
data.external_order_idstringВнешний ID заказа.
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.kaspi_invoice_idstringID счёта в системе Kaspi.
data.phonestringНомер телефона клиента.
data.client_namestringИмя клиента.
data.client_commentstringдаКомментарий клиента (может быть null).
data.is_sandboxbooleanПризнак тестового (sandbox) объекта.
data.is_recurringbooleanПризнак счёта по подписке.
data.subtotalstringдаСумма до скидки (может быть null).
data.discount_sumstringдаСумма скидки (может быть null).
data.discount_percentagestringдаПроцент скидки (может быть null).
data.total_refundedstringСуммарно возвращено по счёту.
data.is_fully_refundedbooleanПризнак полного возврата.
data.error_messagestringдаТекст ошибки (null если ошибок нет).
data.paid_atstringДата и время оплаты (null если не оплачено).
data.created_atstringДата и время создания.
data.itemsany[]Позиции (товары) объекта.
totalintegerОбщее количество записей.

POST /invoices

Создаёт новый счёт для оплаты через Kaspi Pay. Для организаций с каталогом используйте `cart_items` вместо `amount`.

Параметры запроса

ПолеТипОбяз.Описание
phone_numberstringДаНомер телефона. Формат: 8XXXXXXXXXX.
descriptionstringОписание счёта.
external_order_idstringВнешний ID заказа.
amountnumberСумма (обязательна без cart_items).
cart_itemsobject[]Товары корзины (для организаций с каталогом).
cart_items.catalog_item_idintegerДаID товара из каталога.
cart_items.countintegerДаКоличество.
cart_items.pricenumberПереопределённая цена за единицу. Если не указана — используется selling_price из каталога.
discount_percentagenumberСкидка на весь чек, 1-99% (только с cart_items).

Поля ответа

ПолеТипОбяз.NullableОписание
idintegerID записи.
amountstringСумма в тенге.
statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
paid_atstringдаДата и время оплаты (null если не оплачено).
phonestringНомер телефона клиента.
created_atstringДата и время создания.

GET /invoices/{id}

Возвращает детальную информацию о счёте, включая товары.

Поля ответа

ПолеТипОбяз.NullableОписание
idintegerID записи.
amountstringСумма в тенге.
descriptionstringОписание.
external_order_idstringВнешний ID заказа.
statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
kaspi_invoice_idstringID счёта в системе Kaspi.
phonestringНомер телефона клиента.
client_namestringИмя клиента.
client_commentstringдаКомментарий клиента (может быть null).
is_sandboxbooleanПризнак тестового (sandbox) объекта.
is_recurringbooleanПризнак счёта по подписке.
subtotalstringдаСумма до скидки (может быть null).
discount_sumstringдаСумма скидки (может быть null).
discount_percentagestringдаПроцент скидки (может быть null).
total_refundedstringСуммарно возвращено по счёту.
is_fully_refundedbooleanПризнак полного возврата.
error_messagestringдаТекст ошибки (null если ошибок нет).
paid_atstringДата и время оплаты (null если не оплачено).
created_atstringДата и время создания.
itemsany[]Позиции (товары) объекта.

POST /invoices/{id}/cancel

Отменяет счёт в статусе pending или processing. Для production счетов отмена выполняется асинхронно (статус 202).

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
invoiceobjectСвязанный счёт.
invoice.idintegerID записи.
invoice.amountstringСумма в тенге.
invoice.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
invoice.phonestringНомер телефона клиента.
invoice.created_atstringДата и время создания.

POST /invoices/{id}/refund

Создаёт возврат по оплаченному счёту. Поддерживает полный и частичный возврат, а также поэлементный возврат через `return_items`.

Параметры запроса

ПолеТипОбяз.Описание
amountnumberСумма возврата (без return_items; по умолчанию — вся доступная сумма).
reasonstringПричина возврата.
return_itemsobject[]Товары для возврата (вместо amount).
return_items.catalog_item_idintegerДаID товара из каталога.
return_items.countintegerДаКоличество для возврата.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
refundobjectОбъект возврата.
refund.idintegerID записи.
refund.invoice_idintegerID связанного счёта.
refund.user_idintegerID пользователя, инициировавшего операцию.
refund.api_key_idintegerID API-ключа.
refund.amountstringСумма в тенге.
refund.kaspi_refund_idstringдаID возврата в системе Kaspi (null до обработки).
refund.kaspi_statusstringдаСтатус возврата в системе Kaspi (null до обработки).
refund.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
refund.reasonstringПричина возврата.
refund.initiated_bystringИсточник инициации: api_key или dashboard.
refund.error_messagestringдаТекст ошибки (null если ошибок нет).
refund.created_atstringДата и время создания.
invoiceobjectСвязанный счёт.
invoice.idintegerID записи.
invoice.amountstringСумма в тенге.
invoice.total_refundedstringСуммарно возвращено по счёту.
invoice.available_for_refundintegerДоступная для возврата сумма.
invoice.pending_refund_amountintegerСумма возвратов в обработке.

GET /invoices/{id}/refunds

Возвращает все возвраты по конкретному счёту.

Поля ответа

ПолеТипОбяз.NullableОписание
invoiceobjectСвязанный счёт.
invoice.idintegerID записи.
invoice.amountstringСумма в тенге.
invoice.total_refundedstringСуммарно возвращено по счёту.
invoice.available_for_refundintegerДоступная для возврата сумма.
invoice.is_fully_refundedbooleanПризнак полного возврата.
refundsobject[]Список возвратов.
refunds.idintegerID записи.
refunds.invoice_idintegerID связанного счёта.
refunds.user_idintegerID пользователя, инициировавшего операцию.
refunds.api_key_idintegerID API-ключа.
refunds.amountstringСумма в тенге.
refunds.kaspi_refund_idstringдаID возврата в системе Kaspi (null до обработки).
refunds.kaspi_statusstringдаСтатус возврата в системе Kaspi (null до обработки).
refunds.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
refunds.reasonstringПричина возврата.
refunds.initiated_bystringИсточник инициации: api_key или dashboard.
refunds.error_messagestringдаТекст ошибки (null если ошибок нет).
refunds.created_atstringДата и время создания.
refunds.itemsany[]Позиции (товары) объекта.
totalintegerОбщее количество записей.

POST /invoices/status/check

Диспатчит задачи проверки статусов для указанных счетов через Kaspi API.

Параметры запроса

ПолеТипОбяз.Описание
invoice_idsinteger[]ДаМассив ID счетов.

Поля ответа

ПолеТипОбяз.NullableОписание
invoicesobject[]Список счетов с актуальными статусами.
invoices.idintegerID записи.
invoices.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
invoices.kaspi_invoice_idstringID счёта в системе Kaspi.
invoices.amountstringСумма в тенге.
invoices.error_messagestringдаТекст ошибки (null если ошибок нет).
invoices.updated_atstringДата и время последнего обновления.

Возвраты (Refunds)

GET /refunds

Возвращает список возвратов организации с фильтрацией и пагинацией.

Параметры запроса (query)

ПолеТипОбяз.Описание
status[]string[]Фильтр по статусам. Допустимые значения: `pending`, `processing`, `completed`, `failed`.
invoice_idintegerФильтр по ID счёта.
date_fromstringНачало периода в формате `Y-m-d`.
date_tostringКонец периода в формате `Y-m-d`.
per_pageintegerКоличество записей на страницу (1-100).

Параметры запроса

ПолеТипОбяз.Описание
statusstring[]
invoice_idintegerThe <code>id</code> of an existing record in the invoices table.
date_fromstringMust be a valid date. Must be a valid date in the format <code>Y-m-d</code>.
date_tostringMust be a valid date. Must be a valid date in the format <code>Y-m-d</code>. Must be a date after or equal to <code>date_from</code>.
per_pageintegerMust be at least 1. Must not be greater than 100.

Поля ответа

ПолеТипОбяз.NullableОписание
current_pageintegerНомер текущей страницы.
dataobject[]Массив записей результата.
data.idintegerID записи.
data.invoice_idintegerID связанного счёта.
data.user_idintegerID пользователя, инициировавшего операцию.
data.api_key_idintegerID API-ключа.
data.amountstringСумма в тенге.
data.kaspi_refund_idstringдаID возврата в системе Kaspi (null до обработки).
data.kaspi_statusstringдаСтатус возврата в системе Kaspi (null до обработки).
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.reasonstringПричина возврата.
data.initiated_bystringИсточник инициации: api_key или dashboard.
data.error_messagestringдаТекст ошибки (null если ошибок нет).
data.created_atstringДата и время создания.
data.invoiceobjectСвязанный счёт.
data.itemsany[]Позиции (товары) объекта.
totalintegerОбщее количество записей.

Каталог (Catalog)

GET /catalog/units

Возвращает список доступных единиц измерения для товаров каталога (шт, кг, л и т.д.).

Поля ответа

ПолеТипОбяз.NullableОписание
dataobject[]Массив записей результата.
data.idintegerID записи.
data.namestringНазвание.
data.name_kazstringНазвание на казахском языке.

GET /catalog

Возвращает пагинированный список товаров каталога организации. Поддерживает поиск и фильтрацию.

Параметры запроса (query)

ПолеТипОбяз.Описание
barcodestringФильтр по штрихкоду.
first_charstringФильтр по первой букве названия.
per_pageintegerКол-во на страницу (1-200, по умолчанию 50).

Поля ответа

ПолеТипОбяз.NullableОписание
dataobject[]Массив записей результата.
data.idintegerID записи.
data.kaspi_item_idstringдаID товара в системе Kaspi (null до синхронизации).
data.namestringНазвание.
data.unit_idintegerID единицы измерения.
data.selling_pricestringЦена продажи.
data.date_addedstringдаДата добавления (может быть null).
data.image_urlstringдаURL изображения товара (может быть null).
data.first_charstringПервая буква названия (для группировки).
data.nds_percentagestringдаПроцент НДС (может быть null).
data.barcodestringШтрихкод товара.
data.ntinstringдаКод NTIN/маркировки (может быть null).
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.error_messagestringдаТекст ошибки (null если ошибок нет).
data.created_atstringДата и время создания.
data.synced_atstringДата последней синхронизации с Kaspi.
metaobjectМетаданные пагинации.

POST /catalog

Создаёт один или несколько товаров в каталоге организации. Товары сохраняются локально со статусом pending и отправляются в Kaspi API через очередь.

Параметры запроса

ПолеТипОбяз.Описание
itemsobject[]ДаМассив товаров (макс. 50).
items.namestringДаНазвание товара.
items.selling_pricenumberДаЦена продажи.
items.unit_idintegerДаID единицы измерения.
items.image_idstringUUID изображения, полученный из upload-image.
items.barcodestringШтрихкод товара.

Поля ответа

ПолеТипОбяз.NullableОписание
dataobject[]Массив записей результата.
data.idintegerID записи.
data.kaspi_item_idstringдаID товара в системе Kaspi (null до синхронизации).
data.namestringНазвание.
data.unit_idintegerID единицы измерения.
data.selling_pricestringЦена продажи.
data.date_addedstringдаДата добавления (может быть null).
data.image_urlstringдаURL изображения товара (может быть null).
data.first_charstringПервая буква названия (для группировки).
data.nds_percentagestringдаПроцент НДС (может быть null).
data.barcodestringШтрихкод товара.
data.ntinstringдаКод NTIN/маркировки (может быть null).
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.error_messagestringдаТекст ошибки (null если ошибок нет).
data.created_atstringДата и время создания.
data.synced_atstringДата последней синхронизации с Kaspi.

POST /catalog/upload-image

Загружает и оптимизирует изображение товара. Использует MD5 дедупликацию — повторная загрузка того же изображения вернёт существующий image_id.

Параметры запроса

ПолеТипОбяз.Описание
imagestringДаИзображение товара (jpeg/png/webp, макс. 2 МБ).

Поля ответа

ПолеТипОбяз.NullableОписание
image_idstringUUID изображения.

PATCH /catalog/{id}

Обновляет данные товара каталога. Локальные поля обновляются сразу, изменения в Kaspi API отправляются через очередь.

Параметры запроса

ПолеТипОбяз.Описание
namestringНазвание товара.
selling_pricenumberЦена продажи.
unit_idintegerID единицы измерения.
image_idstringUUID нового изображения.
is_image_deletedbooleanУдалить текущее изображение.
barcodestringШтрихкод товара.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
catalog_item_idintegerID товара каталога.

DELETE /catalog/{id}

Помечает товар как удаляемый и отправляет запрос на удаление в Kaspi API через очередь.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
catalog_item_idintegerID товара каталога.

Подписки (Subscriptions)

GET /subscriptions

Возвращает пагинированный список подписок с возможностью фильтрации.

Параметры запроса (query)

ПолеТипОбяз.Описание
statusstringФильтр по статусу (active, paused, cancelled, expired).
external_subscriber_idstringФильтр по внешнему ID подписчика.
phone_numberstringФильтр по номеру телефона (8XXXXXXXXXX).
per_pageintegerКол-во на страницу (по умолчанию 20).

Поля ответа

ПолеТипОбяз.NullableОписание
current_pageintegerНомер текущей страницы.
dataobject[]Массив записей результата.
data.idintegerID записи.
data.subscriber_namestringИмя подписчика.
data.phone_numberstringНомер телефона подписчика.
data.external_subscriber_idstringВнешний ID подписчика.
data.amountstringСумма в тенге.
data.cart_itemsstringдаКорзина товаров подписки (null без каталога).
data.descriptionstringОписание.
data.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
data.billing_period_labelstringЛокализованное название периода биллинга.
data.billing_dayintegerДень биллинга (1-28).
data.billing_day_labelstringЛокализованное обозначение дня биллинга.
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.status_labelstringЛокализованное название статуса.
data.status_colorstringЦвет статуса для UI.
data.started_atstringДата начала подписки.
data.next_billing_atstringДата следующего списания (null если нет).
data.next_billing_in_daysintegerКоличество дней до следующего списания.
data.next_billing_labelstringТекстовое обозначение следующего списания.
data.paused_atstringдаДата приостановки (null если активна).
data.cancelled_atstringдаДата отмены (null если не отменена).
data.failed_attemptsintegerКоличество неудачных попыток списания.
data.max_retry_attemptsintegerМакс. число повторных попыток.
data.retry_interval_hoursintegerИнтервал между повторами в часах.
data.grace_period_daysintegerЛьготный период в днях.
data.in_grace_periodbooleanПризнак нахождения в льготном периоде.
data.is_sandboxbooleanПризнак тестового (sandbox) объекта.
data.metadatastringдаПроизвольные метаданные.
data.created_atstringДата и время создания.
data.updated_atstringДата и время последнего обновления.
totalintegerОбщее количество записей.

POST /subscriptions

Создаёт новую рекуррентную подписку. Первый счёт выставляется автоматически.

Параметры запроса

ПолеТипОбяз.Описание
phone_numberstringДаНомер телефона подписчика в формате 8XXXXXXXXXX.
billing_periodstringДаПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
billing_dayintegerДень биллинга (1-28).
descriptionstringОписание подписки.
subscriber_namestringИмя подписчика.
external_subscriber_idstringВнешний ID подписчика в вашей системе.
started_atstringДата начала (Y-m-d). По умолчанию — сегодня.
max_retry_attemptsintegerМакс. кол-во повторных попыток при неудаче (1-10).
retry_interval_hoursintegerИнтервал между повторами в часах (1-168).
grace_period_daysintegerЛьготный период в днях (1-30).
metadataobjectПроизвольные метаданные.
bill_immediatelybooleanВыставить первый счёт сразу при создании.
amountnumberСумма списания в тенге (100-1000000). Обязательна для организаций без каталога.
cart_itemsobject[]Корзина товаров (только для каталожных организаций).
cart_items.catalog_item_idintegerДаID товара из каталога.
cart_items.countintegerДаКоличество.
cart_items.pricenumberПереопределённая цена за единицу. Если не указана — используется selling_price из каталога.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringДата следующего списания (null если нет).
subscription.next_billing_in_daysintegerКоличество дней до следующего списания.
subscription.next_billing_labelstringТекстовое обозначение следующего списания.
subscription.paused_atstringдаДата приостановки (null если активна).
subscription.cancelled_atstringдаДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadataobjectПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.

GET /subscriptions/{id}

Возвращает детальную информацию о подписке, включая статистику и последний платёж.

Поля ответа

ПолеТипОбяз.NullableОписание
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringДата следующего списания (null если нет).
subscription.next_billing_in_daysintegerКоличество дней до следующего списания.
subscription.next_billing_labelstringТекстовое обозначение следующего списания.
subscription.paused_atstringдаДата приостановки (null если активна).
subscription.cancelled_atstringдаДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadatastringдаПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.
subscription.last_paymentobjectДанные последнего платежа.
subscription.statsobjectСтатистика по подписке.

PUT /subscriptions/{id}

Обновляет параметры существующей подписки. Все поля опциональны.

Параметры запроса

ПолеТипОбяз.Описание
amountnumberСумма списания в тенге (100-1000000).
billing_dayintegerДень биллинга (1-28).
descriptionstringОписание подписки.
subscriber_namestringИмя подписчика.
external_subscriber_idstringВнешний ID подписчика.
max_retry_attemptsintegerМакс. кол-во повторных попыток (1-10).
retry_interval_hoursintegerИнтервал между повторами в часах (1-168).
grace_period_daysintegerЛьготный период в днях (1-30).
metadataobjectПроизвольные метаданные.
cart_itemsobject[]Корзина товаров (только для каталожных организаций).
cart_items.catalog_item_idintegerДаID товара из каталога.
cart_items.countintegerДаКоличество.
cart_items.pricenumberПереопределённая цена за единицу. Если не указана — используется selling_price из каталога.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringДата следующего списания (null если нет).
subscription.next_billing_in_daysintegerКоличество дней до следующего списания.
subscription.next_billing_labelstringТекстовое обозначение следующего списания.
subscription.paused_atstringдаДата приостановки (null если активна).
subscription.cancelled_atstringдаДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadataobjectПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.

POST /subscriptions/{id}/pause

Приостанавливает активную подписку. Новые счета не будут выставляться до возобновления.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringдаДата следующего списания (null если нет).
subscription.next_billing_in_daysstringдаКоличество дней до следующего списания.
subscription.next_billing_labelstringдаТекстовое обозначение следующего списания.
subscription.paused_atstringДата приостановки (null если активна).
subscription.cancelled_atstringдаДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadatastringдаПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.

POST /subscriptions/{id}/resume

Возобновляет приостановленную подписку. Следующий биллинг будет рассчитан автоматически.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringДата следующего списания (null если нет).
subscription.next_billing_in_daysintegerКоличество дней до следующего списания.
subscription.next_billing_labelstringТекстовое обозначение следующего списания.
subscription.paused_atstringдаДата приостановки (null если активна).
subscription.cancelled_atstringдаДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadatastringдаПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.

POST /subscriptions/{id}/cancel

Безвозвратно отменяет подписку. Новые счета больше не будут выставляться.

Поля ответа

ПолеТипОбяз.NullableОписание
messagestringТекстовое сообщение о результате операции.
subscriptionobjectОбъект подписки.
subscription.idintegerID записи.
subscription.subscriber_namestringИмя подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.external_subscriber_idstringВнешний ID подписчика.
subscription.amountstringСумма в тенге.
subscription.cart_itemsstringдаКорзина товаров подписки (null без каталога).
subscription.descriptionstringОписание.
subscription.billing_periodstringПериод биллинга: daily, weekly, biweekly, monthly, quarterly, yearly.
subscription.billing_period_labelstringЛокализованное название периода биллинга.
subscription.billing_dayintegerДень биллинга (1-28).
subscription.billing_day_labelstringЛокализованное обозначение дня биллинга.
subscription.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
subscription.status_labelstringЛокализованное название статуса.
subscription.status_colorstringЦвет статуса для UI.
subscription.started_atstringДата начала подписки.
subscription.next_billing_atstringдаДата следующего списания (null если нет).
subscription.next_billing_in_daysstringдаКоличество дней до следующего списания.
subscription.next_billing_labelstringдаТекстовое обозначение следующего списания.
subscription.paused_atstringдаДата приостановки (null если активна).
subscription.cancelled_atstringДата отмены (null если не отменена).
subscription.failed_attemptsintegerКоличество неудачных попыток списания.
subscription.max_retry_attemptsintegerМакс. число повторных попыток.
subscription.retry_interval_hoursintegerИнтервал между повторами в часах.
subscription.grace_period_daysintegerЛьготный период в днях.
subscription.in_grace_periodbooleanПризнак нахождения в льготном периоде.
subscription.is_sandboxbooleanПризнак тестового (sandbox) объекта.
subscription.metadatastringдаПроизвольные метаданные.
subscription.created_atstringДата и время создания.
subscription.updated_atstringДата и время последнего обновления.

GET /subscriptions/{id}/invoices

Возвращает пагинированный список всех платежей (счетов) по подписке.

Параметры запроса (query)

ПолеТипОбяз.Описание
per_pageintegerКол-во на страницу (по умолчанию 20).

Поля ответа

ПолеТипОбяз.NullableОписание
dataobject[]Массив записей результата.
data.idintegerID записи.
data.invoice_idintegerID связанного счёта.
data.billing_period_startstringНачало расчётного периода.
data.billing_period_endstringКонец расчётного периода.
data.billing_period_labelstringЛокализованное название периода биллинга.
data.amountstringСумма в тенге.
data.attempt_numberintegerНомер попытки списания.
data.statusstringСтатус. Для счёта: pending, processing, paid, cancelled, expired, partially_refunded, refunded, error. Для возврата: pending, processing, completed, failed. Для подписки: active, paused, cancelled, completed, expired. Для товара каталога: pending, active, error.
data.status_labelstringЛокализованное название статуса.
data.status_colorstringЦвет статуса для UI.
data.paid_atstringДата и время оплаты (null если не оплачено).
data.failure_reasonstringдаПричина неудачи (null при успехе).
data.invoiceobjectСвязанный счёт.
data.created_atstringДата и время создания.
metaobjectМетаданные пагинации.
meta.current_pageintegerНомер текущей страницы.
meta.totalintegerОбщее количество записей.
meta.per_pageintegerКоличество записей на странице.

Webhooks

Webhooks настраиваются через личный кабинет ApiPay.kz (Настройки > Подключение). При создании webhook вы получите secret для верификации подписи (HMAC-SHA256).

События

Примеры payload

invoice.status_changed

{
  "event": "invoice.status_changed",
  "invoice": {
    "id": 42,
    "external_order_id": "order_123",
    "amount": "15000.00",
    "subtotal": "16500.00",
    "discount_sum": "1500.00",
    "discount_percentage": "10",
    "status": "paid",
    "description": "Оплата заказа",
    "kaspi_invoice_id": "13234689513",
    "client_name": "Иван Иванов",
    "client_phone": "87071234567",
    "is_sandbox": false,
    "kaspi_source_type": "GOLD",
    "kaspi_sale_type": "Remote",
    "paid_at": "2026-02-12T14:35:00+05:00"
  },
  "source": "My API Key",
  "timestamp": "2026-02-12T14:35:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — invoice.status_changed.
invoice.idintegerВнутренний ID счёта в ApiPay.
invoice.external_order_idstringдаВаш внешний идентификатор заказа, переданный при создании счёта.
invoice.amountstringСумма счёта.
invoice.statusstringСтатус счёта: pending / paid / cancelled / expired / refunded / partially_refunded.
invoice.kaspi_invoice_idstringдаID счёта в Kaspi. null до оплаты.
invoice.client_phonestringНомер телефона клиента.
invoice.kaspi_source_typestringдаИсточник средств клиента: GOLD — дебетовая карта Kaspi, RED — кредитная карта Kaspi, LOAN — рассрочка/кредит, BUSINESSACCOUNT — бизнес-счёт, BANKINTEGRATIONACCOUNT — привязанный внешний банковский счёт. Обычно присутствует при status=paid, но гейтится по наличию значения, а не строго по статусу: поле приходит, когда Kaspi вернул значение (например, счёт, уже получивший его, может пробросить поле и в статусах cancelled/expired), и отсутствует/null иначе. Может отсутствовать для старых счетов; список может расширяться — обрабатывайте неизвестные значения как «прочее».
invoice.kaspi_sale_typestringдаСпособ приёма счёта: Remote — push на номер, QR — QR-код, Restaurant — ресторанный счёт, Static — статичный QR. Обычно присутствует при status=paid, но гейтится по наличию значения, а не строго по статусу: поле приходит, когда Kaspi вернул значение (например, счёт, уже получивший его, может пробросить поле и в статусах cancelled/expired), и отсутствует/null иначе. Может отсутствовать для старых счетов; список может расширяться — обрабатывайте неизвестные значения как «прочее».
invoice.paid_atstringдаВремя оплаты счёта (ISO 8601). null до оплаты.
sourcestringдаНазвание API-ключа, через который создан счёт.
timestampstringВремя отправки события (ISO 8601).

invoice.refunded

{
  "event": "invoice.refunded",
  "refund": {
    "id": 5,
    "amount": "2000.00",
    "status": "completed",
    "reason": "Возврат товара",
    "created_at": "2026-02-12T10:00:00+05:00"
  },
  "invoice": {
    "id": 42,
    "external_order_id": "order_123",
    "amount": "5000.00",
    "subtotal": "5500.00",
    "discount_sum": "500.00",
    "total_refunded": "2000.00",
    "available_for_refund": "3000.00",
    "is_fully_refunded": false,
    "is_sandbox": false,
    "status": "paid",
    "kaspi_invoice_id": "13234689513"
  },
  "source": "My API Key",
  "timestamp": "2026-02-12T10:00:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — invoice.refunded.
refund.idintegerID возврата.
refund.amountstringСумма возврата.
refund.statusstringСтатус возврата (например, completed).
refund.reasonstringдаПричина возврата.
refund.created_atstringВремя создания возврата (ISO 8601).
invoice.idintegerВнутренний ID счёта в ApiPay.
invoice.external_order_idstringдаВаш внешний идентификатор заказа.
invoice.amountstringСумма счёта.
invoice.subtotalstringСумма счёта до применения скидки.
invoice.discount_sumstringСумма скидки по счёту.
invoice.total_refundedstringСуммарно возвращено по счёту на текущий момент.
invoice.available_for_refundstringСумма, ещё доступная для возврата.
invoice.is_fully_refundedbooleantrue, если счёт возвращён полностью.
invoice.is_sandboxbooleanСчёт создан в sandbox-режиме.
invoice.statusstringСтатус счёта на момент возврата.
invoice.kaspi_invoice_idstringдаID счёта в Kaspi.
sourcestringдаНазвание API-ключа.
timestampstringВремя отправки события (ISO 8601).

subscription.payment_succeeded

{
  "event": "subscription.payment_succeeded",
  "subscription": {
    "id": 10,
    "external_subscriber_id": "CLIENT-001",
    "phone_number": "87071234567",
    "subscriber_name": "Иван Иванов",
    "amount": "5000.00",
    "billing_period": "monthly",
    "status": "active",
    "next_billing_at": "2026-03-01T00:00:00+05:00",
    "failed_attempts": 0,
    "in_grace_period": false,
    "is_sandbox": false
  },
  "invoice_id": 200,
  "amount": "5000.00",
  "paid_at": "2026-02-01T12:00:00+05:00",
  "source": "My API Key",
  "timestamp": "2026-02-01T12:00:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — subscription.payment_succeeded.
subscription.idintegerID подписки.
subscription.external_subscriber_idstringдаВаш внешний идентификатор подписчика.
subscription.phone_numberstringНомер телефона подписчика.
subscription.subscriber_namestringдаИмя подписчика.
subscription.amountstringСумма платежа по подписке.
subscription.billing_periodstringПериод списания (например, monthly).
subscription.statusstringСтатус подписки (например, active).
subscription.next_billing_atstringдаДата следующего списания (ISO 8601).
subscription.failed_attemptsintegerКоличество подряд неуспешных попыток списания.
subscription.in_grace_periodbooleanНаходится ли подписка в льготном периоде.
subscription.is_sandboxbooleanПодписка создана в sandbox-режиме.
invoice_idintegerID счёта, по которому прошёл платёж.
amountstringСумма успешного платежа.
paid_atstringВремя оплаты (ISO 8601).
sourcestringдаНазвание API-ключа.
timestampstringВремя отправки события (ISO 8601).

subscription.payment_failed

{
  "event": "subscription.payment_failed",
  "subscription": {
    "id": 10,
    "phone_number": "87071234567",
    "amount": "5000.00",
    "billing_period": "monthly",
    "status": "active",
    "failed_attempts": 2,
    "in_grace_period": false,
    "is_sandbox": false
  },
  "invoice_id": 201,
  "amount": "5000.00",
  "reason": "Invoice expired",
  "attempt_number": 2,
  "source": "My API Key",
  "timestamp": "2026-02-02T12:00:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — subscription.payment_failed.
subscription.idintegerID подписки.
subscription.phone_numberstringНомер телефона подписчика.
subscription.amountstringСумма платежа по подписке.
subscription.billing_periodstringПериод списания (например, monthly).
subscription.statusstringСтатус подписки (например, active).
subscription.failed_attemptsintegerКоличество подряд неуспешных попыток списания.
subscription.in_grace_periodbooleanНаходится ли подписка в льготном периоде.
subscription.is_sandboxbooleanПодписка создана в sandbox-режиме.
invoice_idintegerID счёта, по которому не прошёл платёж.
amountstringСумма неуспешного платежа.
reasonstringдаПричина неуспеха (например, Invoice expired).
attempt_numberintegerНомер текущей попытки списания.
sourcestringдаНазвание API-ключа.
timestampstringВремя отправки события (ISO 8601).

subscription.grace_period_started

{
  "event": "subscription.grace_period_started",
  "subscription": {
    "id": 10,
    "phone_number": "87071234567",
    "amount": "5000.00",
    "status": "active",
    "failed_attempts": 3,
    "in_grace_period": true,
    "is_sandbox": false
  },
  "grace_period_days": 3,
  "expires_at": "2026-02-05T12:00:00+05:00",
  "source": "My API Key",
  "timestamp": "2026-02-02T12:00:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — subscription.grace_period_started.
subscription.idintegerID подписки.
subscription.phone_numberstringНомер телефона подписчика.
subscription.amountstringСумма платежа по подписке.
subscription.statusstringСтатус подписки (например, active).
subscription.failed_attemptsintegerКоличество подряд неуспешных попыток списания.
subscription.in_grace_periodbooleanНаходится ли подписка в льготном периоде (здесь true).
subscription.is_sandboxbooleanПодписка создана в sandbox-режиме.
grace_period_daysintegerДлительность льготного периода в днях.
expires_atstringКогда истекает льготный период (ISO 8601).
sourcestringдаНазвание API-ключа.
timestampstringВремя отправки события (ISO 8601).

subscription.expired

{
  "event": "subscription.expired",
  "subscription": {
    "id": 10,
    "phone_number": "87071234567",
    "amount": "5000.00",
    "status": "expired",
    "next_billing_at": null,
    "failed_attempts": 3,
    "in_grace_period": false,
    "is_sandbox": false
  },
  "source": "My API Key",
  "timestamp": "2026-02-05T12:00:01+05:00"
}
ПолеТипNullableОписание
eventstringТип события — subscription.expired.
subscription.idintegerID подписки.
subscription.phone_numberstringНомер телефона подписчика.
subscription.amountstringСумма платежа по подписке.
subscription.statusstringСтатус подписки (здесь expired).
subscription.next_billing_atstringдаДата следующего списания (null для истёкшей подписки).
subscription.failed_attemptsintegerКоличество подряд неуспешных попыток списания.
subscription.in_grace_periodbooleanНаходится ли подписка в льготном периоде.
subscription.is_sandboxbooleanПодписка создана в sandbox-режиме.
sourcestringдаНазвание API-ключа.
timestampstringВремя отправки события (ISO 8601).

Retry Policy

Верификация подписи

Header: X-Webhook-Signature: sha256=<hex>

python

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

# Usage:
# signature = request.headers.get('X-Webhook-Signature')
# is_valid = verify_webhook(request.body, signature, webhook_secret)

php

javascript

import crypto from 'crypto'

function verifyWebhook(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex')
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  )
}

// Usage:
// const signature = req.headers['x-webhook-signature']
// const isValid = verifyWebhook(req.rawBody, signature, webhookSecret)

Примеры кода

Создание счёта

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/invoices', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 10000,
    phone_number: '87001234567',
    description: 'Payment for order #123'
  })
})

const data = await response.json()
console.log('Invoice created:', data.id)

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'amount': 10000,
        'phone_number': '87001234567',
        'description': 'Payment for order #123'
    }
)

data = response.json()
print(f"Invoice created: {data['id']}")

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 10000,
        'phone_number' => '87001234567',
        'description' => 'Payment for order #123'
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
echo "Invoice created: " . $response['id'];
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/invoices \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "phone_number": "87001234567",
    "description": "Payment for order #123"
  }'

Создание счёта с корзиной

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/invoices', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    phone_number: '87001234567',
    description: 'Cart order',
    cart_items: [
      { catalog_item_id: 1, count: 2, price: 4500.00 },
      { catalog_item_id: 5, count: 3 }
    ],
    discount_percentage: 10
  })
})
// Response includes subtotal, discount_sum, discount_percentage

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'phone_number': '87001234567',
        'description': 'Cart order',
        'cart_items': [
            {'catalog_item_id': 1, 'count': 2, 'price': 4500.00},
            {'catalog_item_id': 5, 'count': 3}
        ],
        'discount_percentage': 10
    }
)
data = response.json()

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'phone_number' => '87001234567',
        'description' => 'Cart order',
        'cart_items' => [
            ['catalog_item_id' => 1, 'count' => 2, 'price' => 4500.00],
            ['catalog_item_id' => 5, 'count' => 3]
        ],
        'discount_percentage' => 10
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/invoices \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "87001234567",
    "description": "Cart order",
    "cart_items": [
      { "catalog_item_id": 1, "count": 2, "price": 4500.00 },
      { "catalog_item_id": 5, "count": 3 }
    ],
    "discount_percentage": 10
  }'

Создание подписки

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/subscriptions', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    phone_number: '87001234567',
    amount: 5000,
    billing_period: 'monthly',
    description: 'Monthly subscription'
  })
})
const data = await response.json()
console.log('Subscription:', data.subscription.id)

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/subscriptions',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'phone_number': '87001234567',
        'amount': 5000,
        'billing_period': 'monthly',
        'description': 'Monthly subscription'
    }
)
data = response.json()
print(f"Subscription: {data['subscription']['id']}")

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'phone_number' => '87001234567',
        'amount' => 5000,
        'billing_period' => 'monthly',
        'description' => 'Monthly subscription'
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
echo "Subscription: " . $response['subscription']['id'];
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/subscriptions \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "87001234567",
    "amount": 5000,
    "billing_period": "monthly",
    "description": "Monthly subscription"
  }'

Создание подписки с корзиной

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/subscriptions', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    phone_number: '87001234567',
    billing_period: 'monthly',
    description: 'Monthly cart subscription',
    cart_items: [
      { catalog_item_id: 1, count: 2 },
      { catalog_item_id: 5, count: 1 }
    ]
  })
})
const data = await response.json()

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/subscriptions',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'phone_number': '87001234567',
        'billing_period': 'monthly',
        'description': 'Monthly cart subscription',
        'cart_items': [
            {'catalog_item_id': 1, 'count': 2},
            {'catalog_item_id': 5, 'count': 1}
        ]
    }
)
data = response.json()

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'phone_number' => '87001234567',
        'billing_period' => 'monthly',
        'description' => 'Monthly cart subscription',
        'cart_items' => [
            ['catalog_item_id' => 1, 'count' => 2],
            ['catalog_item_id' => 5, 'count' => 1]
        ]
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/subscriptions \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "87001234567",
    "billing_period": "monthly",
    "description": "Monthly cart subscription",
    "cart_items": [
      { "catalog_item_id": 1, "count": 2 },
      { "catalog_item_id": 5, "count": 1 }
    ]
  }'

Загрузка изображения и создание товара

JavaScript / Node.js

// Step 1: Upload image
const formData = new FormData()
formData.append('image', imageFile)

const uploadRes = await fetch('https://bpapi.bazarbay.site/api/v1/catalog/upload-image', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY' },
  body: formData
})
const { image_id } = await uploadRes.json()

// Step 2: Create product with image
const productRes = await fetch('https://bpapi.bazarbay.site/api/v1/catalog', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    items: [{
      name: 'Coffee Latte',
      selling_price: 1800,
      unit_id: 1,
      image_id
    }]
  })
})

Python

import requests

# Step 1: Upload image
upload_res = requests.post(
    'https://bpapi.bazarbay.site/api/v1/catalog/upload-image',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    files={'image': open('product.jpg', 'rb')}
)
image_id = upload_res.json()['image_id']

# Step 2: Create product with image
product_res = requests.post(
    'https://bpapi.bazarbay.site/api/v1/catalog',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'items': [{
            'name': 'Coffee Latte',
            'selling_price': 1800,
            'unit_id': 1,
            'image_id': image_id
        }]
    }
)

PHP

 true,
    CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
    CURLOPT_POSTFIELDS => ['image' => $cfile],
    CURLOPT_RETURNTRANSFER => true
]);
$imageId = json_decode(curl_exec($ch), true)['image_id'];
curl_close($ch);

// Step 2: Create product with image
$ch = curl_init('https://bpapi.bazarbay.site/api/v1/catalog');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'items' => [[
            'name' => 'Coffee Latte',
            'selling_price' => 1800,
            'unit_id' => 1,
            'image_id' => $imageId
        ]]
    ]),
    CURLOPT_RETURNTRANSFER => true
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

cURL

# Step 1: Upload image
IMAGE_ID=$(curl -s -X POST https://bpapi.bazarbay.site/api/v1/catalog/upload-image \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "image=@product.jpg" | jq -r '.image_id')

# Step 2: Create product with image
curl -X POST https://bpapi.bazarbay.site/api/v1/catalog \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"items\": [{
      \"name\": \"Coffee Latte\",
      \"selling_price\": 1800,
      \"unit_id\": 1,
      \"image_id\": \"$IMAGE_ID\"
    }]
  }"

Возврат средств

JavaScript / Node.js

// Full refund
await fetch('https://bpapi.bazarbay.site/api/v1/invoices/42/refund', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ reason: 'Customer request' })
})

// Partial refund
await fetch('https://bpapi.bazarbay.site/api/v1/invoices/42/refund', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ amount: 5000, reason: 'Partial return' })
})

Python

import requests

# Full refund
requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices/42/refund',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={'reason': 'Customer request'}
)

# Partial refund
requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices/42/refund',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={'amount': 5000, 'reason': 'Partial return'}
)

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'reason' => 'Customer request'
    ]),
    CURLOPT_RETURNTRANSFER => true
]);
curl_exec($ch);
curl_close($ch);

// Partial refund
$ch = curl_init('https://bpapi.bazarbay.site/api/v1/invoices/42/refund');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 5000,
        'reason' => 'Partial return'
    ]),
    CURLOPT_RETURNTRANSFER => true
]);
curl_exec($ch);
curl_close($ch);

cURL

# Full refund
curl -X POST https://bpapi.bazarbay.site/api/v1/invoices/42/refund \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Customer request"}'

# Partial refund
curl -X POST https://bpapi.bazarbay.site/api/v1/invoices/42/refund \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 5000, "reason": "Partial return"}'

Создание QR-счёта

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/invoices/qr', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 5000,
    description: 'Заказ №123',
    external_order_id: 'order-123'
  })
})

const data = await response.json()
// Покажите QR на экране кассы
document.getElementById('qr').src = data.qr_image_url
// или используйте qr_token_url для своего рендеринга
console.log('QR expires at:', data.qr_expires_at)

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices/qr',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'amount': 5000,
        'description': 'Заказ №123',
        'external_order_id': 'order-123'
    }
)

data = response.json()
# Покажите QR на экране кассы: data['qr_image_url']
print(f"QR expires at: {data['qr_expires_at']}")

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 5000,
        'description' => 'Заказ №123',
        'external_order_id' => 'order-123'
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
// Покажите QR на экране кассы: $response['qr_image_url']
echo "QR expires at: " . $response['qr_expires_at'];
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/invoices/qr \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "description": "Заказ №123",
    "external_order_id": "order-123"
  }'

QR-счёт с корзиной

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/invoices/qr', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    description: 'Заказ №123',
    cart_items: [
      { catalog_item_id: 608400, count: 2, price: 1500 }
    ],
    discount_percentage: 10
  })
})

const data = await response.json()
// data.qr_image_url — готовый PNG, data.qr_token_url — Kaspi-ссылка

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/invoices/qr',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'description': 'Заказ №123',
        'cart_items': [
            {'catalog_item_id': 608400, 'count': 2, 'price': 1500}
        ],
        'discount_percentage': 10
    }
)
data = response.json()

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'description' => 'Заказ №123',
        'cart_items' => [
            ['catalog_item_id' => 608400, 'count' => 2, 'price' => 1500]
        ],
        'discount_percentage' => 10
    ]),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/invoices/qr \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Заказ №123",
    "cart_items": [
      { "catalog_item_id": 608400, "count": 2, "price": 1500 }
    ],
    "discount_percentage": 10
  }'

Проверка номера клиента

JavaScript / Node.js

const response = await fetch('https://bpapi.bazarbay.site/api/v1/clients/check', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ phone: '77001234567' })
})

const data = await response.json()
// { phone: '87001234567', has_kaspi: true, client_name: 'Иван И.' }
if (!data.has_kaspi) {
  // Клиент не зарегистрирован в Kaspi — попросите другой номер
}

Python

import requests

response = requests.post(
    'https://bpapi.bazarbay.site/api/v1/clients/check',
    headers={
        'X-API-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={'phone': '77001234567'}
)

data = response.json()
# {'phone': '87001234567', 'has_kaspi': True, 'client_name': 'Иван И.'}
if not data['has_kaspi']:
    pass  # Клиент не зарегистрирован в Kaspi

PHP

 true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: YOUR_API_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode(['phone' => '77001234567']),
    CURLOPT_RETURNTRANSFER => true
]);

$response = json_decode(curl_exec($ch), true);
// ['phone' => '87001234567', 'has_kaspi' => true, 'client_name' => 'Иван И.']
curl_close($ch);

cURL

curl -X POST https://bpapi.bazarbay.site/api/v1/clients/check \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "77001234567"}'

Коды ошибок

Ошибки приходят в нескольких формах — не путайте их между собой:

В колонке «Код» ниже значения сгруппированы по тому, где именно они появляются.

HTTP-статусы (общие для всех эндпоинтов)

КодОписание
400Bad Request — некорректный запрос или недопустимое состояние. Точная причина — в поле message или error
401Unauthorized — API-ключ отсутствует, неверен, истёк или не привязан к организации; либо аккаунт деактивирован
403Forbidden — организация заморожена (suspended) или не верифицирована для рабочего режима
404Not Found — ресурс не найден или принадлежит другой организации
422Validation Error — ошибка валидации полей; детали в объекте errors
429Too Many Requests — превышен общий лимит Public API (200 запросов/мин на API-ключ); смотрите заголовок Retry-After. Отдельно: POST /clients/check ограничен 60 запросами/мин и 10 000 запросами/сутки на API-ключ, а POST /invoices/qr — 60 QR/мин на организацию (на этом 429 заголовка Retry-After нет)
500Server Error — внутренняя ошибка сервера
502Bad Gateway — ошибка на стороне Kaspi API
503Service Unavailable — сессия Kaspi недействительна или истекла

Поле «error» при создании счёта (POST /invoices, /invoices/qr)

КодОписание
organization_required (400)Организация не подключена — создайте sandbox-организацию для тестов или подключите кассира Kaspi
Organization not found or not verified (400)Рабочий режим: организация не верифицирована. Дождитесь верификации или тестируйте в песочнице
kaspi_session_not_configured (400)Кассир Kaspi не подключён. Подключите его в кабинете (Настройки → Авторизация Kaspi) или через поддержку (WhatsApp +7 708 516 74 89)
kaspi_session_invalid (503)Сессия кассира Kaspi истекла или сброшена. Переподключите кассира — запросите новый SMS-код
connection_ambiguous (422)У организации несколько активных касс, основная не выбрана — передайте kaspi_connection_id
sandbox_invoice_limit (400)Достигнут лимит тестовых счетов (500 на организацию) — очистите песочницу в кабинете

Поле «error» только для QR-счёта (POST /invoices/qr)

КодОписание
qr_rate_limit (429)Слишком много QR-запросов для организации (лимит 60/мин) — подождите минуту. Заголовок Retry-After на этом 429 не возвращается (в отличие от общего лимита Public API 200/мин)
qr_render_failed (500)Не удалось сформировать изображение QR-кода — повторите запрос позже
kaspi_error (502)Kaspi API вернул ошибку при создании QR-токена — повторите позже

Поле «error» при отмене и возврате

КодОписание
Invoice cannot be cancelled (400)Отменить можно только счёт в статусе pending или processing
Invoice is not refundable (400)Возврат возможен только по оплаченному счёту, ещё не возвращённому полностью
Refund amount exceeds available amount (400)Сумма возврата больше доступной — смотрите available_for_refund в GET /invoices/{id}

Поле «error» при работе с подписками

КодОписание
sandbox_subscription_limit (400)Достигнут лимит тестовых подписок (10 на организацию) — очистите песочницу
Organization not verified (403)Подписки в рабочем режиме доступны только верифицированной организации

Асинхронные ошибки Kaspi: status=error / поле error_message (HTTP-кода нет)

КодОписание
status=errorСчёт создан (201, статус processing), но Kaspi не смог его обработать — статус сменился на error. Причина текстом в поле error_message (GET /invoices/{id}). У Kaspi нет фиксированных кодов — текст приходит как есть
error_message: номер не в Kaspi«Этот номер телефона не зарегистрирован в Kaspi. Укажите номер с установленным приложением Kaspi.» — у клиента нет приложения Kaspi; попросите другой номер
error_message: сбой Kaspi«Ошибка обработки платежа. Обратитесь в поддержку» или «Не удалось обработать счёт после нескольких попыток» — временный сбой Kaspi; повторите создание счёта позже

Поле error_code — стабильный машинный код (новое, рекомендуется)

КодОписание
error_code (новое поле)Стабильный snake_case-код ошибки из фиксированного каталога (21 значение). Присутствует в JSON-ответах об ошибках и в webhook-объектах invoice (для status=error) и refund (для status=failed). Поля message/error сохранены без изменений. Определяйте тип ошибки по error_code, текст — для показа пользователю. У каждого кода ниже указана «Доставка» — приходит ли он асинхронно (в webhook) или синхронно (HTTP-ответ с кодом)
error_code: network_unavailableСервис временно недоступен (сбой сети/Kaspi). Можно повторить позже. Доставка: async (webhook)
error_code: session_transientВременные проблемы авторизации Kaspi. Можно повторить попытку. Доставка: async (webhook)
error_code: client_not_foundНомер телефона не зарегистрирован в Kaspi. Не повторяемая — попросите другой номер. Доставка: async (webhook)
error_code: kaspi_throttledKaspi ограничил частоту запросов. Повторите через 2–3 минуты. Доставка: async (webhook)
error_code: refund_window_expiredСрок возврата истёк или возврат уже сделан (часто для refund status=failed). Доставка: async (webhook)
error_code: invoice_already_paidСчёт уже оплачен. Доставка: async (webhook)
error_code: invoice_already_cancelledСчёт уже отменён. Доставка: async (webhook)
error_code: invoice_not_found_in_kaspiСчёт не найден в Kaspi. Доставка: async (webhook)
error_code: organization_not_configuredОрганизация не настроена (нет рабочей привязки Kaspi). Доставка: async (webhook)
error_code: unknown_errorНепредвиденная ошибка обработки — обратитесь в поддержку. Доставка: async (webhook)
error_code: qr_render_failedНе удалось сформировать изображение QR-кода — повторите запрос. Доставка: sync HTTP 500
error_code: kaspi_session_invalidСессия кассира Kaspi истекла или сброшена — переподключите кассира. Доставка: sync HTTP 503
error_code: kaspi_session_unavailableНе удалось проверить сессию Kaspi — попробуйте позже. Доставка: sync HTTP 503
error_code: manager_throttledСлишком много операций — попробуйте позже. Доставка: sync HTTP 429
error_code: whatsapp_otp_throttledСлишком частые запросы кода WhatsApp — попробуйте позже. Доставка: sync HTTP 429
error_code: whatsapp_gateway_errorНе удалось отправить код WhatsApp — попробуйте ещё раз. Доставка: sync HTTP 500
error_code: subscription_payment_failedНе удалось создать счёт для оплаты подписки — попробуйте позже. Доставка: sync HTTP 502
error_code: kaspi_errorKaspi API вернул ошибку — повторите позже. Текст message содержит конкретную причину от Kaspi. Доставка: sync HTTP 502
error_code: cart_items_mismatchЗарезервирован — сейчас не используется бэкендом. Доставка: —
error_code: image_upload_failedЗарезервирован — сейчас не используется бэкендом. Доставка: —
error_code: catalog_item_not_foundЗарезервирован — сейчас не используется бэкендом. Доставка: —

Формат ответа ошибки

{
  "message": "Описание ошибки",
  "errors": {
    "field_name": ["детали ошибки"]
  }
}

Changelog