Қысқаша
Вендинг автоматында схема қарапайым: клиент тауарды таңдайды → автоматтың контроллері бұлттағы сіздің серверге айтады → сервер Qut Pay-де счёт жасайды → QR автоматтың экранында шығады → клиент Kaspi-мен сканерлейді → бізден серверге invoice.paid webhook келеді → сервер автоматқа «бер» деген команда жібереді. Су, кофе, снек автоматтарының бәріне бірдей келеді. QR әр сатылымға жаңадан жасалады, экранда тұрақты тұрған сурет жарамайды.
Жұмыс схемасы
| Қадам | Кім | Не істейді |
|---|---|---|
| 1 | Клиент | Автоматта тауарды таңдайды (мысалы, 5 литр су) |
| 2 | Контроллер | Бұлттағы серверге сұрау: автомат №, ұяшық, сома |
| 3 | Сіздің сервер | POST /api/v1/invoices, metadata ішіне автомат нөмірі мен ұяшық |
| 4 | Сіздің сервер | Контроллерге qrImageUrl немесе qrUrl мен expiresAt береді |
| 5 | Автомат | Экранда QR мен таймер көрсетеді |
| 6 | Клиент | Kaspi қосымшасымен сканерлеп растайды |
| 7 | Qut Pay | Серверге invoice.paid жібереді |
| 8 | Сіздің сервер | Автоматқа команда: ұяшықты аш / насосты қос |
| 9 | Автомат | Тауарды береді, экранды бастапқы күйге қайтарады |
Клиент растағаннан кейін webhook әдетте бес секунд ішінде келеді, сондықтан адам автоматтың жанында тұрып күте алады.
Қандай API әдісі қолданылады
Негізгісі — POST /api/v1/invoices, kind: "qr":
POST https://api.qut.kz/api/v1/invoices
X-API-Key: qp_live_…
Idempotency-Key: vm-014-1726300000
{
"amount": 250,
"kind": "qr",
"description": "Автомат №14, су 5 л",
"externalOrderId": "vm-014-88231",
"metadata": { "machine": "VM-014", "slot": "A2", "address": "Абай 10" }
}
Жауаптан керегі: id, qrImageUrl (экранға шығаратын сурет), qrUrl, expiresAt (таймер үшін).
Қосымша:
GET /api/v1/invoices/{id}— webhook кешіксе күйін сұрауPOST /api/v1/invoices/{id}/cancel— клиент кетіп қалса, счётты жабуPOST /api/v1/invoices/{id}/refund— тауар берілмей қалса, ақшаны қайтару
Автомат нөмірін metadata-ға жазыңыз
Бұл — бүкіл сценарийдің негізі. metadata ішіне кемінде үшеуін салыңыз: автомат нөмірі, ұяшық немесе тауар коды, мекенжай. Webhook келгенде қай автоматқа команда жіберу керегін сол өрістен бірден білесіз, өз базаңыздан іздемей-ақ.
externalOrderId ретінде автомат нөмірі мен ішкі сатылым нөмірін біріктірген ыңғайлы: vm-014-88231. Кейін есеп бергенде де, дауды шешкенде де осы нөмір бойынша табасыз.
Нүктелер бойынша бөлек есеп керек болса, әр нүктеге бөлек API кілт жасаңыз — счёттарды көзі бойынша сүзу жеңілдейді.
Жабдық жағы
Автоматтың ішінде не керек:
- Байланысы бар контроллер. GSM модемі (SIM картамен) немесе нүктеде Wi-Fi болса Wi-Fi модулі. Қосылымсыз схема жұмыс істемейді: счёт бұлтта жасалады.
- Экран. QR-ды көрсететін кез келген экран жарайды. Кейбір автоматтарда бұрыннан бар, кейбіріне шағын дисплей қою керек.
- Бұлттағы сервер. Счёт жасайды, webhook қабылдайды, автоматқа команда жібереді. API кілт тек осында тұрады, контроллердің ішінде емес.
- Команда арнасы. Көбіне MQTT: контроллер брокерге жазылып тұрады, сервер сол арнаға «ұяшық A2-ні аш» деп жібереді. HTTP арқылы да болады — контроллер серверден күйді сұрап отырады, бірақ MQTT жылдамырақ әрі желіге аз жүктейді.
API кілтті контроллерге салмаңыз. Автоматтың ішіндегі құрылғыны ашып алуға болады, ал бір кілт бүкіл желіге жарайды. Контроллер тек өз серверіңізге, өзінің құрылғы токенімен жүгінсін.
QR терезесі — ең маңызды шектеу
Сканерлеу терезесі шамамен үш минут, оны Kaspi белгілейді. Вендингте бұл бірден екі салдар береді.
Экранда тұрақты QR ілініп тұра алмайды. Әр сатылымға жаңа счёт жасалады. Автоматтың экранында алдын ала басып қойылған QR суреті болса, ол бір күннен кейін жұмысын тоқтатады.
Таймер көрсетіңіз. expiresAt өрісін алып, экранда «QR 2:40 ішінде жарамды» деп жазыңыз. Уақыт біткенде «Қайта көрсету» батырмасын беріңіз — контроллер жаңа счёт сұрайды, ескісі expired болып қалады.
Тұрақты QR басып қою керек болса (мысалы, «сұрақ болса осында төлеңіз» деген қосымша жол), ол QR емес, төлем сілтемесі болуы керек: qut.kz/p/<slug>. Оның мерзімі бітпейді, сомасы ашық түрі де бар.
Ерекше ескертулер
- Идемпоттылық. Байланыс үзіліп, контроллер сұрауды қайта жіберуі — қалыпты жағдай.
Idempotency-Keyқойыңыз, әйтпесе бір клиентке екі счёт шығады. - Webhook идемпотентті болсын.
(invoice.id, status)жұбы бойынша бір-ақ рет өңдеңіз — әйтпесе автомат екі бөтелке беріп жібереді. - Тауар берілмей қалса. Ақша түсіп, ұяшық ашылмаса (тұрып қалды, тауар бітті), автоматты түрде
refundжасайтын логика жазыңыз. Бұл вендингтегі ең жиі дау. - Webhook пен күйді сұрауды қатар жүргізіңіз. Клиент автоматтың жанында тұр, күту ұзаққа созылмауы керек. Webhook 5-10 секунд ішінде келмесе, контроллер
GET /invoices/{id}арқылы күйді сұрап көрсін: Төлем баяу расталады. - Webhook адресі ашық болуы керек. Продакшенде тек
httpsжәне нақты домен, IP мен туннель адресі қабылданбайды. Адрес авторизациясыз ашық болсын, әйтпесе жеткізу құлайды: Webhook келмей жатыр. - Кеш төлем. Мерзімі біткен счётқа ақша келсе, оқиға
late: trueбелгісімен келеді. Клиент кетіп қалған болса, ақшаны қайтарыңыз. - Автомат саны көбейгенде тарифті қайта қараңыз. Он автомат күніне 50 сатылымнан жасаса, айына 15 000 счёт болады: Қай тарифті таңдау керек.
Жиі қойылатын сұрақтар
Автоматтың өзінде интернет жоқ, бола ма? Болмайды. Счёт бұлтта жасалады, ал төлем расталғанын автомат білуі керек. Ең арзаны — GSM модемі бар контроллер.
Бір QR-ды бірнеше адам сканерлесе не болады? Бір QR — бір счёт. Сондықтан ол бір ғана сатылымға жарайды, әрі әр сатылымнан кейін экранды бастапқы күйге қайтару керек.
Автоматта экран жоқ, тек түймелер. Қалай? Онда шағын дисплей қосу керек. QR-ды көрсететін жер болмаса, бұл схема жұмыс істемейді.
Сканерлеп қойды да, интернет үзіліп қалды. Ақша қайда? Ақша сіздің Kaspi шотыңызға түседі, ол автоматқа тәуелді емес. Автомат тауарды бере алмаса, refund жасаңыз. Сондықтан контроллердің әр командасын журналға жазып отырыңыз.
Он автоматқа бір кілт бола ма? Болады, бірақ әр нүктеге бөлек кілт берген дұрыс: есеп бөлек шығады, әрі бір кілт шығып кетсе, тек соны жойып, қалғандарын тимей қаласыз.