Tijekom IAP testiranja prije objave naišli smo na tipičan, ali vrlo zbunjujuć problem:
- Korisnik pritisne „Nastavi kupnju”
- Gumb pređe u stanje „Obrada”
- Nakon nekoliko sekundi vrati se na „Nastavi kupnju”
- Ne prikazuje se App Store prozor za potvrdu kupnje
U ovom članku bilježimo cijeli put dijagnostike, ključne logove, root cause i praktičnu strategiju popravka prije izlaska.
1. Simptom
Popis proizvoda na ekranu kupnje učitavao se normalno, ali nakon klika na kupnju:
purchase()je bio pozvan- Nije se pojavio sistemski dijalog
- UI se na kraju vratio u stanje „nije kupljeno”
Na prvi pogled izgledalo je kao da se kupnja uopće nije pokrenula, ali logovi su pokazali drugačije.
2. Prva provjera: prolazi li tok kupnje stvarno kroz sustav?
Dodali smo logove na sve kritične točke toka kupnje:
- Parametri klika na gumb
- Ulaz u
purchaseSelectedProduct()iguardgrane - Prije/poslije
product.purchase() Transaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
Rezultat:
purchase()je vratio.success- Verifikacija transakcije je uspjela i
transaction.finish()se izvršio - Ali
entitledIDsje ostao prazan
To znači: problem nije bio „kupnja nije pokrenuta”, nego „nakon kupnje entitlementi nisu prepoznati”.
3. Ključna otkrića nakon dublje analize
Nakon proširenog logiranja pojavilo se nekoliko odlučujućih signala:
- Broj iteracija
Transaction.currentEntitlementsbio je0 Transaction.latest(for: monthly)imao je valjan zapis, ali istekao- Još važnije: prije kupnje su postojale stare transakcije u
Transaction.unfinished - Trenutni
purchase()vratio je transakciju iz starog lanca, a ne iz nove interaktivne kupnje
To objašnjava zašto nema popupa:
- StoreKit prvo vrati staru obradivu transakciju (unfinished / povijesni lanac)
- Kod je zatim dovrši pozivom
finish() - Zahtjev izgleda „uspješno”, ali ne prolazi kroz novi put potvrde kupnje koji korisnik očekuje
4. Sažetak uzroka
Nije riječ o jednoj grešci, nego o kombinaciji dva faktora:
- Nedovršene transakcije (
unfinished transaction) ometaju tok kupnje - Sandbox pretplatnički lanac je u isteklom stanju (čak i uz
latest transaction, to ne mora biti aktivan entitlement)
Konačno ponašanje: nema popupa, prividan uspjeh, entitlementi prazni.
5. Strategija popravka (potvrđena u praksi)
5.1 Proaktivno očistite unfinished transakcije prije kupnje
Pri pokretanju aplikacije i prije kupnje prođite Transaction.unfinished i pozovite finish() za verificirane transakcije, kako stare transakcije ne bi „preuzele” novi tok kupnje.
5.2 Zadržite i pojačajte dijagnostičke logove (preporučeno prije objave)
Ove logove vrijedi ostaviti uključene do izlaska:
- Snapshot
unfinished transaction subscription status(state, renewal info)- Broj iteracija
currentEntitlements transaction/expirationdetalji izlatest(for:)
5.3 Dvokanalna provjera entitlementa (opcionalno poboljšanje)
Ako je u nekim okruženjima currentEntitlements privremeno prazan, koristite latest(for:) kao fallback (uz obaveznu provjeru da je i dalje active).
6. IAP checklist prije objave
- Prije svakog testa provjerite stanje pretplate sandbox računa (je li istekla)
- Logirajte broj
unfinishedstavki na kritičnim putanjama - Testirajte tri scenarija: „prva kupnja / obnova nakon isteka / restore kupnje”
- Provjerite konzistentnost između
currentEntitlementsilatest - Ako se dogodi „nema popupa”, prvo provjerite je li pogođen stari transakcijski put
7. Zaključak
„Klik na kupnju bez popupa” ne znači nužno UI problem ili problem tajminga poziva.
U StoreKit 2, stanje transakcija, unfinished red i životni ciklus pretplate izravno utječu na završno ponašanje.
Dodavanje ovih logova i koraka čišćenja prije objave značajno smanjuje IAP probleme koje je teško reproducirati u produkciji.