Cüzdanla Ödeme
- 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_SCOPEalı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:
| Model | Kim başlatır | Ne zaman kullanılır |
|---|---|---|
Ödeme talebi (payments/buy) | İşletme, alıcıyı telefon/cüzdan no ile hedefleyerek | E-ticaret, uzaktan satış, fatura tahsilatı |
Kodla tahsilat (CPM) (collect) | İşletme, müşterinin gösterdiği tek kullanımlık kodla | Fiziksel kasa, POS, mağaza |
Ödeme talebi
Talebi oluşturun
POST /api/v1/wallet/payments/buy| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
buyerWalletNo | string | ⚠️ | Alıcının cüzdan numarası |
buyerPhone | string | ⚠️ | Alıcının telefonu |
amount | string | ✅ | Minor-unit |
currency | string | ✅ | |
paymentPurpose | string | ✅ | İşlem amacı |
orderRef | string | — | Sizin sipariş numaranız |
cashierRef | string | — | Kasiyer/şube referansı |
otpDestination, otpChannel, locale | string | — | 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}/approveilebuyerEndUserId,integrityHash,nonceveotpCodetaşınarak.buyerEndUserIdödeyen son kullanıcıdır ve zorunludur; ödeme isteğinin ödeyeniyle eşleşmezse istek404ile 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 etKod 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| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
code | string | ✅ | Müşterinin gösterdiği kod |
amount | string | ✅ | Minor-unit |
currency | string | ✅ | |
orderRef | string | — | Fiş/sipariş referansı |
paymentPurpose | string | — | |
locale | string | — |
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}/commissionKomisyon ş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
| Olay | Ne zaman |
|---|---|
wallet.payment.completed | Ödeme tamamlandı, işletme hesabına geçti |
wallet.payment.failed | Ödeme başarısız |
wallet.payment.reversed | Tamamlanmış ödeme ters kaydedildi |
wallet.refund.credited | Cüzdana iade kredilendi |
wallet.refund.reversed | İade ters kaydedildi |
Yaygın hatalar
| Durum | Sebep | Çö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ş olabilir | Baş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 |