Uygulama içi satın almayı Flutter'da kurmak, ilk bakışta kolay: in_app_purchase paketi ürünleri listeler, kullanıcı öder, uygulamaya bir "satın alındı" olayı düşer. Çoğu hata da tam burada başlar. O olayı alıp doğrudan premium özelliği açmak, kasaya bakmadan "ödendi" yazılı bir kâğıda güvenmek gibidir.
İstemciye neden güvenemezsiniz
Uygulama kullanıcının cihazında çalışır; kullanıcı o cihazın sahibidir. Kök yetkili ya da jailbreak yapılmış bir cihazda, sahte satın alma yanıtı üreten araçlar bulunur. İstemciden gelen "ödeme tamamlandı" bilgisi doğrulanmadığı sürece yalnızca bir iddiadır. Bu yüzden satın alma sonucunun asıl kararı sunucuda verilmelidir.
Doğru akış: makbuzu sunucuya gönderin
Satın alma tamamlandığında PurchaseDetails nesnesi, mağazanın verdiği doğrulama verisini taşır (verificationData). Uygulama bu veriyi kendi sunucunuza gönderir; sunucu da mağazanın resmi doğrulama arayüzüne sorar. Akış kabaca şöyledir:
- Uygulama satın alma olayını alır ve doğrulama verisini backend'e gönderir.
- Backend, Google Play için Play Developer API'sine, Apple için App Store Server API'sine istek atar.
- Mağaza yanıtı geçerliyse backend kullanıcının hakkını veritabanına yazar.
- Ancak backend onayından sonra uygulama
completePurchaseçağırır ve özelliği açar.
Özelliğin kaynağı artık cihazdaki bir bayrak değil, sunucudaki kayıttır. Kullanıcı uygulamayı silip yeniden kursa ya da başka cihazdan girse de hakkı sunucudan okunur.
Sunucu tarafında dikkat edilecekler
Doğrulama yalnızca "makbuz geçerli mi" sorusundan ibaret değil. Aynı makbuzu başka bir hesapla tekrar göndermek, klasik bir kötüye kullanım yöntemidir. Bu yüzden işlem numarasını (örneğin mağazanın verdiği sipariş kimliğini) veritabanında benzersiz indeksle saklayın ve zaten kullanılmış bir makbuzu reddedin. Ürün kimliğinin beklediğiniz ürünle eşleştiğini ve makbuzun sizin uygulamanıza ait olduğunu da kontrol edin.
Laravel tarafında bu mantığı denetleyiciye gömmek yerine ayrı bir servis sınıfında tutun: mağazaya yapılan çağrıları sarmalayan bir arayüz, test sırasında sahte bir uygulamayla değiştirilebilir. Mağaza erişilemediğinde de net bir kural belirleyin: bu durumda satın alma "beklemede" kalır, sonra bir kuyruk işiyle yeniden denenir. Kullanıcıyı parası çekilmişken mağdur etmek, sahtekârlığı engellemekten daha kötü bir sonuçtur.
Abonelikler ve iade: durum zamanla değişir
Tek seferlik ürünlerde doğrulama bir kez yapılır. Abonelikte ise durum sürekli değişir: yenilenir, iptal edilir, ödeme alınamaz, iade edilir. İstemci bu değişimlerin hepsini zamanında bilemez. Mağazaların sunucu bildirimlerini kullanın: Google tarafında gerçek zamanlı geliştirici bildirimleri, Apple tarafında App Store Server Notifications. Backend bu bildirimleri alıp kullanıcının hakkını günceller. Bildirimin kendisine de güvenmeyin; gelen olayı mağaza arayüzünden teyit edin.
Kurulum için kısa kontrol listesi
Satın alma akışını canlıya almadan önce şunlara bakın: tüm özellik açma kararları sunucuda mı veriliyor, işlem numarası benzersiz mi, bekleyen ve yarım kalan satın almalar uygulama açılışında yeniden işleniyor mu, geri yükleme (restore) düğmesi var mı? Özellikle tek seferlik kalıcı ürünlerde geri yükleme seçeneği, kullanıcıların yeni cihazda hakkını geri almasının yanında mağaza inceleme beklentilerinin de parçası.
Test etmek. Satın alma akışı gerçek parayla denenemeyeceği için iki mağazanın da test ortamlarını kullanın: Google Play'de lisans test hesapları, Apple tarafında sandbox kullanıcıları. Ek olarak backend doğrulama servisinin sahte bir uygulamasını yazın; başarısız makbuz, tekrar gönderilen makbuz, mağazanın zaman aşımı gibi uç durumları bu sayede otomatik testlerle her değişiklikte çalıştırabilirsiniz. Satın alma gibi para ile ilgili bir akışta, uç durumu canlıda keşfetmek en pahalı yöntemdir. Bir uyarı daha: mağaza doğrulama çağrılarının kimlik bilgilerini (Google servis hesabı anahtarı, Apple'ın API anahtarı) uygulamanın içine koymayın; yalnızca sunucuda, ortam değişkenlerinde ya da gizli bilgi yöneticisinde tutun. Uygulamaya gömülen her anahtar, paketi açan herkesin eline geçer.
Uygulamanıza satın alma ya da abonelik eklemeyi güvenli biçimde kurmak isterseniz iletişim sayfamızdan bize ulaşın. Flutter ve Laravel ile yıllardır birlikte kurduğumuz bu akışı, doğrulama ve bildirim katmanıyla baştan doğru tasarlıyoruz.