Yayın öncesi IAP entegrasyon testlerinde, tipik ama oldukça kafa karıştırıcı bir sorunla karşılaştık:
- Kullanıcı “Satın Almaya Devam Et”e basıyor
- Buton “İşleniyor” durumuna geçiyor
- Birkaç saniye sonra tekrar “Satın Almaya Devam Et” oluyor
- App Store satın alma onay penceresi açılmıyor
Bu yazıda, uçtan uca inceleme yolunu, kritik logları, kök nedeni ve yayından önce uygulanabilir düzeltme stratejisini paylaşıyoruz.
1. Sorunun belirtisi
Satın alma sayfasındaki ürün listesi normal yükleniyordu; ancak satın al butonuna basınca:
purchase()çağrılıyordu- Sistem diyaloğu görünmüyordu
- UI en sonunda satın alınmamış duruma geri dönüyordu
İlk bakışta, satın alma akışı hiç başlamıyormuş gibi görünüyordu; fakat loglar farklı bir tablo gösterdi.
2. İlk inceleme: satın alma akışı gerçekten çalışıyor mu?
Satın alma akışındaki tüm kritik noktalara log ekledik:
- Buton tıklama parametreleri
purchaseSelectedProduct()girişi veguarddallarıproduct.purchase()öncesi/sonrasıTransaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
Sonuç:
purchase().successdöndürdü- İşlem doğrulaması başarılıydı ve
transaction.finish()da çalıştı - Ama
entitledIDsboş kaldı
Bu şu anlama geliyor: sorun “satın alma başlamadı” değil, “satın alma sonrası entitlement tanınmadı”.
3. Derin analizde ortaya çıkan kritik bulgular
Logları genişletince belirleyici sinyaller ortaya çıktı:
Transaction.currentEntitlementsiterasyon sayısı0idiTransaction.latest(for: monthly)geçerli bir kayıt döndürdü ama süresi dolmuştu- Daha kritik olan: satın alma öncesinde
Transaction.unfinishediçinde eski işlemler vardı - Bu çağrıdaki
purchase(), yeni etkileşimli satın alma yerine eski işlem zincirinden bir işlem döndürdü
Bu da neden popup çıkmadığını açıklıyor:
- StoreKit önce işlenebilir eski bir işlem döndürüyor (unfinished / tarihsel zincir)
- Kodunuz bunu
finish()ile kapatıyor - İstek “başarılı” görünüyor ama kullanıcının beklediği yeni onay akışına hiç girmiyor
4. Kök neden özeti
Sorun tek bir noktadan değil, iki faktörün birleşiminden kaynaklandı:
- Unfinished transaction’ların satın alma akışına müdahale etmesi
- Sandbox abonelik zincirinin süresi dolmuş durumda olması (
latest transactionolsa bile bu her zaman aktif entitlement anlamına gelmez)
Nihai davranış: popup yok, görünürde başarı var, entitlement’lar boş.
5. Düzeltme stratejisi (pratikte doğrulandı)
5.1 Satın alma öncesi unfinished transaction’ları proaktif temizleyin
Uygulama açılışında ve satın alma öncesinde Transaction.unfinished taranmalı; verified transaction’larda finish() çağrılmalı. Böylece eski işlemler yeni akışı “kaçırmaz”.
5.2 Tanılama loglarını koruyun ve güçlendirin (yayın öncesi önerilir)
Yayına kadar şu logları açık tutmak faydalı:
unfinished transactionanlık görüntüsüsubscription status(state, renewal info)currentEntitlementsiterasyon sayısılatest(for:)içindeki transaction/expiration detayları
5.3 Entitlement kontrolünde çift yol kullanın (opsiyonel sağlamlaştırma)
Bazı ortamlarda currentEntitlements geçici olarak boş kalıyorsa, latest(for:) fallback olarak kullanılabilir (aktiflik doğrulaması yine zorunludur).
6. Yayın öncesi IAP kontrol listesi
- Her testten önce Sandbox hesabının abonelik durumunu kontrol edin (süresi dolmuş mu)
- Kritik akışlarda
unfinishedsayısını loglayın - Üç senaryoyu test edin: ilk satın alma / süre dolumu sonrası yenileme / satın alımları geri yükleme
currentEntitlementsvelatesttutarlılığını doğrulayın- “Popup yok” durumunda önce eski işlem akışına düşülüp düşülmediğini kontrol edin
7. Sonuç
“Satın al’a basınca popup çıkmıyor” her zaman UI veya çağrı zamanlaması sorunu değildir.
StoreKit 2’de işlem durumu, unfinished kuyruğu ve abonelik yaşam döngüsü nihai davranışı doğrudan etkiler.
Yayın öncesinde bu logları ve temizlik adımlarını eklemek, prod ortamında yeniden üretmesi zor olan birçok IAP sorununu ciddi şekilde azaltır.