Ödeme Sonucu — POST /plugin-api/payments/{paymentId}/result ⏳ Yakında

Sağlayıcının cihazdaki uygulaması tahsilat sonucunu (ve isterse ilerlemesini) buradan bildirir. Kimlik, tutarı çekerken kullandığı cihaz oturum JWT'sinin aynısıdır. Gövde, sağlayıcının ürettiği nexo SaleToPOIResponse'ın tamamıdır — kasaya senkron dönen gövdenin AYNISI.

← API Uçları · Tutarı çekme: payments/{id} · Cihaz kaydı: connectors/* · Uygulamanız nasıl çağrılır: cihaz taşıması.

⚠️ PRODUCTION'a HENÜZ DAĞITILMADI — yalnız dev ortamında var. Prod'da deneyip 401 alırsan bunu "yetkim yok" diye okuma: bu yüzeyde tanınmayan bir yol da kimlik katmanına düşer, yani 401 "uç yok"un da cevabıdır.

Ölçüm: gövdeler dev'de gerçek HTTP çağrılarıyla yakalandı (uçtan uca 51/51). Ayrıca sözleşme, bağımsız bir uygulama (Windows ajanı) tarafından da uygulanıp test edildi.

İstek

POST https://plugins-3y3x7nqe5a-ew.a.run.app/plugin-api/payments/{paymentId}/result
Authorization: Bearer <CİHAZ OTURUM JWT>     // GET ucuyla AYNI kimlik, install API key DEĞİL

<sağlayıcının ürettiği nexo SaleToPOIResponse'ın TAMAMI>
TEK KANONİK GÖVDE — iki ayrı şekil üretme. Ürettiğin SaleToPOIResponse hem kasaya senkron döner hem buraya bildirim olarak gelir. İki ayrı şekil üretirsen ıraksarlar, ve ıraksadıkları gün kasiyerin gördüğü sonuç ile deftere yazılan sonuç farklı olur. Aynı nesneyi iki yere gönder.

Yanıt

// kesin sonuç kaydedildi
{ "success": true, "data": { "recorded": true, "state": "APPROVED" } }

// ilerleme bildirimi kaydedildi
{ "success": true, "data": { "recorded": true, "state": "WAITING_CUSTOMER" } }

// BAYAT / TEKRAR — hata DEĞİL, retry ETME
{ "success": true, "data": { "recorded": false, "reason": "stale" } }
recorded:false HATA DEĞİLDİR — retry ETME. Bayat ya da tekrarlanmış bir bildirim demektir. Teslim at-least-once'tır, yani aynı bildirimin tekrarı normaldir; tekrar göndermek durumu değiştirmez.

Kesin sonuç DEĞİŞTİRİLEMEZ

İlk kesin sonuç kazanır. approved yazıldıktan sonra declined göndermek 409 plugin.payment.conflictingResult + alarm üretir. Sonucu "düzeltmek" için ikinci bir bildirim gönderme; gerçekten yanlışsa bu bir iade/ters kayıt işidir, bildirim işi değil.

URL ↔ gövde kimliği eşleşmeli

URL'deki paymentId ile gövdedeki SaleTransactionID.TransactionID aynı olmalı; değilse 409 plugin.payment.paymentIdMismatch.

Neden şart: eşleşme aranmasaydı bir cihaz, kendi ödemesinin URL'iyle başka bir ödemenin sonucunu yazdırabilirdi. Kapı bunu engelliyor.

⚠️ Tanınmayan ErrorCondition "reddedildi" SAYILMAZ

Bu, bu sayfadaki en pahalı hata. declined kesin bir durumdur: kasiyeri yeni denemeye iter. İlk işlem gerçekte geçmişse ikinci kez kart çekilir. Bu yüzden emin olmadığın hiçbir şeyi "reddedildi" diye bildirme.
SınıfErrorCondition
Kesin RETRefusal · InvalidCard · WrongPIN · PaymentRestriction
Kesin İPTALCancel · Aborted
BELİRSİZYukarıdakiler dışındaki her şey — tanınmayan değerler dahil

Belirsiz sonuç bir başarısızlık değildir; "ne olduğunu bilmiyoruz" demektir ve mutabakat bunu ayrıca ele alır. Emin olmadığında belirsiz bırak.

Alanlar: ne saklanır, ne saklanmaz

  • AdditionalResponse deftere YAZILMAZ. nexo'da serbest metindir — Türkçe yazabilirsin, zararı yok ama saklanmaz.
  • Makine kodunu ErrorCondition'a koy. Platform onu providerResultCode olarak saklar ve operatörün "neden belirsiz kaldı?" sorusu ancak onunla cevaplanabiliyor. Serbest metne gömersen o cevap kaybolur.
Ham PAN gönderirsen sonuç REDDEDİLİR — 400 plugin.payment.invalidCardLast4. MaskedPan ya maskeleme işareti taşımalı ya da ≤4 hane olmalı.

Kırpma yapılmıyor, bilerek: kırpmak ihlali görünmez kılardı — kart verisi sisteme girmiş ama kimse fark etmemiş olurdu. Kapı rakam sayısına bakıyor; boşluklu, tireli, noktalı ya da önekli PAN'lar da yakalanıyor.

İlerleme bildirimi (opsiyonel)

// İlerleme bildirimi — top-level EventNotification
{ "EventNotification": {
    "SaleData": { "SaleTransactionID": { "TransactionID": "pay_…" } },
    "EventToNotify": "WaitingForCard"
} }
  • Değerler: SentToTerminal · WaitingForCard · WaitingCustomer · Processing.
  • ⚠️ Bunlar nexo'nun resmî enum'u DEĞİLDİR — platformun tanımladığı bir sapmadır. nexo dokümanında aramayın.
  • Tanınmayan olay sessizce düşer (hata almazsınız).
  • İlerleme YALNIZ platforma gider. Kasaya senkron dönen yanıt daima PaymentResponse'tur — kasaya ilerleme göndermeyin.

Hatalar

HTTPmessageAnlamı
400plugin.payment.invalidCardLast4Ham PAN gönderildi.
400plugin.payment.approvedAmountRequiredOnayda tutar bildirilmedi.
400plugin.payment.invalidStatusTanınmayan/geçersiz sonuç durumu.
404plugin.payment.notFoundBilinmeyen ödeme VEYA bu cihazın/sağlayıcının değil (ayrım bilinçli yapılmaz).
409plugin.payment.paymentIdMismatchURL ↔ gövde kimliği uyuşmuyor.
409plugin.payment.amountExceedsRequestedİstenenden fazla onay — kaydedilmedi, alarm üretildi.
409plugin.payment.conflictingResultKesin sonucu değiştirme denemesi.
409plugin.payment.currencyMismatchPara birimi uyuşmuyor.
429plugin.rateLimitedHız sınırı.
Result: "Partial" desteklenmiyor (kısmi onay v1'de kapalı). Yine de gönderirsen deneme belirsiz işaretlenir — çünkü kısmi bir çekim gerçekleşmiş olabilir ve "başarısız" demek o parayı görünmez kılardı.