Қысқаша
Счёт жасау — бір ғана сұрау:
POST https://api.qut.kz/api/v1/invoices
X-API-Key: qp_live_…
Content-Type: application/json
Жауапта 201 күйі және payUrl келеді — клиентті сол адреске жіберіңіз. Міндетті өріс біреу ғана: amount.
Ескі жол POST /api/v1/orders да қабылданады, ол дәл осы эндпоинттің alias-ы.
Сұраудың өрістері
| Өріс | Тип | Міндетті | Сипаттама | |
|---|---|---|---|---|
amount | number | ✅ | Теңге. QR счётта ең көбі 2 ондық, телефонға счётта бүтін сан | |
kind | qr \ | phone | — | qr — әдепкі: QR код және сілтеме. phone — клиенттің Kaspi қосымшасына push |
description | string | — | Клиент көреді. QR — 100 таңба, phone — 60 таңба | |
externalOrderId | string | — | Сіздің тапсырыс нөміріңіз. Webhook-та қайта келеді | |
customer.name | string | — | Клиенттің аты | |
customer.phone | string | kind: phone үшін ✅ | 7XXXXXXXXXX пішімінде, 11 сан | |
customer.email | string | — | Берілсе клиентке чек хаты кетуі мүмкін | |
successUrl | url | — | Төлем сәтті өткенде клиент қайтатын адрес. Тек http(s) | |
failUrl | url | — | Төлем өтпегенде қайтатын адрес. Тек http(s) | |
metadata | object | — | Кез келген JSON. Өзгертілмей сақталады және webhook-та қайта келеді |
Тақырыптар:
| Тақырып | Міндетті | Не үшін |
|---|---|---|
X-API-Key | ✅ | qp_live_… немесе qp_test_… |
Content-Type: application/json | ✅ | Дене JSON |
Idempotency-Key | — | Қайталаудан қорғайды, төменде |
Idempotency-Key жіберсеңіз, сол кілтпен екінші рет сұрау жаңа счёт жасамайды: бұрынғысы қайтады, HTTP 200 және жауапта idempotentReplay: true болады. Толығырақ: Идемпоттылық.
qr мен phone айырмашылығы
qr | phone | |
|---|---|---|
| Клиент не көреді | QR код немесе төлем сілтемесі | Kaspi қосымшасындағы push-счёт |
customer.phone | Міндетті емес | Міндетті |
| Сома | 2 ондыққа дейін | Тек бүтін теңге |
description | 100 таңба | 60 таңба |
| Қашан ыңғайлы | Сайт, офлайн нүкте, экран | Телефон арқылы сату, қашықтан |
Толық салыстыру: QR счёт пен телефонға счёт.
Жауап
HTTP 201 және мынандай дене:
| Өріс | Не |
|---|---|
id | Счёттың идентификаторы, inv_… |
status | Жасалғанда pending |
payUrl | Төлем беті, клиентті осында жіберіңіз |
qrUrl | QR-дың мазмұны |
deepLink | Kaspi қосымшасын ашатын сілтеме |
qrImageUrl | QR суреті, өз бетіңізге қоюға болады |
expiresAt | Осы уақыттан кейін счёт жарамсыз |
QR-дың сканерлеу терезесі шамамен үш минут, оны Kaspi белгілейді. Оны кодыңызда тұрақты сан деп жазбаңыз — әрқашан expiresAt өрісінен алыңыз.
curl мысалы
curl -X POST https://api.qut.kz/api/v1/invoices \
-H 'X-API-Key: qp_live_…' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1001' \
-d '{
"amount": 2500,
"kind": "qr",
"description": "Тапсырыс №1001",
"externalOrderId": "1001",
"customer": { "name": "Айгүл", "phone": "77010000000" },
"successUrl": "https://site.kz/ok",
"failUrl": "https://site.kz/fail",
"metadata": { "branch": "almaty-1", "cart": 17 }
}'
Node мысалы
const res = await fetch('https://api.qut.kz/api/v1/invoices', {
method: 'POST',
headers: {
'X-API-Key': process.env.QUTPAY_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': `order-${order.id}`,
},
body: JSON.stringify({
amount: order.total,
kind: 'qr',
description: `Тапсырыс №${order.id}`,
externalOrderId: String(order.id),
successUrl: 'https://site.kz/ok',
metadata: { orderId: order.id },
}),
});
if (!res.ok) {
const err = await res.json();
console.error('qutpay', res.status, err.error, err.message);
throw new Error(err.error);
}
const invoice = await res.json();
redirect(invoice.payUrl);
Қате болғанда error кодына қараңыз, message мәтініне емес: мәтін өзгеруі мүмкін, код өзгермейді.
/orders alias
Ескі интеграциялар үшін POST /api/v1/orders жолы сақталған. Онда merchantRef (яғни externalOrderId) және method: "invoice" өрістері де қабылданады. Жаңа код жазып жатсаңыз, /api/v1/invoices қолданыңыз.
Жиі кездесетін қателер
| Код | HTTP | Не болды | Шешімі |
|---|---|---|---|
invalid_amount | 422 | Сома жоқ немесе сан емес | Оң сан жіберіңіз |
amount_must_be_whole_tenge | 422 | Тиын жіберілген | Бүтін теңге жіберіңіз |
amount_too_small / amount_too_large | 422 | Сома шектен тыс | Соманы түзетіңіз |
invalid_phone | 422 | Телефон пішімі бөлек | 7XXXXXXXXXX, 11 сан, + және бос орынсыз |
phone_required | 422 | kind: phone, бірақ телефон жоқ | customer.phone қосыңыз |
invalid_kind | 422 | Белгісіз түр | qr немесе phone |
invalid_url | 422 | successUrl/failUrl дұрыс емес | Толық http(s) адрес жазыңыз |
unauthorized | 401 | Кілт жоқ немесе жарамсыз | X-API-Key тақырыбын тексеріңіз |
insufficient_scope | 403 | Кілтте invoices:write жоқ | Кабинеттен scope қосыңыз |
kaspi_session_expired | 409 | Кассир байланысы үзілген | Қайта байланыстырыңыз |
tariff_limit_reached | 429 | Айлық лимит бітті | Тарифтер және лимиттер |
invoice_create_failed | 502 | Kaspi счётты қабылдамады | Өсіп отыратын кідіріспен қайталаңыз |
Толық тізім: Қателер каталогы.
Шекті жағдайлар
- Тиын. QR счёт екі ондықты қабылдайды, ал телефонға счёт бүтін теңгені ғана. Сомаңызда тиын болса,
kind: phoneалдында дөңгелектеңіз. - Ұзын сипаттама. Шектен асқан мәтін клиентте қиылып көрінуі мүмкін, сондықтан QR үшін 100, phone үшін 60 таңбадан асырмаңыз.
- Бірнеше счёт бір тапсырысқа. Клиент «төлеу» батырмасын екі рет бассаңыз екі счёт жасалады.
Idempotency-Keyқойыңыз. - Көп счёт бірден керек. 100-ге дейін счётты бір сұраумен жасауға болады: Топтап счёт жасау.
- Жауапты күтіп қалдыңыз. Таймаут болса счёт жасалған да болуы мүмкін. Сол
Idempotency-Keyмен қайталаңыз — жаңасы жасалмайды.
Жиі қойылатын сұрақтар
payUrl мен deepLink айырмашылығы неде? payUrl — браузерде ашылатын төлем беті, кез келген құрылғыда жұмыс істейді. deepLink — Kaspi қосымшасын тікелей ашады, телефонда ыңғайлы.
Счёттың күйін қалай білемін? Webhook арқылы немесе GET /api/v1/invoices/{id} сұрауымен. Қайсысын қашан: Webhook пен күйді сұрау.
metadata ішіне не жазуға болады? Кез келген JSON: нүкте нөмірі, себет идентификаторы, ұяшық нөмірі. Ол webhook-та да, күй сұрауында да сол күйінде қайтады.
Счёт жасалғаннан кейін сомасын өзгертуге бола ма? Жоқ. Счётты болдырып, жаңасын жасаңыз.
Sandbox-та да осы өрістер жүре ме? Иә, бірдей. Айырмашылығы — Kaspi шақырылмайды, төлемді өзіңіз симуляциялайсыз.