Türkiye'de neden önce İyzico?
Yurt dışı ödeme sağlayıcıları her use case için uygun değildir. Türkiye'de şirket yapısı, sözleşme süreci, 3DS zorunluluğu ve müşterinin kart alışkanlığı farklıdır. Stripe deneyimine alışkın ekipler için İyzico paneli ve akışları ilk bakışta daha az “pürüzsüz” gelebilir; ancak yerel merchant hesabı, TL faturalandırma ve regülasyon uyumu açısından çoğu Türkiye odaklı ürün için gerçekçi seçenek burada kalır. Etkinlik biletleme, abonelik tabanlı SaaS veya pazar yeri checkout'u gibi farklı modellerde de aynı sağlayıcıyla çalışmak mümkündür — fark, entegrasyon derinliği ve operasyonel disiplindedir.
SDK'yı bağlamak yeterli değil
Entegrasyonun asıl zorluğu checkout formunu açmakta değil, ödeme yaşam döngüsünün geri kalanında ortaya çıkar. Kullanıcı kart reddedildiğinde ne görür? 3DS adımında sayfadan ayrılıp geri döndüğünde sipariş hâlâ onun mu? Webhook birkaç saniye — bazen dakika — gecikirse arayüz “tamamlandı” mı der, yoksa “işleniyor” mu? İade veya iptal talebi geldiğinde stok, bilet veya abonelik durumu otomatik güncellenir mi? Bu sorulara cevap vermeden canlıya çıkmak, sandbox'ta sorunsuz görünen akışların prod'da patlamasının en sık nedenidir.
Entegrasyonda en çok patlayan noktalar
Webhook endpoint'inin idempotent olmaması — aynı ödeme bildiriminin iki kez işlenmesi — yüksek trafikli bilet satışında sık görülür; İyzico aynı callback'i tekrar gönderebilir ve göndermelidir. 3DS dönüşünde session veya order eşleşmesinin kaybolması, özellikle mobil tarayıcı ve webview senaryolarında kullanıcıyı “ödedim ama sipariş yok” noktasına getirir. Test ortamında çalışan akışın prod merchant ayarlarında farklı davranması (taksit, BIN kısıtı, callback URL) keşif aşamasında konuşulmayan sürprizler yaratır. Mobil webview ile ödeme sayfası arasındaki cookie ve redirect sorunları, uygulama içi checkout denemelerinde sessizce oturum koparır. Son olarak, webhook henüz gelmeden kullanıcıya erken “ödeme tamamlandı” mesajı göstermek destek yükünü ve chargeback tartışmalarını artırır.
Backend'de ödeme durumu nasıl modellenir?
Ödeme durumunu tek bir payment_intent veya order_payment tablosunda tutmak en sağlıklı yaklaşımdır: pending, requires_action, paid, failed, refunded. Kullanıcı arayüzü bu state'e bakar; webhook yalnızca state'i günceller, iş mantığını tekrarlamaz. NestJS veya Go tarafında webhook handler'ları mutlaka imza doğrulaması ve idempotency key ile yazılmalıdır — aynı event_id veya payment_id ikinci kez geldiğinde no-op dönmelidir. Sipariş, bilet veya abonelik tabloları ödeme state'ine foreign key ile bağlanır; “paid” olmayan kayıt için fulfillment tetiklenmez. Yüksek trafikli etkinlik satışında bu ayrım, çift bilet basımını ve envanter sapmasını önler.
Prod öncesi test ve mobil vs. web
Sandbox'ta her şey düzgün olsa bile prod merchant panelindeki ayar farkı şaşırtabilir. Canlıya çıkmadan önce gerçek kartla düşük tutarlı prod testi yapmak şarttır: 3DS dönüşü, webhook gecikmesi ve iade akışı ancak bu şekilde doğrulanır. Mobil tarafta uygulama içi dijital ürün satışı App Store kurallarına girer; fiziksel hizmet, etkinlik bileti veya gerçek dünya teslimatı farklı değerlendirilir — bu ayrımı netleştirmeden ödeme mimarisi kurmak pahalıya patlar. Web checkout + deep link dönüşü mobilde çalışır; ancak UX maliyeti vardır. Proje tipine göre native In-App Purchase, harici web ödeme veya hibrit model değerlendirilmelidir; tek doğru cevap yoktur, doğru cevap ürün ve dağıtım kanalına bağlıdır.