Testing Declines
Sandbox decline, provider error, retry/fallback ve normalized error modelini test etme rehberi.
Entegrasyonun kalitesi başarılı ödemede değil, reddedildiğinde ne yaptığınızda belli olur. Sandbox’ta decline ve timeout’u bilinçli tetikleyip UI, webhook ve state haritanızı önceden oturtun.
Production’da ilk gerçek hard decline’da panik yaşamamak için bu senaryoları canlıya çıkmadan bitirin.
Neden Decline Test Etmelisiniz?
Ödeme sistemlerinde sadece successful payment test etmek yeterli değildir. Gerçek ürün kalitesi invalid card, insufficient funds, issuer unavailable, provider timeout, 3DS failed, suspected fraud, duplicate request, expired card, hard decline, soft decline ve retryable/non-retryable hata davranışlarını doğru handle etmekle ölçülür.
HSRC Pay'in normalized error modeli provider kaosunu merchant için okunabilir hale getirir.
Hard Decline ve Soft Decline Farkı
| Decline type | Anlam | Merchant davranışı |
|---|---|---|
| Hard decline | Aynı ödeme yöntemiyle tekrar denemek doğru değildir | Retry etmeyin, kullanıcıdan farklı ödeme yöntemi isteyin |
| Soft decline | Geçici durum veya farklı route ile düzelebilecek hata | Uygunsa fallback/retry, status check veya daha sonra tekrar deneyin |
| Unknown | Sonuç kesin değil veya provider cevabı belirsiz | Idempotency ve status query ile dikkatli ilerleyin |
Hata kodları (public özet)
Confirm orchestrator özetinde errCode string olarak gelir; decline’ta ek olarak hard / soft ayrımı vardır. Sık görülen kodlar:
| Kod | Genelde |
|---|---|
invalid_payment_method | Kart/yöntem geçersiz (hard) |
invalid_currency | Para birimi uyumsuz (hard) |
invalid_credentials / invalid_api_key | Sağlayıcı yapılandırması (hard) |
system_proxy_timeout | Geçici; status check (soft) |
system_network_other / system_network_econnreset | Geçici ağ (soft) |
system_no_provider_strategy_available_for_routing_plan | Routing/config (hard) |
system_unknown | Belirsiz; dikkatli ilerle |
Ham sağlayıcı mesajını kullanıcıya göstermeyin; errCode ve decline tipine göre sadeleştirin.
Sandbox'ta Expected Error Simülasyonu
Sandbox scenario configuration ile belirli sonuç üretilebilir. Eğer entegrasyonunuzda bu alan farklı isimle expose ediliyorsa aynı mental model geçerlidir: explicit sandbox configuration provider veya normalized error sonucu üretir; sandbox kart numaraları üretmez.
{
"amount": 12500,
"currency": "TRY",
"payment_method": "pm_sandbox_card",
"sandbox": {
"expectedErr": "system_unknown"
}
}{
"kind": "declined",
"errCode": "system_unknown",
"errMsg": "Felix Sandbox: Simulation of system_unknown",
"type": "hard",
"providerRef": "sandbox_provider_ref",
"traceId": "trace_sandbox_123"
}Kart Validasyon Decline'ı
Sandbox kartları spesifik decline sebebi simüle etmez. Bir sandbox kart numarası insufficient funds, expired card, invalid account, stolen card, issuer unavailable veya başka bir issuer-specific response anlamına gelmez.
Kart listesine bağlı tek decline davranışı validasyondur: card payment method sandbox kart allowlist'iyle eşleşmezse sandbox provider Invalid sandbox test card mesajıyla invalid_payment_method döndürür.
Açık hata simülasyonu için kart numarası değil expectedSandboxErr veya provider-specific sandbox configuration kullanın.
Provider Bazlı Decline Senaryoları
Provider simulation şunları test edebilir:
- Provider timeout
- Provider maintenance/unavailable
- Unsupported operation
- Invalid credential configuration
- Mapping failure veya unknown provider result
Merchant raw provider error'a güvenmemeli; normalized error modeline göre davranmalıdır.
3DS Failure Senaryoları
3DS challenge iptal edilir, süresi dolar veya başarısız tamamlanırsa result decline olabilir. Bu durumda kullanıcıya challenge'ı tekrar başlatma veya farklı ödeme yöntemi seçme yolu verilmelidir.
Retry ve fallback
- Hard: Yeni ödeme yöntemi isteyin; aynı kartla otomatik döngü yapmayın.
- Soft: Sıradaki sağlayıcı adayı veya kontrollü yeniden confirm; önce
GET /payments/:id?include_charges=true. - Belirsiz timeout: Yeni payment açmadan mevcut kaydı ve webhook loglarını kontrol edin.
Webhook/Event Handling
Decline veya retry sürecinde birden fazla event gelebilir. Merchant webhook handler:
- Idempotent olmalıdır.
- Payment state transition'larını sıralı yorumlamalıdır.
- Unknown/timeout durumunda status check yapmalıdır.
- UI mesajını raw provider string yerine normalized error'a göre üretmelidir.
Örnek Test Matrix
| Senaryo | Normalized Error | Decline Type | Retry/Fallback | Merchant UI Mesajı | Webhook Beklentisi |
|---|---|---|---|---|---|
| Invalid card/payment method | invalid_payment_method | hard | Retry yok | Kart bilgilerini kontrol edin | payment.requires_payment_method / charge declined |
| Stolen payment method | stolen_payment_method | hard | Retry yok | Farklı ödeme yöntemi isteyin | charge declined |
| Invalid currency | invalid_currency | hard | Konfigürasyonu düzeltin | Para birimi desteklenmiyor | failed/declined event |
| Invalid API key | invalid_api_key | hard | Provider config düzeltme | Provider bağlantısı yapılandırılamadı | failed event |
| Invalid credentials | invalid_credentials | hard | Provider config düzeltme | Provider bilgileri geçersiz | failed event |
| Proxy connection failed | system_proxy_conn_failed | soft | Fallback/retry denenebilir | Provider bağlantısı kurulamadı | retry/fallback trace |
| Proxy auth failed | system_proxy_auth_failed | hard | Proxy config düzeltme | Provider bağlantısı yapılandırılamadı | failed event |
| Proxy timeout | system_proxy_timeout | soft | Status check | İşlem kontrol ediliyor | payment.processing veya güncelleme |
| Network other | system_network_other | soft | Fallback/retry denenebilir | Geçici ağ sorunu | retry/fallback trace |
| Network ECONNRESET | system_network_econnreset | soft | Fallback/retry denenebilir | Geçici ağ sorunu | retry/fallback trace |
| Max retry exceeded | system_candidate_processor_max_retry_exceeded | soft | Yeni route/status kontrolü | İşlem tekrar denemeleri tamamlandı | failed/updated event |
| No provider config for plan | system_no_provider_strategy_available_for_routing_plan | hard | Routing/provider config düzeltme | Uygun provider bulunamadı (API hata kodu; ürün adımı "strategy execution" değil) | failed event |
| System unknown | system_unknown | soft veya hard | Dikkatli retry/status check | İşlem durumu kontrol ediliyor | updated veya failed |
Best Practices
- Success, hard decline, soft decline, timeout ve 3DS failed senaryolarını ayrı ayrı test edin.
- Retry kararını raw message'a göre değil
typeve normalized error'a göre verin. - Idempotency key kullanın.
- Webhook handler'ı duplicate delivery için dayanıklı yapın.
- Fallback denemelerini trace edin.
- Kullanıcı mesajlarını teknik provider mesajlarından ayırın.
Sık Hatalar
- Her decline sonucunu aynı UI mesajıyla göstermek.
- Hard decline sonrası aynı kartla otomatik retry yapmak.
- Timeout sonrası ödeme başarısız sanıp hemen yeni ödeme oluşturmak.
- Webhook duplicate delivery'yi hata kabul etmek.
- Production provider error mapping'ini sandbox'ta test etmemek.