☰ Menü · İşletme kuralları ve limitler
Rehberler

İşletme kuralları ve limitler

İşletme, bağlı kasaların neler yapabileceğini nasıl belirler: cashback seviyeleri, ürün kategorileri, rezervasyonlar, fiş numaralandırma, geç gelen fişler, limitler ve kart okutma kontrolü.

Bu sayfadaki her şeyi işletme sahibi Geliştiriciler → Kasa kuralları bölümünde ayarlar. Kurallar işletmenin tüm API anahtarları için geçerlidir. Tek bir anahtar (bir kasa, bir kiosk) bunların her biri için kendi değerine sahip olabilir. Entegrasyonunuz hangi kurallarla çalıştığını GET /v1/account yanıtındaki settings alanından okur.

JSON
"settings": {
  "redemption": "hold",
  "hold_minutes": 30,
  "check_numbering": "per_register",
  "offline_max_hours": 72,
  "redeem_max_per_check": 50000,
  "redeem_max_per_day": null,
  "require_scan": true,
  "scan_window_minutes": 30,
  "allow_adjustments": false,
  "adjustment_max": 50000
}

Cashback seviyeleri

Bir cashback programının seviyeleri olabilir: örneğin Temel %5, ikinci ziyaretten itibaren Gümüş %7, 1000,00 harcamadan itibaren Altın %10. Seviyeler ziyaret sayısına, toplam harcamaya ya da hangisi önce gelirse ona göre hesaplanır. İşletme sahibi bunları sadakat programında ayarlar. Kasa tarafında bir şey yapmanız gerekmez: her fiş, misafirin o fişten sonraki seviyesine göre kazandırır ve her üye nesnesi misafirin hangi seviyede olduğunu gösterir.

JSON
"cashback": {
  "balance": 10200,
  "held": 0,
  "available": 10200,
  "currency": "MDL",
  "earn_rate": 7,
  "level": "Silver",
  "level_basis": "any",
  "levels": [
    { "name": "Base", "earn_rate": 5, "min_visits": null, "min_spent": null },
    { "name": "Silver", "earn_rate": 7, "min_visits": 2, "min_spent": null },
    { "name": "Gold", "earn_rate": 10, "min_visits": null, "min_spent": 100000 }
  ],
  "next_level": { "name": "Gold", "earn_rate": 10, "visits_left": null, "spent_left": 80000 },
  ...
}

next_level.visits_left ve next_level.spent_left doğrudan misafire gösterilebilir ("Gümüş seviyeye 2 ziyaret kaldı"). display.receipt_lines bu satırı misafirin dilinde hazır olarak içerir.

Ürün kategorileri

Ürünlerinizi kategorileriyle bir kez yükleyin, sonra yalnızca değişiklikleri gönderin. Kategoriler işletme sahibinin panelinde görünür. Orada her kategori için şunlar seçilebilir: cashback kazandırmasın (tütün, alkol), cashback ile ödenemesin (zaten kampanyada olan ürünler) ya da misafirin seviyesi yerine kendi oranıyla kazandırsın (kahve %10). API ürün ve kategori oluşturabilir, adlarını değiştirebilir, ancak bu kuralları yalnızca işletme sahibi değiştirir.

curl
curl https://loyaltyfy.io/api/v1/catalog/products/bulk \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "products": [
      { "sku": "4840001", "name": "Marlboro Gold", "category": "TOB", "category_name": "Tobacco", "price": 6500 },
      { "sku": "1001", "name": "Latte", "category": "COF", "category_name": "Coffee", "price": 4500 },
      { "sku": "2040", "name": "Zeama", "category": "KIT", "category_name": "Kitchen", "price": 6500 }
    ]
  }'

# { "object": "catalog_sync", "upserted": 3 }

Ardından her fişle birlikte line_items gönderin. Bir satır category içerebilir ya da yalnızca sku taşıyabilir: bu durumda kategoriyi katalogdan buluruz. Satır toplamları fiş tutarına oranlanır, böylece kasa tarafında yapılan indirimler satırlara adil şekilde dağılır. Kuralı olmayan kategorilerdeki satırlar misafirin seviyesine göre kazandırır.

curl
curl https://loyaltyfy.io/api/v1/transactions \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "CHK-2026-000130",
    "member": "2000111703779",
    "amount": 17500,
    "line_items": [
      { "sku": "4840001", "quantity": 1, "unit_price": 6500 },
      { "sku": "1001", "quantity": 1, "unit_price": 4500 },
      { "sku": "2040", "quantity": 1, "unit_price": 6500 }
    ]
  }'

# Tobacco earns nothing, Coffee has its own 10%, Kitchen earns at the guest's level (5%):
# 0 + 450 + 325 = "cashback_earned": 775

Rezervasyonla cashback ödemesi

Fişin içinde seçeneğinde (varsayılan) kasa redeem_amount değerini kapanan fişle birlikte gönderir. Rezervasyonla seçeneğinde kasa, misafir cashback ile ödemek istediğinde tutarı ayırır, kapanan fiş de bunu onaylar. Fiş hiç gelmezse (bağlantı koptu, satış iptal edildi) rezervasyon işletme sahibinin belirlediği süreden sonra kalkar ve para misafirde kalır. Bakiyeden düşülmeden hiçbir indirim verilmez.

  1. 1
    Rezerve edin

    Üye, tutar ve fiş toplamıyla POST /v1/holds gönderin. Fişteki limitlerin aynısı uygulanır. Yanıtta rezervasyonun id değeri bulunur.

  2. 2
    Onaylayın

    hold_id ile POST /v1/transactions gönderin. Rezervasyonun tamamını kullanmak için redeem_amount göndermeyin ya da daha küçük bir tutar gönderin.

  3. 3
    Ya da kaldırın

    Satış iptal edildiğinde POST /v1/holds/{id}/release çağırın. İki kez kaldırmak zarar vermez.

curl
curl https://loyaltyfy.io/api/v1/holds \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hold-R3-000131" \
  -d '{ "member": "2000111703779", "amount": 3000, "check_amount": 20000, "register_id": "R3" }'

# at payment: the check captures it
curl https://loyaltyfy.io/api/v1/transactions \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{ "external_id": "000131", "register_id": "R3", "member": "2000111703779",
        "amount": 20000, "hold_id": "5b0d6c1e-8f3a-4d7e-9a61-2c4b8e0f7d19" }'
Rezervasyonlar her yerde hesaba katılır: üyenin cashback.available değerinde, limitlerde ve işletmenin kendi kasiyer uygulamasında. Böylece aynı para iki kez harcanamaz.

Kasa bazında fiş numaraları

Her kasa fişleri 1'den saymaya başlıyorsa Her kasa kendi numarasını verir seçeneğini seçin. Bu durumda register_id zorunludur ve fişi <register_id>:<external_id> olarak saklarız, örneğin R3:15. Fişi okumak, iptal etmek veya iade etmek için bu birleşik id'yi kullanın.

Geç gönderilen fişler

Bir kesintiden sonra kasa kuyruğundaki fişleri gönderir. Limit örneğin 72 saat ise closed_at değeri bundan eski olan fişler check_too_old ile reddedilir. Böylece eski bir yedekten geri yüklenen kasa işletmeye eski fişler yağdıramaz. Gelecekte 10 dakikadan daha ileri bir closed_at her zaman reddedilir.

Cashback kullanım limitleri

İşletme sahibi, programın fiş başına oranına ek olarak fiş başına ve misafir başına günlük en fazla cashback tutarını belirleyebilir (tüm kasalar birlikte, işletmenin saat dilimine göre). Daha fazlasını isteyen bir fiş izin verilen kadarını kullanır ve yanıt gerçek redeem_amount değerini gösterir. Daha fazlasını isteyen bir rezervasyon limited_by ile reddedilir. Misafire kesin tutarı önceden göstermek için hesaplama uç noktasını kullanın.

Kart okutulmalı

Bu kural açıkken bir kart için fiş, ziyaret, rezervasyon veya ödül yalnızca aynı anahtar o kartı kısa süre önce POST /v1/scans uç noktasına gönderdiyse kabul edilir. Kasada elle yazılan kart numarası scan_required ile reddedilir. Tarayıcının ham çıktısını /v1/scans uç noktasına gönderin, sonra her zamanki gibi devam edin.

Elle düzeltmeler

Varsayılan olarak kapalıdır. İşletme sahibi izin verdiğinde members:adjust iznine sahip bir anahtar, bir neden belirterek ve sahibin düzeltme başına belirlediği limite kadar cashback ekleyip düşebilir. Her düzeltme üyenin geçmişinde görünür ve balance.adjusted gönderir.

curl
curl https://loyaltyfy.io/api/v1/members/2000111703779/adjustments \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{ "external_id": "ADJ-2026-0009", "amount": 2000, "reason": "Goodwill after a complaint" }'

# a negative amount takes cashback away
Entegrasyonla ilgili sorularınız için: api@loyaltyfy.io. Bir iş günü içinde yanıt veriyoruz.