Payment Orchestrator
Cüzdanla Öde

Cüzdanla Öde — Payment

paymentMethod: "WALLET" ile POST /payments/direct/payment, alıcının cüzdanından ödeme alır. Alıcı telefonuna gelen tek seferlik kodla ödemeyi onaylar; kodu siz confirm ile gönderirsiniz. Bu sayfa cüzdanla ödemenin bütün istek alanlarını, yanıtını, onayını ve hatalarını gösterir; bütün yöntemlerde ortak olan aksiyon, confirm ve hata kodu kuralları Payment sayfasındadır.

Hesabınızda kullanılabilen cüzdanlar GET /payments/methods yanıtında WALLET satırının providers listesindedir. İşletmenizin kendi cüzdan programı bağlıysa o da bu listede, programınızın adı ve logosuyla yer alır.

Nasıl çalışır

Cüzdanı seçin

Tek cüzdan bağlıysa wallet.providerCode gönderilmesi gerekmez. Birden fazla cüzdan bağlıysa alıcının seçtiği cüzdanın kodunu gönderin; göndermezseniz 400 payment.provider.required döner. Bkz. Sağlayıcıyı seçme.

Ödemeyi başlatın

wallet bloğunda alıcının cüzdan hesabının telefon numarasını (gsmNumber) ve cüzdanın inputFields tanımındaki diğer alanları gönderin.

Kodu alın

Yanıt (202) bir OTP aksiyonu taşır. Kod action.otp.maskedTarget numarasına gönderilir. Aksiyon charge taşıyorsa alıcıya onaydan önce toplam tutarı gösterin.

Onaylayın

Alıcının girdiği kodu POST /payments/{paymentId}/actions/{actionId}/confirm ile gönderin. Sonuç 200 ile döner ve payment.captured gönderilir.

Sağlayıcıyı seçme

Cüzdanda sağlayıcıyı alıcı seçer: WALLET satırında providerSelectionMode BUYER'dır. Platform alıcı adına cüzdan seçmez.

  • Tek cüzdan bağlıysa wallet.providerCode gönderilmesi gerekmez; o cüzdan kullanılır. Yöntem satırında providerSelection OPTIONAL'dır.
  • Birden fazla cüzdan bağlıysa WALLET satırının providers[] listesini (displayName, logoUrl) alıcıya gösterin ve seçtiği cüzdanın providerCode'unu wallet.providerCode ile gönderin. Yöntem satırında providerSelection REQUIRED'dır. Kodu göndermezseniz istek 400 payment.provider.required alır; bağlı kodlar details.boundProviderCodes içindedir.
  • Gönderdiğiniz kod hesabınızda bu yönteme bağlı değilse istek 422 payment.provider.not_available alır.
  • Seçilen cüzdan ödemeye sabitlenir: hata olursa başka cüzdana, başka yönteme ya da karta geçilmez.

Seçim modları ve providerSelection ile ilişkisi: Yöntemleri Listeleme › Sağlayıcı seçimi.

İstek

POST https://api-gateway.lunixi.com/api/v1/payments/direct/payment
Content-Type: application/json

İstek Step-Up kimlik doğrulaması (Bearer token ve Ed25519 imza başlıkları; bkz. Kimlik Doğrulama) ve zorunlu Idempotency-Key başlığı (en fazla 200 karakter) taşır; kurallar Payment — Idempotency ile aynıdır.

Yöntem alanları

AlanTipZorunluAçıklama
paymentMethodstringEvetWALLET
walletobjectEvetCüzdan bloğu; alanları aşağıdaki satırlardadır
wallet.providerCodestringBirden fazla cüzdan bağlıysaAlıcının seçtiği cüzdanın sağlayıcı kodu (GET /payments/methods); bkz. Sağlayıcıyı seçme
wallet.gsmNumberstringCüzdanın tanımı istiyorsaCüzdan hesabının telefonu; doğrulama kodu bu numaraya gider. Gönderilmezse buyer.gsmNumber kullanılır
wallet.<alan>—Tanıma göreCüzdanın inputFields tanımındaki diğer alanlar; bkz. Yöntem alanları. Tanımda olmayan alan gönderilemez
preauthbooleanHayırtrue: ön provizyon; seçilen cüzdanın desteklemesi gerekir. Bkz. Ön provizyon
callbackUrlstringHayırhttp ya da https, en fazla 2048 karakter. Sağlayıcı REDIRECT aksiyonu döndürürse alıcının tarayıcısı sonuçla bu adrese döner

Gövdede yalnız wallet bloğu bulunur: başka bir yöntemin bloğu ya da card, force3D, installment, installmentQuoteToken gönderilirse istek 400 VALIDATION_ERROR alır.

Sipariş alanları

AlanTipZorunluAçıklama
amountintegerEvetTutar, minor unit tam sayı; en az 1. Sepet toplamıdır: alıcının ödediği ürün ve hizmet bedeli, vade farkı hariç. basketItems gönderirseniz kalemlerin price toplamına eşit olmalıdır. Kartta taksit seçilirse vade farkını sistem ekler. Örnek: 10050
currencystring (enum)EvetISO 4217 kodu: TRY, USD, EUR, GBP, RUB, AED, SAR, QAR, KWD, JPY, CHF, CAD, AUD, CNY, AZN. Hesabınızda açık olmayan para birimi reddedilir
orderIdstringEvetSizin sipariş numaranız, en fazla 128 karakter. Örnek: ORD-84722
customerIdstringHayırSizin müşteri anahtarınız. Cüzdanla ödemede alıcıyı tanımlar; 3D Secure ile kart kaydında kart bu anahtarın altına yazılır. Örnek: cust_7788
descriptionstringHayırÖdeme açıklaması
localestringHayırMesaj dili, varsayılan tr
paymentChannelstringHayırÖdeme kanalı. Örnek: WEB
paymentGroupstringHayırÜrün grubu. Örnek: PRODUCT
buyerobjectHayırAlıcı bilgisi; bkz. buyer
shippingAddressobjectHayırTeslimat adresi; bkz. Adres
billingAddressobjectHayırFatura adresi; bkz. Adres
basketItemsarrayHayırSepet kalemleri; bkz. basketItems[]
metadataobjectHayırKendi kayıtlarınız için serbest anahtar-değer nesnesi. Ön provizyonu metadata ile değil preauth alanıyla isteyin

Tutar yalnız amount ile gönderilir; kaldırılan tutar alanları 400 payment.amount.field_removed alır. Tanımlı olmayan bir alan gönderirseniz istek 400 VALIDATION_ERROR ile reddedilir.

Cüzdanla ödemede customerId alıcıyı tanımlar ve işletmenin cüzdan programında önerilir; bkz. Alıcı kimliği. buyer.gsmNumber, wallet.gsmNumber gönderilmezse kullanılır.

buyer

buyer opsiyoneldir. Gönderirseniz aşağıdaki "Evet" alanlarının hepsi dolu olmalıdır. Checkout Formu intent'inde (POST /payments/intents, POST /payments/marketplace/intents) bu zorunluluk yoktur: alanların hepsi isteğe bağlıdır, gönderdiğiniz alanların tipi ve uzunluğu doğrulanır.

AlanTipZorunluÖrnek
idstringHayırCUST-1
namestringEvetAda
surnamestringEvetYılmaz
identityNumberstringEvet11111111111
emailstring (e-posta)Evet[email protected]
gsmNumberstringEvet+905000000000
citystringEvetİstanbul
countrystringEvetTurkey
zipCodestringEvet34732
ipstringEvetAlıcının IP adresi
registrationDatestringHayır2024-04-21 15:12:09
lastLoginDatestringHayır2026-10-05 12:43:35
registrationAddressstringHayırKayıtlı adres

Zorunluluk kuralı, customerId ile farkı ve hata alan yolları: Alıcı Bilgileri.

Adres

shippingAddress ve billingAddress aynı yapıdadır. Nesneyi gönderirseniz beş alan da zorunludur.

AlanTipÖrnek
contactNamestringAda Yılmaz
addressstringAltunizade Mah. …
citystringİstanbul
countrystringTurkey
zipCodestring34742

İki adresin farkı ve hata alan yolları: Adres Bilgileri.

basketItems[]

AlanTipZorunluAçıklama
idstringEvetKalem kodu
namestringEvetKalem adı
category1stringEvetAna kategori
category2stringHayırAlt kategori
itemTypestring (enum)EvetPHYSICAL ya da VIRTUAL
priceintegerEvetKalem tutarı, minor unit tam sayı, en az 0

Kalemlerin price toplamı amount'a eşit olmalıdır; eşit değilse istek 400 VALIDATION_ERROR ile reddedilir. Vade farkı kalemlere yazılmaz.

Örnek istek

# Step-Up imza başlıklarının nasıl hesaplandığı için Kimlik Doğrulama sayfasına bakın.
curl -X POST https://api-gateway.lunixi.com/api/v1/payments/direct/payment \
  -H "Authorization: Bearer at_test_5f3e2b1a..." \
  -H "Content-Type: application/json" \
  -H "X-Key-Id: mk_test_sk_..." \
  -H "X-Date: 2026-10-11T09:00:00.000Z" \
  -H "X-Nonce: 4a7e1c92-3b5d-4f60-8e2a-9c1d7b3e5f08" \
  -H "Digest: SHA-256=..." \
  -H "X-Signature: ..." \
  -H "Idempotency-Key: ORDER-1004-1" \
  -d '{
    "paymentMethod": "WALLET",
    "orderId": "ORDER-1004",
    "amount": 12500,
    "currency": "TRY",
    "customerId": "CUST-2",
    "wallet": { "providerCode": "<providerCode>", "gsmNumber": "+905321234567" }
  }'

<providerCode> bir yer tutucudur; cüzdanın kodunu GET /payments/methods yanıtından okuyun.

Alıcı kimliği

İşletmenizin cüzdan programıyla ödemede cüzdan iki bilgiyle bulunur:

  • customerId: Alıcıyı cüzdan programınızdaki müşteri kaydıyla eşler. Gönderdiğinizde telefon yalnız doğrulama için kullanılır; telefon o müşterinin kayıtlı numarasıyla eşleşmezse istek reddedilir.
  • wallet.gsmNumber: Telefon her durumda gereklidir. Doğrulama kodu bu numaraya gider; kod, ödeyen kişinin cüzdanın sahibi olduğunu kanıtlar. Alan gönderilmezse buyer.gsmNumber kullanılır. İkisi de yoksa ya da numaranın biçimi bozuksa istek 400 payment.method.block_invalid alır ve details.field wallet.gsmNumber olur.

Alıcının kimliği yalnız customerId alanından okunur. metadata.customerId tek başına gönderilirse ya da customerId'den farklıysa istek 400 payment.method.customer_identity_conflict alır.

Yanıt ve aksiyon

{
  "status": "partial",
  "code": "CUSTOMER_ACTION_REQUIRED",
  "message": "…",
  "data": {
    "paymentId": "3a8d5f1c-6b2e-4c9a-8e7d-1f0b2c3d4e5f",
    "orderId": "ORDER-1004",
    "status": "INITIATED",
    "paymentMethod": "WALLET",
    "providerCode": "<providerCode>",
    "action": {
      "id": "act_8e1f2a3b4c5d6e7f8091a2b3c4d5e6f7",
      "type": "OTP",
      "expiresAt": "2026-10-11T09:03:00.000Z",
      "otp": { "maskedTarget": "53****67" },
      "charge": {
        "amount": 12500,
        "feeTotal": 250,
        "taxTotal": 50,
        "buyerTotalCharge": 12800,
        "currency": "TRY"
      },
      "maskedBusinessName": "Ör*** Ma*****"
    }
  },
  "statusCode": 202,
  "requestId": "…"
}
AlanAçıklama
action.otp.maskedTargetKodun gönderildiği numaranın maskeli hâli. otp alanı yoksa kod istenmez; confirm'ü otp olmadan gönderin
action.chargeAlıcının ödeyeceği toplam ve kırılımı, minor unit. Ücret ya da vergi alıcıya yansıtılıyorsa buyerTotalCharge, sipariş tutarından (amount) büyüktür. Onaydan önce alıcıya buyerTotalCharge'ı gösterin
action.maskedBusinessNameÖdemenin gideceği işletmenin maskeli adı
action.stepUpRequiredYalnız true iken bulunur: cüzdan güçlü doğrulama istedi. Sizden ek girdi beklenmez

İşletmenizin cüzdan programıyla ödemede ödeme, kod onaylanana kadar INITIATED durumunda kalır.

Onay

{ "otp": "123456" }

POST /payments/{paymentId}/actions/{actionId}/confirm ile gönderin; kimlik doğrulama ve sonuç tablosu Payment — confirm ile aynıdır.

  • Yanlış kod 422 payment.action.input_rejected alır; aksiyon açık kalır ve kalan hak details.attemptsRemaining içindedir. İşletmenizin cüzdan programında hak 3'tür.
  • İşletmenizin cüzdan programında kod yeniden gönderilemez: resend 422 payment.action.resend_not_supported alır. Kodun süresi dolarsa yeni bir ödeme başlatın.

Sonuç

DurumYanıtNe yapmalı
Ödeme tamamlandı200, data.status CAPTUREDSiparişi payment.captured ile teslim edin
Cüzdan ödemeyi reddetti (bakiye, limit, doğrulama …)400 ya da 402, code payment.wallet_payment.*Para hareket etmedi. Alıcıya başka bir yöntem önerin
Onay gönderildi ama sonuç henüz kesinleşmedi409 payment.wallet_payment.not_settledSiparişi ödenmiş saymayın; aynı confirm isteğini kısa süre sonra tekrarlayın. Ödeme yerleşince aynı onay sonucu döner ve payment.captured gönderilir

İşletmenizin cüzdan programıyla ödemede:

  • Ret yanıtında data.status INITIATED kalabilir; para hareket etmemiştir ve payment.failed gönderilmez. Yeniden denemek için yeni bir Idempotency-Key ile yeni ödeme başlatın. Tamamlanmayan ödeme kaydı 24 saat sonra EXPIRED olur.
  • Aksiyonun süresi onay gönderilmeden dolarsa aksiyon kapanır, ödeme INITIATED kalır.

Sık görülen cüzdan kodları:

KodAnlamı
payment.wallet_payment.insufficient_balanceCüzdan bakiyesi yetersiz
payment.wallet_payment.limit_exceededCüzdan harcama limiti bu ödeme için yetersiz
payment.wallet_payment.kyc_insufficientCüzdanın kimlik doğrulama seviyesi bu ödeme için yetersiz
payment.wallet_payment.customer_not_matchedcustomerId ile eşleşen cüzdan bulunamadı
payment.wallet_payment.identity_mismatchTelefon, bu müşterinin cüzdanında kayıtlı numarayla eşleşmiyor
payment.wallet_payment.provider_unavailableSeçilen cüzdan hesabınızda kullanılabilir değil
payment.wallet_payment.rejectedCüzdan ödemeyi tamamlamadı; ayrıntı paylaşılmaz
payment.wallet_payment.not_settledOnay gönderildi, sonuç henüz kesinleşmedi

Ön provizyon

Bir cüzdanın ön provizyonu destekleyip desteklemediği GET /payments/methods yanıtındaki preauth alanındadır. Desteklemeyen cüzdanla preauth: true gönderilirse istek ödeme başlamadan 422 payment.preauth.unsupported_for_method alır. İşletmenizin cüzdan programı ön provizyonu desteklemez.

Hatalar

DurumYanıt
Birden fazla cüzdan bağlı, providerCode yok400 payment.provider.required
Seçilen cüzdan bağlı değil422 payment.provider.not_available
Telefon yok ya da biçimi bozuk400 payment.method.block_invalid
metadata.customerId ile customerId çelişiyor400 payment.method.customer_identity_conflict
Seçilen cüzdanın doğrulama akışı bu uçta desteklenmiyor422 payment.method.wallet_bridge_not_available
Ön provizyon desteklenmiyor422 payment.preauth.unsupported_for_method

Diğer kodlar: Payment — Hata kodları.

Webhook'lar

EventNe zaman
payment.capturedCüzdan ödemesi tamamlandı. Siparişi bunun üzerine teslim edin
payment.authorizedÖn provizyonlu ödemede tutar bloke edildi (AUTHORIZED); para henüz çekilmedi. Bkz. Ön Provizyon
payment.failedÖdeme başarısız oldu (işletmenin cüzdan programında ret, ödemeyi FAILED yapmaz)

Olayların data'sında paymentMethod: "WALLET" ve cüzdanın providerCode'u bulunur. Bkz. Webhook'lar.

Sonraki adımlar