3D Secure akışı
Bankalar 3D doğrulamasını farklı biçimlerde yürütür. Biz bunu tek bir nextAction sözleşmesine indirger; siz yalnızca müşteriyi yönlendirirsiniz.
Akış
- Sunucunuz
POST /v1/paymentsçağırır. Yanıtstatus: "requires_action"venextActioniçerir. - Sunucunuz
nextAction'ı tarayıcıya iletir; tarayıcı kullanıcıyı bankanın doğrulama sayfasına gönderir. - Müşteri doğrulamayı tamamlar; banka müşteriyi bizim callback adresimize döndürür. Sonucu biz doğrular (imza/MAC kontrolü), gerekiyorsa provizyonu tamamlarız.
- Müşteri
returnUrl'e yönlendirilir. Ödemenin son durumunu sunucunuzdan okuyun (GET /v1/payments/{id}) ya da webhook'u bekleyin.
nextAction türleri
| kind | Ne yapılır | Alanlar |
|---|---|---|
form | Tarayıcıda action adresine method ile fields içeriğini gönderen bir form otomatik submit edilir. | action, method, fields |
redirect | Tarayıcı verilen adrese yönlendirilir. Bankanın HTML sayfası sunan sağlayıcılarda bu adres bizim tek kullanımlık sayfamızdır. | url |
nextAction'ı uygulama
// nextAction: API yanıtındaki payment.nextAction (sunucunuz tarayıcıya iletir)
function continue3DS(next) {
if (next.kind === "form") {
const f = document.createElement("form");
f.method = next.method || "POST";
f.action = next.action;
for (const [k, v] of Object.entries(next.fields || {})) {
const i = document.createElement("input");
i.type = "hidden"; i.name = k; i.value = v;
f.appendChild(i);
}
document.body.appendChild(f);
f.submit();
} else {
window.location.assign(next.url); // "redirect" ve "html" türleri
}
}returnUrl parametrelerine güvenmeyin
Müşteri returnUrl'e ?paymentId=…&status=…&orderId=… ile döner. Bu değerleri tarayıcı taşıdığı için kullanıcı değiştirebilir; siparişi onaylamadan önce mutlaka ödemeyi API'den okuyun veya imzalı webhook'u esas alın.
3D sonuç durumları
| Durum | Anlamı |
|---|---|
captured | Doğrulama ve provizyon başarılı; ödeme tahsil edildi. |
authorized | Ön provizyon (kind=preauth) alındı; kapatılmayı bekliyor. |
declined | Doğrulama başarısız (error.kind = 3ds_failed) ya da banka provizyonu reddetti. |
pending | Sonuç doğrulanıyor; arka planda bankada sorgulanır. Webhook ile kesinleşir. |
failed | Müşteri 30 dakika içinde dönmediyse error.kind = expired ile kapatılır. |
Callback güvenliği
- Callback adresi ödemeye özel, tahmin edilemez bir jeton içerir; jeton yalnızca özet halinde saklanır.
- Aynı callback tekrar (yenileme, çift gönderim) gelse de banka çağrısı bir kez yapılır; ikinci istek mevcut sonucu döndürür.
- Banka imzaları (hash/MAC) sağlayıcı bazında doğrulanır; imza geçersizse ödeme reddedilir.
- Kartı 3D dönüşünden sonra gerektiren sağlayıcılarda kart, yalnızca bu ödeme için şifreli ve tek kullanımlık saklanır; callback sahiplenildiği anda silinir.
Örnek yanıtlar
kind: form
"nextAction": {
"type": "three_ds",
"kind": "form",
"method": "POST",
"action": "https://sanalposprov.garanti.com.tr/servlet/gt3dengine",
"fields": { "mode": "TEST", "terminalid": "...", "secure3dhash": "..." }
}kind: redirect
"nextAction": {
"type": "three_ds",
"kind": "redirect",
"url": "https://api.paymentgateway.com.tr/v1/3ds/start/pay_01J.../a1b2c3..."
}Kart bilgisi toplamak istemiyorsanız hazır ödeme sayfası bu akışın tamamını sizin yerinize yürütür.