İçeriğe geç
Muhammet Şafak
en
Soran: Sıla Cevaplandı:

Ödeme webhook'u aynı bildirimi tekrar gönderiyor; idempotency'i nasıl kurarım?


Soru

Üçüncü parti bir ödeme sağlayıcısından webhook alıyorum. Sağlayıcı ağ kesintileri nedeniyle aynı başarılı ödeme bildirimini birden çok kez (retries) gönderebiliyor. Sistemim mükerrer işlem (double-spending) yapmasın diye webhook endpoint'inde nasıl bir mimari kurmalıyım? İstekleri imzalama (HMAC) ve DB seviyesinde idempotency key takibi nasıl olmalı?

Cevap

Kısa cevap: Bunlar iki ayrı mesele — kimlik doğrulama (HMAC) ve mükerrerliği önleme (idempotency). İkisini karıştırma, ikisini de ayrı çöz.

Tek cümleyle: imza “bu gerçekten sağlayıcı mı”yı, idempotency “bu işi daha önce yaptım mı”yı sorar. Mimarini bu ayrım üzerine kur:

  1. İmzayı RAW body üzerinde doğrula. Sağlayıcının HMAC imzasını, parse etmeden önce ham gövde üzerinde, constant-time karşılaştırmayla kontrol et; tutmuyorsa hiçbir şeye güvenme, reddet. JSON’ı decode edip yeniden encode edersen imza bozulur — body’ye dokunmadan doğrula.
  2. Idempotency’i DB’ye yaptır. Provider’ın event id’sini (ya da hash’ini) UNIQUE constraint’li bir tabloda sakla; bir transaction içinde check-or-insert yap. Bir-kez garantisini uygulama mantığı değil, veritabanı verir — aynı id ikinci kez gelirse insert zaten patlar.
  3. Önce hızlı 200 dön, işi kuyruğa al. Webhook handler’ında ödeme yan etkilerini senkron çalıştırma; imzayı doğrula, kaydı al, hızlıca 200 dön ve asıl işi kuyruğa it. Worker aynı key üzerinde idempotent kalsın. Sağlayıcı timeout yiyip tekrar denemesin diye yanıt hızlı olmalı.
  4. Her katmanda iki-kez-çağrılmaya dayanıklı ol. Handler da, worker da, yan etki de aynı bildirimle iki kez çağrılınca tek bir net sonuç üretmeli. “Bir kere gelir” varsayımını hiçbir yere koyma.
  5. Sıralamayı ve replay penceresini gözet. “Refund” bildirimi “charge”dan önce gelebilir; out-of-order durumları handle et. Provider’ın replay/retry penceresini de bil ki eski bir bildirimi yeni sanıp tekrar işlemeyesin.

Sonuç: Ben olsam akışı imza doğrula → hızlı 200 → işi kuyruğa al diye kurar, idempotency’i event_id üzerindeki UNIQUE constraint + transaction’lı check-or-insert ile DB’ye yaptırırdım. HMAC’i ham body’de constant-time karşılaştır. Double-spending’i app kodu değil, veritabanının tekillik garantisi durdurur. Kuyruk tarafının operasyonel detayını hub yazısında bulursun.

İlgili Yazılar

Etiketler: #mimari#güvenlik#laravel
Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi