Laravel ile geliştirdiğim bir e-ticaret uygulamasında sepet müşterinin session’ında tutuluyordu. Ödeme tamamlanınca sepeti temizlemeyi PayTR’nin callback isteğine bağlamak doğru değildi: bu isteği müşterinin tarayıcısı değil, ödeme servisinin sunucusu gönderiyordu.
Düzeltmede iki ayrı sorumluluğu ayırdım. Ödeme bildirimi siparişin durumunu belirliyor; müşterinin tarayıcısında açılan sayfa ise o müşterinin sepetini yönetiyordu. Aynı ödeme sürecinin parçaları olmaları, aynı oturuma eriştikleri anlamına gelmiyordu.
Sunucu bildirimi ile başarı sayfası aynı istek değil
PayTR sipariş numarası, ödeme sonucu ve doğrulama bilgisiyle uygulamaya bildirim gönderiyor. Kullanıcının tarayıcısı ayrıca başarılı veya başarısız ödeme adresine yönlendiriliyor. Bu iki istek farklı göndericilerden geliyor ve birbirlerinin tamamlandığını varsayamaz.
Callback isteği müşterinin session çerezini taşımadığı için o session’daki sepeti değiştiremiyor. Burada oluşturulan bir oturum değeri de müşterinin sonraki isteğine aktarılmıyor. Sepet temizliğini bu istekte yapmak, yanlış oturum üzerinde işlem yapmak demekti.
Sepeti tarayıcının erişebildiği yerde temizlemek
Checkout sırasında sipariş numarasını müşterinin session’ına kaydettim. Tarayıcı sipariş sayfasına döndüğünde, sayfanın numarası kayıtlı numarayla eşleşiyorsa sepet temizleniyor ve bu geçici işaret kaldırılıyor.
Karşılaştırmada numaranın veri tipi de önemliydi. Sayı olarak üretilen bir değer adresten metin olarak gelir; sıkı eşitlik kullanılıyorsa önce aynı gösterime çevrilmelidir. Bu kontrol, sepet işleminin hangi sipariş için yapılacağını belirliyor. Siparişi ödendi durumuna geçirmiyor.
Ödeme durumundan önce bildirim doğrulaması
Ödeme callback’ini incelerken hash doğrulamasının işlem sırasındaki önemini de ele aldım. İstekte başarılı ödeme yazması tek başına sipariş onaylamak için yeterli değil. Önce bildirimin beklenen doğrulama bilgisiyle geldiği kontrol edilmeli.
Doğrulama başarısızsa sipariş değişmiyor. Sonuçlanmış siparişe gelen tekrar bildirimleri ise yan etkileri yeniden çalıştırmadan cevaplanıyor. Böylece ödeme doğrulaması, durum geçişi ve müşterinin ekranda gördüğü işlem ayrı sınırlar içinde kalıyor.
Testin gerçek istek sınırını temsil etmesi
Bu akış için yalnız checkout sayfasının açıldığını test etmek yeterli değil. Callback’in session taşımadığı, doğrulanmamış bildirimin siparişi değiştirmediği ve aynı bildirimin yeniden gelmesinin ikinci bir onay üretmediği ayrı senaryolar olarak ele alınmalı. Testin anlamı, yalnız sayfayı değil istekleri kimin gönderdiğini de modellemesinde.