Müşteri bankanın 3D Secure sayfasını tamamladığında banka, sonucu Poyra’nın geri dönüş ucuna gönderir:
Sonucu form POST’uyla değil tarayıcıyı sorgu dizesiyle yönlendirerek bildiren sağlayıcılar (Lidio) için aynı uç GET isteğini de kabul eder; işleyiş aynıdır. Bu uç kimliksizdir — bankalar API anahtarı taşımaz. İşyeri, adresteki geri dönüş belirtecinden çözülür: confirm sırasında her deneme için üretilen, 256 bit rastgelelikte, 30 dakika ömürlü ve tek kullanımlık bir değer.

Dönüş nasıl işlenir

Sıra önemlidir:
  1. Çift POST zararsızdır. Belirteç daha önce kullanılmışsa mevcut durum döner; banka aynı sonucu iki kez gönderdiğinde ikinci istek hiçbir şeyi değiştirmez. Yakalanan bir isteğin yeniden oynatılması da aynı nedenle sonuçsuz kalır.
  2. Form + query birleştirilir, form öncelikli — bazı protokoller (ör. VakıfBank PayFlex) sonucu GET query’siyle döndürür.
  3. Konnektörün başlatma sırasında sakladığı gizli durum (örneğin Adyen’in ödeme bağlantısı kimliği) forma harmanlanır; çakışmada bankanın gönderdiği alan kazanır.
  4. Sipariş eşleşmesi: dönüşteki sipariş numarası, denemenin kimliğiyle (att_…) birebir aynı olmalıdır. Değilse 400 callback.order_mismatch — imzası geçerli ama başka bir siparişe ait bir dönüş kabul edilmez.

İmza doğrulama protokole göre değişir

Her konnektör dönüşü kendi yöntemiyle doğrular; iki ana ailesi vardır: Yerel imza doğrulaması — dönüşteki alanlardan hash yeniden hesaplanır ve sabit-zamanlı karşılaştırmayla denetlenir: Sunucu sorgusu — dönüşteki alanlara güvenilmez, sonuç bankaya/sağlayıcıya sorulur: Sunucu bildirimi — üçüncü bir yol: PayTR’da sonuç, müşterinin tarayıcısı üzerinden değil, sağlayıcının Poyra’ya yaptığı imzalı bildirimle gelir. Bildirim ucu düz metin OK döndürmezse PayTR göndermeyi tekrarlar; tarayıcı dönüşü hiçbir koşulda kanıt sayılmaz.
Hangi ailede olursa olsun sonuç ikilidir: doğrulanmış başarı ya da birleşik hata koduna eşlenmiş red. İmzası tutmayan dönüş, içeriği ne derse desin başarı sayılmaz.

İmzanın yokluğu da reddedilir (fail closed)

Bir doğrulama denetimi “imza var ama tutmuyorsa reddet” biçiminde yazılırsa, imza alanını hiç göndermeyen bir dönüş denetimi tamamen atlar. Bu, InterVPOS adaptöründe gerçekten böyleydi; Kuveyt Türk’te ise hiç imza doğrulaması yoktu. Callback adresi tek kullanımlık 256 bit belirteç taşıdığı için rastgele biri o adrese erişemiyordu — ama ödemeyi yapan müşteri o adresi kendi tarayıcısında görüyordu: bankaya hiç para göndermeden siparişini ödenmiş gösterebilirdi. Bugün her konnektörde imzanın yokluğu da reddedilir ve doğrulanacak dönüş imzası bulunmayan protokollerde (BOA ailesi) tarayıcı dönüşü tek başına asla başarı sayılmaz. Kural, konnektörlerin tek tek testleriyle değil, tüm konnektörleri kendiliğinden kapsayan konnektör uyum kitiyle zorlanır: “boş ya da kurcalanmış dönüş kabul edilmemeli” teorisi her yeni banka için otomatik koşar.

Sonucun yazılması

Doğrulama olumluysa deneme captured, intent succeeded olur; payment.succeeded olayı deftere düşer ve webhook kuyruğa girer. Olumsuzsa birleşik hata kodu ve bankanın ham kodu denemeye yazılır, intent failed olur. Her iki durumda da webhook tesliminin gecikmesini düşürmek için kuyruk anında dürtülür; dakikalık süpürücü zaten güvencedir — ayrıntı Webhook’lar sayfasında. Son adım müşteriyi return_url’e taşımaktır:
Query’deki durum yalnızca kolaylıktır; sonuç sayfası gerçeği her zaman defterden okur.

Müşteri hiç dönmezse: 3DS zaman aşımı

Müşteri banka sayfasını kapatabilir, SMS beklerken vazgeçebilir, banka hiç dönüş göndermeyebilir. Ödeme sonsuza dek requires_action’da kalmasın diye beş dakikada bir çalışan bir iş, süresi dolmuş ve kullanılmamış belirteçleri tarar:
  1. Belirteç kullanılmış işaretlenir — bundan sonra çok geç gelen banka dönüşü 410 alır; durum makinesi tutarlı kalır.
  2. Deneme three_ds_timeout koduyla failed, intent failed yapılır.
  3. payment.failed olayı ve webhook’u üretilir.
Belirtecin 30 dakikalık ömrüne beş dakika da tolerans eklenir: sınırda tamamlanan bir 3DS, zaman aşımı işiyle yarışmaz.

Kart bizde toplanıp 3DS bankada yapılan akış

Posnet OOS gibi protokollerde kart veriniz Poyra üzerinden bankaya iletilir, ama doğrulama yine bankanın sayfasında olur (confirm-direct + useThreeDs=true). Banka formuna kart verisi yazılmaz — yalnızca bankanın ürettiği imzalı paket taşınır. Dönüş, bu sayfadaki akışın aynısıyla işlenir; tek fark başlangıçta kartın sizden gelmiş olmasıdır. Bu akış Posnet’e özgü değildir: yurt içi ödeme kuruluşlarının çoğu (İyzico, Moka, Payten, CCPayment, Tami, ParamPos, AHL Pay, PayTR) banka-hosted kart girişi sunmaz ve tek 3DS seçeneği budur — tam listesi banka adaptörleri sayfasındadır. PCI kapsamına girer, bu yüzden sertifikasyon tamamlanana dek yalnız test/sandbox kimlikleriyle kullanılmalıdır.