☰ Мәзір · POS және кассалар
POS және кассалар
Кассаға керектің бәрі: қонақты табу, чек өткізу, кэшбэкпен төлеу, қайтаруларды өңдеу және кассаның өз нөмірлері бар карталарды шығару.
Кассадағы әдеттегі сценарий: кассир қонақтың Wallet картасын сканерлейді (немесе телефонын тереді), касса балансты көрсетеді, қонақ чектің бір бөлігін кэшбэкпен төлеу-төлемеуін шешеді, чек жабылады және касса оны бізге жібереді. Телефондағы карта бірнеше секундта жаңарады.
1. Қонақты табу
GET /v1/members/{member} кассада бар кез келген мәнді қабылдайды: карта нөмірін, штрихкод мазмұнын, халықаралық пішімдегі телефонды немесе біздегі қатысушы id-ін. Телефонды URL-кодтаңыз (+ таңбасы %2B болады).
# by the number on the card (or the barcode the scanner read)
curl https://loyaltyfy.io/api/v1/members/2000111703779 \
-H "Authorization: Bearer sk_test_..."
# by phone, with fresh add-to-wallet links
curl "https://loyaltyfy.io/api/v1/members/%2B37366791102?expand=wallet" \
-H "Authorization: Bearer sk_test_..."Қатысушы объектісінен бағдарламаға маңызды мәндерді кассирге көрсетіңіз:
| program.mechanic | Не көрсету керек |
|---|---|
| cashback | cashback.balance және төлеуге болатын ең көп сома: баланс пен чектің redeem_max_percent үлесінің кішісі. |
| stamps | stamps.required ішінен stamps.current, ал қонақты тегін тауар күтіп тұрса, stamps.rewards_available. |
| visit_discount, vip | discount.percent және discount.tier: бұл жеңілдікті чекке өзіңіз қолданыңыз. |
2. Карта штрихкодында не бар
Мекеме штрихкод пішімін Әзірлеушілерге → Карта штрихкоды бөлімінде кассаның сканері оқитындай етіп таңдайды:
| Пішім | Штрихкодта не бар | Қашан қолдану керек |
|---|---|---|
| Карта нөмірі бар QR | card_number, мысалы 2000111703779 | Сканер QR оқиды, ал касса карта нөмірі бойынша іздейді. Ұсынылады. |
| Карта нөмірі бар штрихкод (Code 128) | Сол нөмір сызықтық штрихкод түрінде, жолақтардың астында басылады | QR оқи алмайтын ескі лазерлік сканерлер. |
| Loyaltyfy кассасына арналған QR | Біздің ішкі сериялық нөмір (UUID) | Әдепкі. Оны тек Loyaltyfy касса қосымшасы оқиды. POS қонақты бәрібір телефон арқылы таба алады. |
Пішімді өзгерткенде қонақтардың Wallet ішіндегі карталары да жаңарады, ешкімге ештеңені қайта орнатудың керегі жоқ. Пішім қандай болса да, сканерленген мәнді өзгертпестен GET /v1/members/{member} немесе POST /v1/scans эндпоинтіне жіберіңіз. Соңғысы сканер префикстері мен жол ауыстыруларды да алып тастайды.
3. Кассаның өз нөмірлерімен карта шығару
Кассада карта жүйесі бұрыннан бар болса, оның нөмірлерін сақтаңыз. Қонақты card_number өрісіне кассаның нөмірін беріп тіркеңіз: Wallet картасы осы нөмірді көрсетеді және штрихкод оны кодтайды, сондықтан сканер қонақты кассаның өз базасынан да табады. Нөмірлер мекеме ішінде бірегей: қайталанған нөмір 409 card_number_taken алады. Бар қатысушыға кейін касса нөмірін беру үшін card_number өрісімен PATCH /v1/members/{member} шақырыңыз.
curl https://loyaltyfy.io/api/v1/members \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7d1b2c4e-enrol-000123" \
-d '{
"phone": "+37366791102",
"first_name": "Ion",
"last_name": "Popescu",
"card_number": "2000111703779",
"language": "ro",
"consent": true
}'Жауапта wallet.apple_url және wallet.google_url болады. Оларды чекке QR ретінде басып шығарыңыз, SMS арқылы жіберіңіз немесе клиент дисплейінде көрсетіңіз: қонақ сілтемені ашады да, карта телефонға қосылады.
4. Чек өткізу
Әр жабық чекті төлемнен кейін бір рет жіберіңіз. amount дегеніміз кэшбэк шегерілгенге дейінгі толық чек, redeem_amount дегеніміз қонақ оның қанша бөлігін кэшбэкпен төлегені. Бағдарлама ережелерін (ең аз чек, төлеу шегі, деңгейлер) мекеменің кассир экраны сияқты қолданамыз.
curl https://loyaltyfy.io/api/v1/transactions \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"external_id": "CHK-2026-000123",
"member": "2000111703779",
"amount": 25000,
"currency": "MDL",
"register_id": "POS-1",
"closed_at": "2026-10-06T18:17:00+03:00",
"line_items": [
{ "sku": "1001", "name": "Espresso", "quantity": 2, "unit_price": 4000, "category": "Coffee" },
{ "sku": "2005", "name": "Cheesecake", "quantity": 1, "unit_price": 17000, "category": "Desserts" }
]
}'{
"object": "transaction",
"id": "f8acbb16-0b3b-4afc-acbb-e5eabd4dd072",
"external_id": "CHK-2026-000123",
"status": "completed",
"amount": 25000,
"redeem_amount": 0,
"cashback_earned": 1250,
"stamps_earned": 0,
"reward_unlocked": false,
"net_amount": 25000,
"currency": "MDL",
"register_id": "POS-1",
"closed_at": "2026-10-06T15:17:00+00:00",
"livemode": false,
"created_at": "2026-10-06T18:17:17.921+00:00",
"voided_at": null,
"member": {
"object": "member",
"id": "6dacfe0a-2500-44c6-a37c-05c660b093b4",
"card_number": "2000111703779",
"cashback": { "balance": 1250, "currency": "MDL", "earn_rate": 5, ... },
...
}
}external_id мекеменің барлық кассаларында бірегей болуы керек. Чек нөмірлері әр кассада немесе әр ауысымда басынан басталса, оларды біріктіріңіз, мысалы POS-3-000123 (3-касса, 123-чек).Кэшбэк қонақ шын мәнінде төлеген сомаға есептеледі: amount − redeem_amount. Штамп және келу бағдарламаларында чек келу ретінде есептеледі. stamps_earned және reward_unlocked не болғанын айтады, сондықтан касса "тағы бір кофе, келесісі тегін" деп көрсете алады.
5. Кэшбэкпен төлеу
Алдымен балансты сұраңыз, қонақ таңдасын, содан кейін чекті redeem_amount өрісімен жіберіңіз. Осы аралықта баланс өзгерсе (қонақ бір секунд бұрын басқа жерде төлеген), ағымдағы available сомасымен 402 insufficient_balance аласыз. Оны көрсетіп, кассирге қайталауға мүмкіндік беріңіз.
curl https://loyaltyfy.io/api/v1/transactions \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"external_id": "CHK-2026-000124",
"member": "2000111703779",
"amount": 12000,
"redeem_amount": 1250
}'{
"error": {
"type": "invalid_request_error",
"code": "insufficient_balance",
"message": "redeem_amount is more than the available balance.",
"param": "redeem_amount",
"available": 1250
},
"request_id": "req_6f4c30b8ca7d4423a9d4"
}201 немесе 200 деп жауап бергеннен кейін беріңіз. Чекті сомасы түпкілікті болғанда, бірақ төлемді алмай тұрып жіберіңіз. Жауап болмаса, сол external_id арқылы қайталаңыз немесе чекті кэшбэксіз жабыңыз. Әйтпесе қонақ әрі жеңілдік алып, әрі балансын сақтап қалуы мүмкін.6. Штамп сыйлығын беру
stamps.rewards_available нөлден үлкен болса, қонақтың тегін тауары бар. Оны кассада беріп, тіркеңіз:
curl -X POST https://loyaltyfy.io/api/v1/members/4285324286429/rewards/redeem \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: reward-4285324286429-0001"7. Қайтарулар мен қателер
Бүкіл чекті оның external_id мәні бойынша болдырмаңыз. Есептелген кэшбэк немесе штамптар кері алынады, төленген кэшбэк қонаққа қайтарылады. Ішінара қайтару: чекті болдырмап, түзетілген сомамен және жаңа external_id мәнімен жаңа чек жіберіңіз.
curl -X POST https://loyaltyfy.io/api/v1/transactions/CHK-2026-000123/void \
-H "Authorization: Bearer sk_test_..."8. Касса желіден тыс болғанда
Чектерді external_id және closed_at мәндерімен жергілікті кезекке жинап, байланыс қалпына келгенде жіберіңіз. Қайталанғандары еленбейді, сондықтан бүкіл кезекті қайта жіберу қауіпсіз. Қонақты іздеу үшін желі керек. Желі жоқ болса, сатуды тоқтатпай, кассир осы чекте адалдық бағдарламасын өткізіп жіберсін.
Кассаның серверінен жіберілетін чектер
Кейбір POS жүйелері кассада API шақыра алмайды, бірақ жабық чектерді өз серверінен жібере алады. Бұл да жұмыс істейді: чек жабылған бойда серверден кассир сканерлеген карта нөмірімен сол POST /v1/transactions жіберіңіз. Касса нәтижені кейін көрсеткісі келсе, transaction.completed оқиғасына жазылыңыз.