Under IAP-testing før lansering støtte vi på et klassisk, men svært forvirrende problem:

  • Brukeren trykker «Fortsett kjøp»
  • Knappen går til «Behandler»
  • Etter noen sekunder går den tilbake til «Fortsett kjøp»
  • Ingen kjøpsbekreftelse fra App Store vises

Denne artikkelen dokumenterer hele feilsøkingsløpet, nøkkellogger, rotårsak og en praktisk løsning som kan brukes før release.

1. Symptom

Produktlisten på kjøpssiden lastet som normalt, men etter trykk på kjøp:

  • purchase() ble kalt
  • Ingen systemdialog dukket opp
  • UI endte tilbake i ikke-kjøpt tilstand

Ved første øyekast så det ut som om kjøpsflyten aldri startet, men loggene viste noe annet.

2. Første runde: verifiser at kjøpsflyten faktisk kjører

Vi la inn logger på alle kritiske sjekkpunkter i kjøpsflyten:

  • Parametere fra knappetrykk
  • Inngang til purchaseSelectedProduct() og guard-grener
  • Før/etter product.purchase()
  • Transaction.updates
  • refreshEntitlements()
  • Transaction.currentEntitlements
  • Transaction.latest(for:)

Resultat:

  • purchase() returnerte .success
  • Transaksjonsverifisering lyktes, og transaction.finish() ble også kjørt
  • Men entitledIDs forble tom

Dette betyr: problemet var ikke «kjøpet startet ikke», men «rettigheter ble ikke gjenkjent etter kjøp».

3. Avgjørende funn etter dypere analyse

Etter mer detaljert logging kom flere tydelige signaler fram:

  1. Transaction.currentEntitlements hadde iterasjonsantall 0
  2. Transaction.latest(for: monthly) hadde en gyldig post, men den var utløpt
  3. Viktigst: før kjøpet fantes gamle transaksjoner i Transaction.unfinished
  4. Nåværende purchase() returnerte en transaksjon fra en gammel kjede, ikke fra en ny interaktiv kjøpsflyt

Dette forklarer hvorfor det ikke kom noen popup:

  • StoreKit returnerte først en gammel, prosesserbar transaksjon (unfinished / historisk kjede)
  • Koden fullførte den med finish()
  • Kjøpet så «vellykket» ut, men gikk ikke gjennom den nye bekreftelsesflyten brukeren forventer

4. Oppsummering av rotårsak

Dette var ikke én enkelt feil, men en kombinasjon av to faktorer:

  • Uferdige transaksjoner (unfinished transaction) forstyrrer kjøpsflyten
  • Sandbox-abonnementskjeden er i utløpt tilstand (selv med latest transaction er det ikke nødvendigvis en aktiv entitlement)

Sluttresultatet ble: ingen popup, tilsynelatende suksess, tomme rettigheter.

5. Løsningsstrategi (verifisert i praksis)

5.1 Rydd unfinished-transaksjoner proaktivt før kjøp

Ved app-start og før kjøp: skann Transaction.unfinished og kjør finish() på verifiserte transaksjoner, slik at gamle transaksjoner ikke kaprer den nye kjøpsflyten.

5.2 Behold og styrk diagnostiske logger (anbefalt før lansering)

Disse loggene bør holdes aktive fram til release:

  • Snapshot av unfinished transaction
  • subscription status (state, renewal info)
  • Iterasjonsantall for currentEntitlements
  • transaction/expiration-detaljer i latest(for:)

5.3 Bruk dobbelt kanal for rettighetsvurdering (valgfri herding)

Hvis currentEntitlements er midlertidig tom i enkelte miljøer, kan latest(for:) brukes som fallback (med fortsatt validering av aktiv status).

6. IAP-sjekkliste før lansering

  1. Før hver test: bekreft abonnementstilstand for sandbox-kontoen (utløpt eller ikke)
  2. Logg antall unfinished i kritiske stier
  3. Test tre scenarier: førstegangskjøp / fornyelse etter utløp / gjenopprett kjøp
  4. Sjekk konsistens mellom currentEntitlements og latest
  5. Hvis «ingen popup» oppstår, sjekk først om gammel transaksjonssti ble truffet

7. Konklusjon

«Trykk på kjøp uten popup» betyr ikke nødvendigvis et UI-problem eller timing-problem i kallene.
I StoreKit 2 påvirker transaksjonstilstand, unfinished-kø og abonnementets livssyklus sluttatferden direkte.

Ved å legge inn disse loggene og ryddeprosedyrene før lansering kan du redusere mange IAP-problemer som er vanskelige å gjenskape i produksjon.