Создание счёта
POST /v1/cashier/invoices ставит в очередь один счёт плательщику. Запрос идемпотентен.
Метод и путь: POST {ELEVENPAY_BASE_URL}/v1/cashier/invoices (базовый адрес вам выдают при подключении — Окружения).
Машиночитаемый контракт: /openapi.json.
Заголовки
| Заголовок | Обязателен | Значение |
|---|---|---|
Authorization | да | Bearer <API_KEY> — ключ окружения live с возможностью cashier.invoice.create |
Idempotency-Key | да | 1–255 печатаемых ASCII-символов без пробелов; один ключ на одну логическую команду |
Content-Type | да | application/json |
Тело
Дополнительные поля запрещены.
| Поле | Тип | Правила |
|---|---|---|
amount | string | точно два знака после точки, целое число тенге: "1500.00". JSON-число отклоняется |
currency | string | только "KZT" (по умолчанию KZT) |
merchant_order_id | string | 1–100 символов A-Za-z0-9_.:-; ваш идентификатор заказа |
customer_phone | string | только цифры, 10–15 |
{
"amount": "1500.00",
"currency": "KZT",
"merchant_order_id": "order_demo_1001",
"customer_phone": "77001234567"
}Ответ
201 Created — счёт поставлен в очередь; 200 OK — безопасный повтор (тот же Idempotency-Key и тот же запрос). Заголовок Idempotency-Replayed: true|false показывает, был ли это повтор.
{
"reference": "ep1_7t4k2m8q9x3v6b1n5c0d2f4a8h",
"merchant_order_id": "order_demo_1001",
"status": "pending",
"amount": "1500.00",
"currency": "KZT",
"environment": "live",
"created_at": "2024-09-05T11:59:30Z",
"invoice_state": "queued",
"payer_action": null,
"settled": false
}| Поле | Значение |
|---|---|
reference | публичный идентификатор (ep1_…) для GET |
status | состояние платежа (pending → succeeded); см. Статусы |
invoice_state | где находится счёт: queued, sending, sent, not_sent, unknown |
payer_action | null или "approve_in_kaspi_app": задано только пока счёт дошёл до приложения и платёж ещё открыт |
settled | true только когда расчёт подтверждён |
Телефон плательщика в ответах и вебхуках не возвращается.
Не говорите плательщику «откройте приложение» раньше времени
Показывайте инструкцию «подтвердите платёж в приложении» только когда payer_action равен "approve_in_kaspi_app". Пока invoice_state — queued или sending, показывайте «отправляем запрос…». Любое неизвестное значение трактуйте как «неизвестно», а не как «оплачено».
Идемпотентность и стабильный заказ
- Храните
Idempotency-Keyвместе с заказом до первого запроса и используйте тот же ключ при каждом повторе (потеря ответа, таймаут, перезапуск процесса). Повтор вернёт исходный счёт. - Тот же ключ с другим запросом (другая сумма, телефон, заказ) →
409 idempotency_conflict. - Для одного
merchant_order_idсуществует один счёт: новый ключ для того же заказа →409 cashier_order_not_unique. Если счёт «потерян» илиunknown, не создавайте второй: повторите исходный запрос с исходным ключом или заведите новый заказ осознанно.
Подробнее — Идемпотентность.
Ошибки создания
Формат: {"error": {"code": "...", "message": "..."}}. Ориентируйтесь на code.
| HTTP | code | Что делать |
|---|---|---|
| 400 | idempotency_key_required, idempotency_key_invalid | добавьте/исправьте заголовок |
| 401 | invalid_api_key | проверьте ключ |
| 403 | forbidden | у ключа нет cashier.invoice.create |
| 403 | organization_unavailable | организация недоступна; обратитесь в поддержку |
| 409 | idempotency_conflict | ключ уже использован для другого запроса |
| 409 | cashier_order_not_unique | счёт для этого merchant_order_id уже есть |
| 409 | cashier_environment_unsupported | нужен ключ окружения live |
| 409 | cashier_live_disabled, cashier_pilot_stopped, cashier_merchant_disabled, cashier_not_authorized, cashier_authorization_expired | приём счетов не включён/остановлен/не разрешён для организации; не повторяйте вслепую |
| 409 | cashier_limit_exceeded | превышен лимит; см. условия подключения |
| 409 | cashier_operation_unsupported, cashier_amount_invalid | операция или сумма недопустимы |
| 409 | cashier_not_connected, cashier_session_not_active | подключение канала оплаты отсутствует или требует переподключения — сообщите в поддержку |
| 409 | ambiguous_create_blocked | предыдущее создание не разрешено однозначно и не будет повторено; не создавайте второй счёт |
| 422 | payment_amount_invalid, amount_not_whole_tenge, customer_phone_invalid | исправьте поле |
| 422 | (формат FastAPI detail) | неверная форма тела; см. Ошибки |
| 429 | rate_limited | слишком много запросов; учитывайте Retry-After |
| 429 | payer_rate_limited | плательщику недавно уже отправили слишком много счетов (Retry-After: 3600) |
| 500 | internal_error | повторите с тем же ключом позже |
| 503 | service_unavailable | повторите с тем же ключом позже |
Пример: curl
curl -X POST "$ELEVENPAY_BASE_URL/v1/cashier/invoices" \
-H "Authorization: Bearer $ELEVENPAY_API_KEY" \
-H "Idempotency-Key: $(cat order-1001.idempotency-key)" \
-H "Content-Type: application/json" \
-d '{"amount":"1500.00","currency":"KZT","merchant_order_id":"order_demo_1001","customer_phone":"77001234567"}'Готовые клиенты на Python и Node.js уже реализуют стабильный ключ, безопасные повторы и опрос.