Қысқаша
Тұрақта схема мынау: жүргізуші шығу тұсына келеді → билет нөмірін енгізеді немесе нөмірін камера оқиды → сіздің сервер тұрақ уақытына қарай соманы есептеп, Qut Pay-де счёт жасайды → экранда QR шығады → жүргізуші Kaspi-мен сканерлеп растайды → бізден webhook келеді → сервер IP-реле арқылы шлагбаумды ашады. QR әр шығуға жаңадан жасалады: сканерлеу терезесі шамамен үш минут. Жүргізуші машинадан шықпай тұрып төлейді.
Жұмыс схемасы
| Қадам | Кім | Не істейді |
|---|---|---|
| 1 | Жүргізуші | Шығу тұсына келеді, билет нөмірін енгізеді |
| 2 | Тұрақ бақылаушысы | Серверге сұрау: билет №, кіру уақыты, көлік нөмірі |
| 3 | Сіздің сервер | Соманы есептеп, POST /api/v1/invoices жасайды |
| 4 | Экран | QR мен таймерді көрсетеді |
| 5 | Жүргізуші | Kaspi-мен сканерлеп растайды |
| 6 | Qut Pay | Серверге invoice.paid жібереді |
| 7 | Сіздің сервер | IP-релеге команда жібереді |
| 8 | Шлагбаум | Ашылады, оқиға журналға жазылады |
Клиент растағаннан кейін webhook әдетте бес секунд ішінде келеді. Шығу тұсында мұның өзі ұзақ: артында кезек тұр. Сондықтан төмендегі «кідіріс» бөлімін міндетті түрде оқыңыз.
Қандай API әдісі қолданылады
Негізгісі — POST /api/v1/invoices, kind: "qr":
POST https://api.qut.kz/api/v1/invoices
X-API-Key: qp_live_…
Idempotency-Key: park-exit-4471
{
"amount": 600,
"kind": "qr",
"description": "Тұрақ: билет 4471, 2 сағ 15 мин",
"externalOrderId": "park-4471",
"metadata": {
"ticket": "4471",
"plate": "123ABC02",
"gate": "exit-2",
"entered_at": "2026-09-14T09:12:00Z"
}
}
Керегі: id, qrImageUrl, expiresAt. Қалғаны: GET /api/v1/invoices/{id} — күйін сұрау, POST /api/v1/invoices/{id}/cancel — жүргізуші төлемей кетсе, POST /api/v1/invoices/{id}/refund — шлагбаум ашылмай қалса.
Абонементпен жүретін тұрақ болса, айлық төлемді жазылым арқылы кестеге қоюға болады. Бірақ есіңізде болсын: жазылым счётты кестеге сай шығарады, ақшаны клиент әр жолы өзі растайды.
Көлік нөмірін metadata-ға жазыңыз
metadata ішіне міндетті түрде салыңыз: билет нөмірі, көлік нөмірі, қай шлагбаум, кіру уақыты. Webhook келгенде қай шлагбаумды ашу керегін сол өрістен бірден білесіз.
Бұл дауды шешуге де керек: «мен төледім, ол ашылмады» дегенде счётты көлік нөмірі бойынша тауып, оқиғалар тізбегін көрсетесіз. externalOrderId ретінде билет нөмірін беріңіз — іздеу жеңіл болады.
Бірнеше тұрағыңыз болса, әрқайсысына бөлек API кілт беріңіз: нүктелер бойынша есеп бөлек шығады.
Динамикалық және басылған QR
Динамикалық QR (негізгі жол). Экранда әр шығуға жаңа счёт көрсетіледі. Сомасы сол көлікке нақты есептелген, төлем нақты билетке байланады, шлагбаум автоматты ашылады. Осы жолды қолданыңыз.
Басылған QR (қосымша жол). Шығу тұсына тұрақты қағаз код іліп қоюға болады, бірақ ол счёттың QR-ы болмауы керек — счёттың терезесі шамамен үш минут, ертесіне ол жұмысын тоқтатады. Тұрақты код үшін төлем сілтемесін қолданыңыз: qut.kz/p/<slug>, сомасы ашық түрі де бар.
Бірақ басылған кодтың бір кемшілігі бар: төлем нақты билетке байланбайды, сондықтан шлагбаум өздігінен ашылмайды. Оны күзетші қолмен ашады немесе оператор кабинеттен төлемді көріп растайды. Сондықтан ол — автомат істемей қалғандағы немесе кіші тұрақтағы қосалқы нұсқа.
| Динамикалық QR | Басылған төлем сілтемесі | |
|---|---|---|
| Сома | Нақты есептелген | Клиент өзі енгізеді немесе тұрақты |
| Билетке байланады | Иә | Жоқ |
| Шлагбаум автоматты ашыла ма | Иә | Жоқ, қолмен |
| Мерзімі | Шамамен 3 минут | Бітпейді |
| Қайда жарайды | Негізгі жол | Қосалқы, кіші тұрақ |
Жабдық жағы
- Шығу тұсындағы экран мен пернетақта — QR көрсету және билет нөмірін енгізу үшін.
- Бұлттағы сервер — соманы есептейді, счёт жасайды, webhook қабылдайды, шлагбаумға команда береді. API кілт тек осы жерде тұрады.
- IP-реле немесе контроллер — шлагбаумның «ашу» кірісіне жалғанады. Сервер релеге команда жібереді, реле контактіні жабады.
- Байланыс — тұрақта интернет болуы міндетті. Қосалқы GSM арнасын қойған дұрыс: интернет үзілсе, шлагбаум жұмыс істемей қалады.
Релені интернетке тікелей шығармаңыз. Ол тек сіздің сервердің командасын қабылдасын. API кілтті реленің немесе жергілікті контроллердің ішіне салмаңыз.
Кідіріс маңызды: webhook пен сұрауды қатар жүргізіңіз
Шығу тұсында бірнеше секундтың өзі ұзақ. Сондықтан екі арнаны қатар ұстаңыз:
- Webhook — негізгісі.
invoice.paidкелгенде шлагбаум ашылады. - Күйді сұрау — сақтандырғыш. Счёт жасалғаннан кейін контроллер
GET /api/v1/invoices/{id}арқылы күйді әр 2-3 секунд сайын сұрап отырсын. Қайсысы бірінші «paid» көрсе, сол ашады — екеуін бір оқиға деп санаңыз, екі рет ашпаңыз.
Poller әр үш секунд сайын жүреді, ал үш минуттан жас счёттар әр айналымда тексеріледі — яғни жаңа счёттың күйі ең жиі жаңарады. Жалпы жылдамдық туралы: Төлем баяу расталады.
Webhook мүлде келмей жатса, себебін журналдан қарау керек: Webhook келмей жатыр.
Ерекше ескертулер
- Идемпоттылық. Жүргізуші «QR» батырмасын бірнеше рет бассa, әр басқан сайын жаңа счёт шықпауы керек.
Idempotency-Keyретінде билет нөмірін беріңіз. - Webhook идемпотентті болсын.
(invoice.id, status)жұбы бойынша бір рет өңдеңіз, әйтпесе шлагбаум екі рет ашылып, артындағы көлік те өтіп кетеді. - Шлагбаум ашылмай қалса — қайтару. Ақша түсіп, реле істемесе (интернет үзілді, жабдық қатесі)
refundжасаңыз. Бұл жердегі ең жиі дау осы. - Кеш төлем. Мерзімі біткен счётқа ақша келсе, оқиға
late: trueбелгісімен келеді. Жүргізуші кетіп қалған болса, ақшаны қайтарыңыз. - Күзетшіге қолмен ашу мүмкіндігін қалдырыңыз. Интернет үзілген сәтте тұрақ тұрып қалмауы керек.
- Әр оқиғаны журналға жазыңыз: счёт жасалды, төленді, реле командасы кетті, шлагбаум ашылды. Дау шыққанда осы журнал ғана көмектеседі.
- Алдымен sandbox.
qp_test_…кілтімен бүкіл тізбекті өткізіңіз: счёт →simulate→ webhook → реле командасы: Sandbox пен нақты режимнің айырмашылығы.
Жиі қойылатын сұрақтар
Шығу тұсына бір рет QR басып іліп қойсам бола ма? Счёттың QR-ы жарамайды — оның терезесі шамамен үш минут. Тұрақты код керек болса, төлем сілтемесін қолданыңыз, бірақ онда шлагбаум автоматты ашылмайды.
Көлік нөмірін камера оқиды, билет жоқ. Бола ма? Иә. Сома есептеу мен счёт жасау реті сол күйі қалады, тек metadata ішіне билет орнына көлік нөмірін жазасыз.
Абонемент сатсам, ай сайын өзі шешіле ме? Жоқ. Жазылым белгіленген кестемен счёт шығарады, ал төлемді клиент әр жолы Kaspi-де өзі растайды.
Жүргізуші төлеп үлгермей, QR-дың уақыты бітсе? Жаңа счёт жасайсыз — экранда «Қайта көрсету» батырмасы болсын. Ескі счёт expired болып қалады, ақша алынбайды.
Интернет үзілсе не болады? Счёт жасау да, webhook та жұмыс істемейді. Сондықтан қосалқы GSM арнасын және күзетшінің қолмен ашу мүмкіндігін алдын ала қарастырыңыз.