Under IAP-test før lancering stødte vi på et klassisk, men meget forvirrende problem:
- Brugeren trykker på “Fortsæt køb”
- Knappen skifter til “Behandler”
- Efter få sekunder går den tilbage til “Fortsæt køb”
- App Stores købsbekræftelse popper ikke op
Denne artikel gennemgår hele fejlfindingsforløbet, nøglelogs, root cause og en praktisk løsning, der kan bruges før release.
1. Symptomet
Produktlisten på købssiden blev indlæst korrekt, men efter klik på køb:
purchase()blev kaldt- Ingen systemdialog blev vist
- UI endte i ikke-købt tilstand igen
Ved første øjekast lignede det, at købet slet ikke startede, men loggene viste noget andet.
2. Første runde: virker købskæden faktisk?
Vi lagde logs ind på alle kritiske punkter i købskæden:
- Parametre fra knapklik
- Entry i
purchaseSelectedProduct()ogguard-grene - Før/efter
product.purchase() Transaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
Resultat:
purchase()returnerede.success- Transaktionen blev verificeret, og
transaction.finish()blev også kørt - Men
entitledIDsforblev tom
Det betyder: problemet var ikke “køb blev ikke startet”, men “rettigheder blev ikke genkendt efter køb”.
3. Afgørende fund ved dybere analyse
Efter mere detaljeret logging kom disse klare signaler frem:
Transaction.currentEntitlementshavde iterationsantal0Transaction.latest(for: monthly)havde en gyldig post, men den var udløbet- Vigtigst: før køb fandtes der gamle transaktioner i
Transaction.unfinished - Det aktuelle
purchase()returnerede en transaktion fra en gammel kæde, ikke fra et nyt interaktivt køb
Det forklarer, hvorfor der “ikke kommer en popup”:
- StoreKit returnerer først en gammel transaktion, der kan behandles (unfinished / historisk flow)
- Koden kalder
finish()på den - Købet ser “succesfuldt” ud, men går ikke gennem den nye købsbekræftelse, som brugeren forventer
4. Root cause opsummeret
Fejlen var ikke én enkelt årsag, men en kombination af to:
- Uafsluttede transaktioner (
unfinished transaction) forstyrrer købsflowet - Sandbox-abonnementskæden er i udløbet tilstand (selv med
latest transactioner det ikke nødvendigvis en aktiv entitlement)
Det samlede symptom blev derfor: ingen popup, tilsyneladende succes, tomme rettigheder.
5. Løsningsstrategi (verificeret i praksis)
5.1 Ryd unfinished-transaktioner før køb
Ved app-start og før køb: scan Transaction.unfinished og kør finish() på verificerede transaktioner, så gamle transaktioner ikke kaprer det nye køb.
5.2 Bevar og styrk diagnostiske logs (anbefalet før release)
Følgende logs bør bevares frem til lancering:
- Snapshot af
unfinished transaction subscription status(state, renewal info)- Iterationsantal for
currentEntitlements transaction/expirationfralatest(for:)
5.3 Brug “dobbelt kanal” til rettighedsvurdering (valgfri forbedring)
Hvis currentEntitlements midlertidigt er tom i visse miljøer, kan latest(for:) bruges som fallback (men verificér stadig, at rettigheden er aktiv).
6. IAP-checkliste før lancering
- Før hver test: bekræft abonnementstilstand for sandbox-kontoen (om den er udløbet)
- Log antal
unfinishedi kritisk sti - Test tre scenarier: “førstegangskøb / fornyelse efter udløb / gendan køb”
- Kontrollér, at
currentEntitlementsoglateststemmer overens - Hvis “ingen popup” opstår, tjek først om et gammelt transaktionsflow blev ramt
7. Afslutning
“Tryk på køb uden popup” betyder ikke nødvendigvis et UI-problem eller et timing-problem i kaldet.
I StoreKit 2 påvirker transaktionstilstand, unfinished-kø og abonnementets livscyklus det endelige resultat.
Ved at tilføje disse logs og oprydning før lancering kan man undgå mange IAP-problemer, som ellers er svære at reproducere i produktion.