Payment Orchestrator
Cüzdana İade

Cüzdana İade

Cüzdana İade, çekilmiş bir ödemeyi kart ağına geri döndürmek yerine alıcının program-içi cüzdan bakiyesine kredi olarak yatırır — müşteri bu "store credit"i sizin ekosisteminiz içinde harcar. Bu ayrı bir endpoint ve ayrı bir izne sahiptir; mevcut kart iadeniz (POST /payments/:id/refund) değişmez. İkisi de para-kritiktir: bu endpoint kart iadesiyle aynı Step-Up'ı (Bearer artı Ed25519 imza) kullanır ve tek bir kalıcı idempotency anahtarı altında çalışır.

Tüm tutarlar minor-unit (kuruş) integer'dır: "amount": 500 cüzdana ₺5,00 kredi yatırır. Asla ondalık veya float göndermeyin.

⚠️

Bu endpoint POST /payments/:id/refund-to-wallet'tir — kart iadesi endpoint'i değildir. Parayı karta geri göndermek için kart iadesi kullanın. Pazaryeri / split ödemeler cüzdana iade edilemez, kart iadesi kullanmalıdır.

Nasıl çalışır

Cüzdana-iade endpoint'ini çağırın

Step-Up kimlik bilgileriniz ve bir Idempotency-Key ile POST /payments/:id/refund-to-wallet. Kısmi kredi için amount ekleyin; kalan iade edilebilir tutarın tamamı için hiç göndermeyin. Yalnızca birden fazla cüzdan programı işletiyorsanız programId ekleyin.

Platform müşteriyi sunucuda çözer

Alıcının telefonu ve dış id'si, ödemenin kayıtlı buyer'ından okunur — asla istekten alınmaz. Müşteri, program içinde telefon ile dedup edilir; yoksa bir cüzdan otomatik açılır (auto-provision). Pazaryeri/split ödemeler burada reddedilir.

Kredi cüzdana uygulanır

Önce cüzdan kredilenir ve ledger POST edilir, ardından destination=WALLET iade satırı ve ödemenin state geçişi finalize edilir. Tüm operasyon kalıcı refundId üzerinde idempotent'tir; bu yüzden tekrar denemeler asla çifte kredi yaratmaz.

Webhook teyit eder

wallet.refund.credited, webhook endpoint'inize teslim edilir. Sipariş durumunuzu yalnız senkron yanıttan değil, webhook'tan mutabık kılın.

İstek

Kimlik doğrulama Step-Up'tır: at_live_… Bearer token'ınız artı Ed25519 istek imzası — tüm para hareketi endpointlerinde zorunludur; bkz. Authentication. İzin, kart iadesi izninden ayrı olan payment:refund-to-wallet'tir.

AlanTipAnlamı
amountinteger (minor unit), opsiyonelCüzdana yatırılacak tutar. Kalan iade edilebilir bakiyenin tamamını yatırmak için göndermeyin.
reasonstring, opsiyonelSerbest metin sebep; raporlamanız için iade kaydında saklanır.
programIdstring, opsiyonelHedef cüzdan programı. Tek program işletiyorsanız göndermeyin (cüzdan çözer). Yalnızca birden fazla program işletiyorsanız zorunludur.

Alıcı istekten alınmaz. buyerPhone ve externalCustomerId, ödemenin kayıtlı buyer'ından sunucuda çözülür; bu yüzden DTO'da buyer alanı yoktur. İstemciden farklı bir hedef müşteri dayatılamaz.

# Alıcının cüzdanına ₺5,00 kısmi kredi
curl https://api-gateway.lunixi.com/api/v1/payments/pay_01J9ZK3W8Q/refund-to-wallet \
  -H "Authorization: Bearer at_live_5f3e2b1a..." \
  -H "Idempotency-Key: wallet-refund-84721-1" \
  -H "Content-Type: application/json" \
  # ...artı Ed25519 istek-imza header'ları — bkz. Authentication
  -d '{
    "amount": 500,
    "reason": "Store credit"
  }'
 
# Kalan bakiyenin tamamı cüzdana — amount göndermeyin
curl https://api-gateway.lunixi.com/api/v1/payments/pay_01J9ZK3W8Q/refund-to-wallet \
  -H "Authorization: Bearer at_live_5f3e2b1a..." \
  -H "Idempotency-Key: wallet-refund-84721-final" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Siparis iptal edildi" }'

Her iade niyeti için ayrı bir Idempotency-Key kullanın. Anahtar, kalıcı refundId olur; aynı anahtarla tekrar denemek aynı cüzdan kredisini güvenle geri oynatır (ağ zaman aşımları ve reconcile taramaları çifte kredi yaratmaz), aynı ödemede yeni bir anahtar ise kalan bakiyeye karşı ek bir kredi oluşturur.

Yanıt

200 OK, paranın cüzdana kredilendiği veya alıcının cüzdanı olmadığında karta iade edildiği anlamına gelir (aşağıdaki fallback kuralları). Hangi yolun izlendiğini bilmek için webhook'tan mutabık kılın.

Davranış

Program çözümü — kendi cüzdan programınız

programId opsiyoneldir. Göndermezseniz cüzdan, merchant'ın tek programını çözer; birden fazla program işletiyorsanız programId zorunludur.

Telefon dedup'ı ve auto-provision

Program, son kullanıcı ve cüzdan/hesap kavramları için Cüzdan — Temel Kavramlar sayfasına bakın.

Cüzdan kullanıcısı program içinde telefon (birincil) ile dedup edilir: o telefon hash'ine sahip bir müşteri varsa kredi ona yazılır; yoksa telefon artı externalCustomerId ile bir cüzdan otomatik açılır. Eşzamanlı provision yarışları, telefon/dış-id UNIQUE kısıtına karşı çözülür.

Cüzdan yoksa kart iadesine fallback

Alıcının cüzdanı yoksa ve provision edilemiyorsa — ödemede telefon yok (NO_PHONE) ya da CANNOT_PROVISION — akış otomatik olarak standart kart iadesine düşer. Müşteri yine de iade edilir ve yine 200 alırsınız.

Özellik kapalıysa açık hata

Özellik kapalıyken cüzdan inert bir DISABLED döner ve endpoint açık bir hata verir — bilinçli olarak sessizce karta düşmez. Bu kasıtlı ayrım, "alıcının cüzdanı yok" (fallback) ile "özellik kapalı" (hata) durumlarını birbirinden ayırır.

Hangi statuslarda cüzdana iade mümkün

Ödeme statüsüCüzdana iade edilebilir mi?
SETTLEDEvet — v1'de desteklenen statü
AUTHORIZEDHayır — henüz kredilenecek çekilmiş para yok
INITIATED, PROCESSING, AWAITING_3DHayır — henüz çekilmiş para yok
REFUNDEDHayır — iade edilecek bir şey kalmadı
Pazaryeri / split ödeme (her statü)Hayır — kart iadesi kullanın

İade tavanı, kart iadesiyle aynı matematiği paylaşır: kümülatif captured_amount eksi önceki iadeler.

Hatalar

DurumNe görürsünüzNe yapmalı
Pazaryeri / split ödemeReddedilirBunun yerine kart iadesi endpoint'ini kullanın
Alıcının telefonu yok / provision edilemiyor200 — karta iade edildiBir şey yapmayın — müşteri iade edildi; webhook'tan mutabık kılın
Özellik kapalıAçık DISABLED hatasıCüzdana İade'yi açtırmak için hesap yöneticinizle iletişime geçin
amount kalan iade edilebilir bakiyeyi aşıyor422Ödemeyi okuyun, en fazla kalan bakiyeyi kredilendirin
Bilinmeyen payment id404paymentId'yi doğrulayın
Cüzdan kredisi tamamlanamadı ya da sonucu henüz kesin değil502 payment.refund_to_wallet.credit_failedKart iadesi başlatmayın — kredi gerçekleşmiş olabilir. Aynı Idempotency-Key ile tekrar deneyin ya da wallet.refund.credited webhook'unu bekleyin; aynı anahtar çifte kredi yaratmaz
Aynı Idempotency-Key ile tekrar istekAynı cüzdan kredisi geri dönerGüvenli — çifte kredi olmaz

Webhook'lar

EventNe zaman ateşlenir
wallet.refund.creditedİade cüzdana başarıyla kredilendi
wallet.refund.reversedBir operatör bu cüzdan iadesini geri aldı (wallet.refund.credited'in eşlenik tersi)

Endpoint yapılandırması ve teslimat semantiği için Webhooks.

Sonraki adımlar

  • İadeler — çekilen parayı karta geri döndürme ve alıcının cüzdanı olmadığında fallback yolu
  • Webhook'lar — wallet.refund.credited ve wallet.refund.reversed alma
  • Ödemeleri Listeleme — bir ödemenin güncel statüsünü ve geçmişini okuma