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 ve guard dalları
  • product.purchase() öncesi/sonrası
  • Transaction.updates
  • refreshEntitlements()
  • Transaction.currentEntitlements
  • Transaction.latest(for:)

Sonuç:

  • purchase() .success döndürdü
  • İşlem doğrulaması başarılıydı ve transaction.finish() da çalıştı
  • Ama entitledIDs boş 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ı:

  1. Transaction.currentEntitlements iterasyon sayısı 0 idi
  2. Transaction.latest(for: monthly) geçerli bir kayıt döndürdü ama süresi dolmuştu
  3. Daha kritik olan: satın alma öncesinde Transaction.unfinished içinde eski işlemler vardı
  4. 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 transaction olsa 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 transaction anlık görüntüsü
  • subscription status (state, renewal info)
  • currentEntitlements iterasyon 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

  1. Her testten önce Sandbox hesabının abonelik durumunu kontrol edin (süresi dolmuş mu)
  2. Kritik akışlarda unfinished sayısını loglayın
  3. Üç senaryoyu test edin: ilk satın alma / süre dolumu sonrası yenileme / satın alımları geri yükleme
  4. currentEntitlements ve latest tutarlılığını doğrulayın
  5. “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.