Cüzdan
Cüzdanla Ödeme

Cüzdanla Ödeme

Bu uçları kim çağırır?Dış API (s2s)
Taban yol
/api/v1/wallet
Kimlik
Ed25519 istek imzası — X-Key-Id, X-Date, X-Nonce, Digest (body varsa), X-Signature. Zaman penceresi ±5 dk, nonce tek kullanımlık, anahtarda IP allow-list olabilir.
Yetki
Anahtarınız cüzdan ürününü ve çağrının gerektirdiği cüzdan iznini taşımalıdır; izni olmayan çağrı 403 WALLET_INSUFFICIENT_SCOPE alır. Uç başına izinler: Anahtar izinleri.
Çapraz yüzey
Bu uçlar s2s yüzeyindedir (payments/buy, collect, payments/:id/approve, payments/:id). Son kullanıcı onayı portal tarafındadır (me/payments/:requestId/approve, me/authorizations/*) ve step-up ister.

Cüzdanla ödeme, bireysel bir kullanıcının program içindeki bir işletme hesabına bakiyesinden ödeme yapmasıdır. Kart ağı devrede değildir; para tenant içinde yer değiştirir, bu yüzden anında ve düşük maliyetlidir.

İki tahsilat modeli vardır:

ModelKim başlatırNe zaman kullanılır
Ödeme talebi (payments/buy)İşletme, alıcıyı telefon/cüzdan no ile hedefleyerekE-ticaret, uzaktan satış, fatura tahsilatı
Kodla tahsilat (CPM) (collect)İşletme, müşterinin gösterdiği tek kullanımlık kodlaFiziksel kasa, POS, mağaza

Ödeme talebi

Talebi oluşturun

POST /api/v1/wallet/payments/buy
AlanTipZorunluAçıklama
buyerWalletNostring⚠️Alıcının cüzdan numarası
buyerPhonestring⚠️Alıcının telefonu
amountstring✅Minor-unit
currencystring✅
paymentPurposestring✅İşlem amacı
orderRefstring—Sizin sipariş numaranız
cashierRefstring—Kasiyer/şube referansı
otpDestination, otpChannel, localestring—Alıcı onayı için

⚠️ buyerWalletNo veya buyerPhone'dan biri zorunludur.

curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/payments/buy" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-ORD-4471" \
  -H "X-Key-Id: …" -H "X-Signature: …" \
  -d '{
    "buyerPhone": "+905321234567",
    "amount": "18900",
    "currency": "TRY",
    "paymentPurpose": "PURCHASE",
    "orderRef": "ORD-4471"
  }'

Müşteri onaylar

Ödeme, müşteri onaylayana kadar tamamlanmaz. Onay iki yoldan gelir:

  • Portal/uygulamadan — müşteri kendi uygulamasında POST /api/portal/v1/wallet/me/payments/{requestId}/approve çağırır (uygulamanız bu ekranı sunar).
  • s2s tarafından — POST /api/v1/wallet/payments/{id}/approve ile buyerEndUserId, integrityHash, nonce ve otpCode taşınarak. buyerEndUserId ödeyen son kullanıcıdır ve zorunludur; ödeme isteğinin ödeyeniyle eşleşmezse istek 404 ile reddedilir.
{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "operationId": "e9c4a7b2-1f3d-4a6e-b8c5-7d2f0e9a3b16",
    "status": "COMPLETED",
    "ledgerTxnRef": "ltx_01J8ZW…"
  }
}

Sonucu doğrulayın

GET /api/v1/wallet/payments/{id}
⚠️

Ödemeyi "başarılı" sayıp malı teslim etme kararını COMPLETED durumuna bağlayın. INITIALIZED ve CHALLENGED yalnızca "talep açıldı" demektir; müşteri hiç onaylamayabilir.

Sonuç henüz kesin değilse: INDETERMINATE

Onay yanıtında status: "INDETERMINATE" görebilirsiniz. Bu bir ret değildir: tutar müşterinin cüzdanından çekilmiş olabilir, ancak işlemin son durumu henüz kesinleşmemiştir. Cüzdan işlemi kısa süre içinde kendiliğinden COMPLETED ya da FAILED/REVERSED olarak kesinleştirir.

⚠️

INDETERMINATE gördüğünüzde ödemeyi başarısız saymayın, müşteriyi başka bir ödeme yöntemine yönlendirmeyin ve yeni bir ödeme talebi açmayın — ilk ödeme tamamlanırsa müşteriden iki kez tahsilat yapılmış olur. Sonucu GET /api/v1/wallet/payments/{id} ile sorgulayın ya da onayı aynı Idempotency-Key ile yeniden gönderin; işlem kesinleşince kesin durum döner.

Kodla tahsilat (CPM)

Fiziksel kasada müşteri uygulamasında tek kullanımlık bir kod üretir; kasiyer bu kodu okutur ve tahsilat yapılır.

Müşteri kodu üretir

POST   /api/portal/v1/wallet/me/payment-code    # kod üret
DELETE /api/portal/v1/wallet/me/payment-code    # kodu iptal et

Kod kısa ömürlüdür ve tek kullanımlıktır; okutulduğu anda tükenir.

İşletme tahsil eder

POST /api/v1/wallet/collect
AlanTipZorunluAçıklama
codestring✅Müşterinin gösterdiği kod
amountstring✅Minor-unit
currencystring✅
orderRefstring—Fiş/sipariş referansı
paymentPurposestring—
localestring—
⚠️

Kod tek kullanımlıktır: kasada ağ hatası alırsanız aynı kodu tekrar okutmayın, Idempotency-Key ile aynı isteği tekrarlayın. Kod tükenmişse müşteriden yeni kod isteyin.

Kodu ekranda gösterirken sürenin dolmasına kalan zamanı da gösterin. Süresi dolmuş kod kasada "geçersiz" hatası verir ve kasiyer bunu genellikle bakiye sorunu sanır.

Komisyon

İşletme hesabına yapılan ödeme, program komisyon şemasına tabidir. Komisyon ödeme anında hesaplanır ve işletmenin alacağından düşülür.

GET /api/v1/wallet/business-accounts/{id}/commission

Komisyon şemaları merchant panelden versiyonlanarak yönetilir ve onaya tabidir: Panel — Limit & Ücret Şemaları.

Ücret (fee) ile komisyon (commission) farklıdır: ücret işlemi yapandan alınır, komisyon tahsilat yapan işletmeden alınır. Operasyon kaydında ikisi ayrı alanlarda görünür (feeTotal, commissionTotal).

İade

Cüzdanla yapılmış bir ödemenin iadesi cüzdana yapılır. Kart ödemesinin cüzdana iadesi ayrı bir üründür: Cüzdana İade.

Webhook'lar

OlayNe zaman
wallet.payment.completedÖdeme tamamlandı, işletme hesabına geçti
wallet.payment.failedÖdeme başarısız
wallet.payment.reversedTamamlanmış ödeme ters kaydedildi
wallet.refund.creditedCüzdana iade kredilendi
wallet.refund.reversedİade ters kaydedildi

Yaygın hatalar

DurumSebepÇözüm
Ödeme CHALLENGED'da kaldıMüşteri onaylamadıSüre dolunca EXPIRED; yeni talep açın
Onay INDETERMINATE döndüSonuç henüz kesinleşmedi; tutar çekilmiş olabilirBaşarısız saymayın; sorgulayın ya da aynı anahtarla yeniden onaylayın (ayrıntı)
Kod "geçersiz"Süre doldu veya kod kullanıldıMüşteriden yeni kod isteyin
Komisyon beklenenden farklıAktif komisyon şeması sürümü değişmişcommissionScheduleVersionId ile operasyondaki sürümü kontrol edin
Alıcı bulunamadıTelefon programda kayıtlı değilÖnce POST /wallet/wallets/lookup ile kontrol edin