← Tüm case study'ler
Multi-Provider Orchestration Payment Heavy Architecture Fraud Detection
Case Study: Kurumsal Payment Gateway
Kapsam: Backend + Altyapı

Kurumsal Ödeme Gateway
Orchestration Sistemi

Stripe, Iyzico ve Adyen'i tek akıllı routing katmanı altında birleştiren; provider başarısızlıklarında otomatik failover, gerçek zamanlı fraud kararı ve idempotency garantisi sunan payment altyapısı.

1) Yönetici Özeti

Büyük bir e-ticaret holding, Avrupa ve Türkiye pazarlarında farklı ödeme sağlayıcılarıyla çalışmak zorundaydı. Tek provider kullanıldığında %100 kesinti riski, çoklu provider yönetiminde ise operasyonel karmaşa ve duplicate charge sorunu yaşanıyordu. Tüm sağlayıcıları soyutlayan, fail-safe tasarlanmış bir orchestration katmanı inşa ettik.

2) İş Hedefleri ve Başarı Kriterleri

Hedefler

  • Provider kesintilerinde sıfır kullanıcı etkisi
  • Tüm provider webhook'larını tek standart interface ile yönetmek
  • Fraud riskini gerçek zamanlı tespit ve bloke etmek
  • İşlem maliyetini akıllı routing ile optimize etmek

Başarı Kriterleri

  • Provider failure'da otomatik failover, kullanıcı fark etmez
  • Aynı ödeme isteği birden fazla kez gelse çift ücretlendirme sıfır
  • Fraud kararı <15ms — checkout UX bozulmasın
  • Tüm hare ketler audit log'da, geri izlenebilir

3) Sistem Mimarisi

API Gateway Layer

Rate limiting, JWT auth, request validation, idempotency key kontrolü.

Orchestration Core

Provider scoring, circuit breaker, smart routing, fraud pipeline entegrasyonu.

Data & Ops Layer

PostgreSQL ledger, Redis queue, BullMQ worker, audit log, Prometheus metrics.

4) Akıllı Provider Routing & Failover

Ödeme İsteği Provider Scoring Circuit Breaker Kontrol Ülke / Para Birimi Filtre Provider Seçimi Charge

Her provider sağlık skoru, başarı oranı, son 5 dakikalık hata sayısı ve işlem maliyetine göre dinamik olarak sıralanır. Provider yanıt vermezse bir sonrakine geçilir — kullanıcı sadece hafif bir gecikme fark eder, işlem tamamlanır.

Circuit Breaker Mantığı

  • 5 dakikada 3+ hata → provider devre dışı
  • 30 saniye sonra yarı-açık state: tek deneme
  • Başarılı → kapalı state, tamamen aktif
  • Redis'te durum tutulur, tüm instance'lar senkron

Maliyet Optimizasyonu

  • Her işlem için provider komisyon hesabı runtime'da
  • Düşük riskli işlemler → en ucuz sağlayıcı
  • Yüksek değerli → güvenilirlik öncelikli sıralama
  • %22 toplam işlem maliyeti düşüşü

5) Webhook Güvenliği

Her provider farklı imzalama yöntemi kullanır. Adapter pattern ile hepsi normalize edildi; güvenlik katmanı tüm provider'larda aynı:

HMAC-SHA256 Doğrulama Timestamp Replay Koruması (5dk) Event ID Deduplicate (Redis 24h) Normalize → Queue

6) Fraud Detection

Velocity Check

Redis ZADD sliding window: aynı kart/IP ile belirli sürede işlem sayısı. Lua script ile atomic.

Risk Scoring

BIN analizi (prepaid kart), geo-anomaly (billing ↔ IP uyumsuzluğu), hesap yaşı kombinasyonu.

Karar Katmanı

Skor <30 → geç; 30–70 → 3DS challenge; >70 → blok. Her karar audit log'a yazılır.

7) Redis & Fail-safe Tasarım

8) Idempotency

Ağ problemi nedeniyle aynı ödeme isteği birden fazla kez gelebilir. Çözüm:

X-Idempotency-Key zorunlu Redis SET NX EX 24h İşlem + Sonuç kayıt Retry → Cached sonuç döner

Redis erişilemez → DB idempotency_keys tablosu, unique constraint. Race condition yok, çift ücretlendirme imkânsız.

9) Operasyon & SLA

10) Sonuçlar

Metrik Öncesi Sonrası Yöntem
Ödeme başarı oranı %92.4 %98.8 Failover + retry mantığı
Duplicate charge Ayda 3–5 vaka 0 Idempotency engine
Fraud kayıp oranı Gelirin %0.6'sı %0.08 Real-time scoring
İşlem maliyeti Sabit tek provider %22 düşüş Akıllı provider routing
Provider kesinti süresi Tam kesinti Kullanıcı fark etmez Circuit breaker + fallback

11) Production Snapshot

Sistemin 90 günlük production ortalaması. Ölçümler Prometheus + Grafana ile alındı.

Metrik Değer Kapsam
Ortalama RPS 140 Hafta içi mesai saatleri
Peak RPS 380 Kampanya zamanları, 15:00–17:00 UTC
Günlük işlem adedi ~50.000 3 provider toplam
Günlük işlem hacmi ~€240.000 Ort. €4.8 / işlem
P95 latency 118ms Fraud scoring dahil, uçtan uca
P99 latency 210ms Circuit breaker timeout dahil değil
API Pod sayısı 4 HPA min:2 / max:8
Worker Pod sayısı 3 BullMQ concurrency: 12/pod
Redis Cluster 6 node (3 shard × primary+replica) AOF + RDB persistence
PostgreSQL 1 primary + 1 read replica Streaming replication, lag <200ms
Uptime (90 gün) %99.81 Planned maintenance hariç
Deployment modeli Blue / Green Zero-downtime, health check kapısı geçli

12) Incident Log

INC-001 — Iyzico Partial Outage (2024-09-14, 14:32 UTC)

  • Tetikleyen: Iyzico charge endpoint'i %43 oranında 503 dönmeye başladı
  • Tespit: Circuit breaker, 4 dakika içinde 5 hata eşiğini geçti → provider devre dışı
  • Failover süresi: 3.8 saniye (son hata → Stripe routing aktif)
  • Etkilenen işlem: 7 istek 503 aldı, tümü client'a retry önergesiyle HTTP 202 döndü
  • Kullanıcı etkisi: Görünmez — checkout tamamlandı, sadece sağlaycı değişti
  • Recovery: Iyzico 22 dk sonra stabilize oldu, half-open test başarılı, yeniden aktif
  • Kaybedilen işlem: 0
  • Sonraki aksiyon: Circuit breaker eşiği 5 → 3'e düşürüldü

INC-002 — Stripe Webhook Replay Storm (2024-11-03, 09:17 UTC)

  • Tetikleyen: Stripe tarafında geçici gecikme; aynı event'leri 3 dk içinde 847 kez gönderdi
  • Tespit: duplicate_event_rate alert — eşik 5/dk, gerçekleşen: 282/dk
  • Engelleme: Redis SET NX EX 86400 — 847 event'in 846'sı sessizce düşürüldü
  • Korunan işlem: 823 potansiyel duplicate charge tamamen engellendi
  • Redis durumu: Bu süreçte Redis stabil, NX kontrolü ortalama 0.9ms
  • Kullanıcı etkisi: Sıfır — hiçbir aboneye fazla ücretlen dirme yapılmadı
  • Kaybedilen işlem: 0
  • Sonraki aksiyon: Duplicate alert eşiği refinement, Stripe retry policy dokümantasyonu eklendi

13) Observability & Alerting

Prometheus Metric Listesi

  • payment_requests_total{provider, status}
  • payment_success_rate{provider} — gauge, 60s window
  • provider_latency_p95{provider} — histogram
  • fraud_block_rate — blocked / total, 5m window
  • duplicate_event_rate{source} — counter
  • idempotency_hit_ratio — cache hit / (hit+miss)
  • circuit_breaker_state{provider} — 0=closed 1=half 2=open
  • redis_command_latency_p99{command}
  • worker_queue_depth{queue_name}
  • provider_score{provider} — routing ağırlık skörü

Alert Eşikleri

Alert Koşul Severity
payment_success_rate < 0.92 5dk P1
circuit_breaker_state = 2 Anlık P1
provider_latency_p95 > 800ms 3dk P2
fraud_block_rate > 0.08 5dk P2
duplicate_event_rate > 5/dk 1dk P2
worker_queue_depth > 500 2dk P2
redis_command_latency_p99 > 20ms 2dk P3

Fraud spike: fraud_block_rate önceki 30dk ortalamasının 3 katını aşarsa anomaly alert üretilir, otomatik 3DS zorlama aktif olur.

14) Security Hardening

  • SSRF: Tüm outbound çağrılar whitelist tablosuyla doğrulanır. RFC-1918 adreslere istek engellenir, DNS rebinding korunur.
  • Replay Attack: Webhook timestamp ±5dk penceresiyle kontrol edilir. Geçmiş event ID Redis'te 24 saat tutulur.
  • JWT Rotation: Access token TTL: 15dk. Refresh token: 7 gün, tek kullanımlık. Kullanılan refresh token Redis'te invalidate edilir.
  • Refresh Token Revocation: Logout veya şüpheli aktivite → tüm token ailesi Redis'ten temizlenir, DB'de revoked flag.
  • Secrets Management: Ortam değişkenleri Kubernetes Secret ile inject edilir. Prod'ında Vault ile dinamik credential rotation uygulandı.
  • CSRF: Cookie oturumu yok. Stateless JWT, CSRF saldırısı anlamsız. Payment endpoint'leri HTTP-only Bearer ile korunur.
  • Sensitive Log Masking: Kart numarası, CVV, IBAN logger middleware'de regex ile maskeler. PAN son 4 hane görünür, gerisi yıldız.
  • Rate Limiting: IP + user_id kombinasyonu üzerinde Redis sliding window. Burst limit 20 req/10sn.
  • SQL Injection: Tüm sorgular parameterized (Prisma ORM). Ham SQL kullanılmıyor.
  • Dependency Audit: CI/CD pipeline'da npm audit --audit-level=high zorunlu. Critical CVE → deploy bloke.

15) Redis Unavailable — Derinlemesine Senaryo

Redis tamamen erişilemez olduğunda sistem hiçbir kritik fonksiyonu durdurmuyor. Her katman kendi fallback'ini biliyor.

  • Distributed Lock fallback: Redis SET NX başarısız → PostgreSQL SELECT FOR UPDATE SKIP LOCKED ile advisory lock. Performans düşer, doğruluk korunur.
  • Idempotency fallback: Redis miss → DB idempotency_keys tablosu, UNIQUE(key) constraint. İki eşzamanlı istek gelirse biri UniqueConstraintError alır, retry sonucu döner.
  • Fraud velocity degrade: Redis ZADD erişilemez → mevcut oturumda fraud check bypass değil, DB'den son 1 saatin kart transaction sayısı sorgulanır (daha yavaş, aynı karar).
  • Circuit breaker state: Redis hash erişilemez → her pod kendi in-memory durumunu tutar. Cluster genelinde senkron bozulur ama lokal circuit breaker korunur. Recover olunca Redis otomatik heartbeat ile yeniden senkronize edilir.
  • Rate limit soft-disable: Redis down → rate limiting geçici olarak devre dışı, log'a WARN: rate_limit_degraded yazılır, PagerDuty P3 alert tetiklenir. Kötüye kullanım riski kabul edilir, servis kesilmez.
  • BullMQ persistent mode: Redis cluster down → BullMQ, DB-backed fallback queue'a geçer. Dunning ve webhook işlemleri gecikmeli ama kayıpsız tamamlanır.

16) Payment Heavy Production Proof

Bu sistem production'da çalıştırılmış, aşağıdaki maddeler gözlemlenmiş veya test edilmiş davranışlardır.

Idempotency Yaklaşımı

  • Her işlem isteği X-Idempotency-Key headerı zorunlu kılar
  • Redis SET NX EX 86400 ile ilk yazma atomik
  • İlk yazma başarılı → işlem ve sonuç birlikte cache'e alınır
  • Sonraki aynı key → provider'a hiç gidilmez, cache sonucu döner
  • Redis down → PostgreSQL unique constraint fallback, race condition yok

Duplicate Webhook Handling

  • Her webhook event ID normalize edilip Redis'e yazılır
  • Duplicate gelirse SET NX false döner → sessiz skip, HTTP 200
  • INC-002'de 847 event'ten 846'sı bu katmanda engellendi
  • Timestamp penceresi (5dk) ile gecikmiş replay da bloke edilir
  • HMAC-SHA256 başarısız → event işlenmez, 401 log

Redis Down Davranışı

  • Circuit breaker: in-memory fallback, senkron kaybı kabul edilir
  • Idempotency: DB unique constraint, yazma atomik kalır
  • Fraud velocity: DB sorgu fallback, aynı karar mantığı, daha yavaş
  • Rate limit: soft-disable, P3 alert, servis kesilmez
  • BullMQ: DB-backed queue, işler gecikmeli ama kaybsız tamamlanır

SLA & Devir

  • P1 (duplicate charge, provider tam arıza): <1 saat müdahale
  • P2 (fraud spike, latency artışı): <4 saat müdahale
  • Tüm runbook'lar Notion'da, yeni ekip üyesi bağımsız okuyabilir
  • Infrastructure as Code (Terraform), ortam yeniden kurulabilir
  • Testler: %74 branch coverage, kritik ödeme yolları %100

17) Architecture Topology Overview

Trafik, soldan sağa katmanlar üzerinden akar. Her katman kendi sorumluluğunu taşır.

Load Balancer
NGINX / ALB
TLS termination
Rate limit ilk katman
API Pods ×4
Node.js stateless
JWT auth, routing
Fraud scoring
Redis Cluster
3 shard × primary+replica
Idempotency, CB state
Fraud velocity, queues
PostgreSQL
Primary + read replica
Ledger, audit log
Idempotency fallback
Worker Pods ×3
BullMQ consumers
Webhook processing
Notification queue
Providers
Stripe / Iyzico / Adyen
Circuit breaker korumalı
HMAC-signed webhooks

Webhook trafiği ters yönde: Provider → Load Balancer → API Pods (HMAC doğrulama) → Redis Queue → Worker Pods → PostgreSQL ledger.

Kaynak Kodu Hakkında

Bu projeye ait kaynak kodlar, müşteri ile imzalanan gizlilik sözleşmesi (NDA) kapsamında paylaşılamamaktadır. Teknik yapı, mimari kararlar ve implementasyon detayları hakkında sorularınızı doğrudan iletebilirsiniz; müsait olanı kapsamında yanıtlayırız.