☰ Menü · POS ve yazarkasalar
POS ve yazarkasalar
Bir kasanın ihtiyacı olan her şey: misafiri bulun, fişi işleyin, cashback harcatın, iadeleri yönetin ve kasanın kendi numaralarını taşıyan kartlar çıkarın.
Kasadaki olağan akış: kasiyer misafirin Wallet kartını okutur (veya telefonu girer), kasa bakiyeyi gösterir, misafir fişin bir kısmını cashback ile ödeyip ödemeyeceğine karar verir, fiş kapanır ve kasa fişi bize gönderir. Misafirin telefonundaki kart birkaç saniye içinde güncellenir.
1. Misafiri bulun
GET /v1/members/{member} kasada hangi bilgi varsa onu kabul eder: kart numarası, barkod içeriği, uluslararası formatta telefon veya bizim üye id'miz. Telefonu URL-encode edin (+ karakteri %2B olur).
# 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_..."Kasiyere, üye nesnesinden programa göre önemli olan bilgileri gösterin:
| program.mechanic | Gösterin |
|---|---|
| cashback | cashback.balance ve harcanabilecek en yüksek tutar: bakiye ile fişin redeem_max_percent oranından küçük olanı. |
| stamps | stamps.required içinden stamps.current, misafiri bekleyen ücretsiz ürün varsa stamps.rewards_available. |
| visit_discount, vip | discount.percent ve discount.tier: bu indirimi fişe kendiniz uygulayın. |
2. Kart barkodunda ne var
İşletme barkod biçimini Geliştiriciler → Kart barkodu bölümünden, kasa tarayıcısının okuduğu biçime göre seçer:
| Biçim | Barkodun içeriği | Ne zaman kullanılır |
|---|---|---|
| Kart numaralı QR | card_number, örneğin 2000111703779 | Tarayıcı QR okuyor ve kasa kart numarasıyla arama yapıyor. Önerilen seçenek. |
| Kart numaralı barkod (Code 128) | Aynı numara, çizgili barkod olarak ve altında yazılı | QR okuyamayan eski lazer tarayıcılar. |
| Loyaltyfy kasa uygulaması için QR | Dahili seri numaramız (UUID) | Varsayılan. Yalnızca Loyaltyfy kasa uygulaması okur. POS misafiri yine de telefonla bulabilir. |
Biçimi değiştirdiğinizde misafirlerin Wallet'ındaki mevcut kartlar da güncellenir, kimsenin bir şey yeniden yüklemesi gerekmez. Biçim ne olursa olsun, okunan değeri olduğu gibi GET /v1/members/{member} veya POST /v1/scans uç noktasına gönderin. İkincisi tarayıcı öneklerini ve satır sonlarını da temizler.
3. Kasanın kendi numaralarıyla kart çıkarın
Kasanın zaten bir kart sistemi varsa numaralarını koruyun. Misafiri card_number alanında kasanın numarasıyla kaydedin. Wallet kartı bu numarayı gösterir ve barkodu da bu numarayı içerir, böylece tarayıcı misafiri kasanın kendi veritabanında da bulur. Numaralar işletme bazında benzersizdir: tekrar eden numara 409 card_number_taken alır. Mevcut bir üyeye sonradan kasa numarası atamak için card_number ile PATCH /v1/members/{member} kullanın.
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
}'Yanıtta wallet.apple_url ve wallet.google_url bulunur. Bunları fişe QR olarak basın, SMS ile gönderin veya müşteri ekranında gösterin: misafir bağlantıyı açar ve kart telefona eklenir.
4. Fişi işleyin
Her kapanan fişi ödemeden sonra bir kez gönderin. amount, cashback düşülmeden önceki fiş toplamıdır. redeem_amount, misafirin bunun ne kadarını cashback ile ödediğidir. Program kurallarını (minimum fiş tutarı, harcama limiti, seviyeler) işletmenin kasiyer ekranıyla aynı şekilde uygularız.
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 işletmenin tüm kasalarında benzersiz olmalıdır. Fiş numaraları her kasada ya da her vardiyada baştan başlıyorsa bunları birleştirin, örneğin POS-3-000123 (3 numaralı kasa, 123 numaralı fiş).Cashback, misafirin gerçekte ödediği tutar üzerinden kazanılır: amount − redeem_amount. Damga ve ziyaret programlarında fiş bir ziyaret sayılır. stamps_earned ve reward_unlocked ne olduğunu söyler, böylece kasa "bir kahve daha, sonraki bedava" diyebilir.
5. Cashback ile ödeme
Önce bakiyeyi sorgulayın, misafir seçsin, sonra fişi redeem_amount ile gönderin. Bu arada bakiye değiştiyse (misafir bir saniye önce başka yerde ödeme yaptıysa) güncel available tutarıyla 402 insufficient_balance alırsınız. Bu tutarı gösterin ve kasiyerin tekrar denemesine izin verin.
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 ya da 200 ile yanıt verdikten sonra uygulayın. Fişi tutarı kesinleştiğinde, ama ödemeyi almadan önce gönderin. Yanıt gelmezse aynı external_id ile tekrar deneyin ya da fişi cashback olmadan kapatın. Aksi halde misafir hem indirimi alır hem de bakiyesini korur.6. Damga ödülünü verin
stamps.rewards_available sıfırdan büyükse misafirin ücretsiz bir ürün hakkı vardır. Ürünü kasada verin ve kaydedin:
curl -X POST https://loyaltyfy.io/api/v1/members/4285324286429/rewards/redeem \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: reward-4285324286429-0001"7. İadeler ve hatalar
Fişin tamamını external_id değeriyle iptal edin. Kazanılan cashback veya damgalar geri alınır, harcanan cashback misafire iade edilir. Kısmi iade için fişi iptal edin ve düzeltilmiş tutarla, yeni bir external_id ile yeni fiş gönderin.
curl -X POST https://loyaltyfy.io/api/v1/transactions/CHK-2026-000123/void \
-H "Authorization: Bearer sk_test_..."8. Kasa çevrimdışıyken
Fişleri external_id ve closed_at değerleriyle yerel olarak kuyruğa alın, bağlantı gelince gönderin. Tekrarlar yok sayılır, bu yüzden tüm kuyruğu yeniden göndermek güvenlidir. Üye sorgulama için ağ gerekir. Ağ yoksa satışı engellemek yerine kasiyerin o fiş için sadakat adımını atlamasına izin verin.
Kasa sunucusundan gönderilen fişler
Bazı POS sistemleri kasadan API çağıramaz ama kapanan fişleri kendi sunucusundan gönderebilir. Bu da çalışır: fiş kapanır kapanmaz aynı POST /v1/transactions isteğini, kasiyerin okuttuğu kart numarasıyla sunucudan gönderin. Kasa sonucu daha sonra göstermek istiyorsa transaction.completed olayına abone olun.