How to Test In-App Purchases (Android + iOS, 2026)
In-app purchases (IAP) touch revenue directly — a broken IAP flow is an immediate, measurable loss. They also touch three systems (your app, store services, your backend), each with its own sandboxes
In-app purchases (IAP) touch revenue directly — a broken IAP flow is an immediate, measurable loss. They also touch three systems (your app, store services, your backend), each with its own sandboxes and edge cases. This guide covers what to test, how to reproduce edge cases, and what ships broken most often.
What IAP actually is
A user taps "Buy." Your app shows the store's native purchase sheet (Google Play Billing / Apple StoreKit). The store validates payment, returns a signed receipt. Your app verifies (ideally server-side), grants access, stores state. Four steps, four places to fail.
What to test
Product catalog
- Products load from Play Console / App Store Connect
- Localized prices display in user's currency
- Subscription terms (trial, renewal, price) shown clearly
- Missing / inactive products handled gracefully
Purchase flow
- Sheet opens on tap
- Successful purchase — receipt received
- Receipt verified server-side
- Entitlement granted within 5 seconds
- UI updates (button changes, feature unlocks)
- User cancels at sheet — no charge, no error
- Payment declined — clear error, entry preserved
Restore purchases
- Restore button visible (required by Apple)
- Returning user restores access
- Restored subscription verified as active
- No duplicate entitlements granted
Subscriptions
- Free trial starts correctly (if offered)
- Trial countdown visible
- Auto-renewal billed on schedule
- Cancel-in-trial does not charge
- Grace period after failed renewal
- Account hold state detected, user prompted
Edge cases
- Purchase while offline — queued and replayed
- Force-close mid-purchase — state recovered
- Receipt validation fails → entitlement not granted (secure fail)
- Receipt validation times out → retry with backoff
- Race: two devices purchase simultaneously
- User refunds via store → app detects and revokes (if required)
- Subscription pause (Play) → entitlement respects pause
- Upgrade / downgrade mid-subscription — prorated correctly
Family sharing (iOS) / shared library (Play)
- Shared subscription grants access to family members
- Revocation from primary account propagates
Receipts and server
- Server verifies receipt with Apple / Google
- Server stores transaction ID for dedup
- Server refuses duplicate transaction IDs
- Server tolerates replay with same receipt (idempotent)
- Server rejects receipts from different product
Accessibility
- Purchase buttons labeled with price and product
- Subscription terms readable at 200% font size
- Screen reader announces subscription periodic cost
Content restrictions (Apple)
- Auto-renew terms visible before confirmation
- "Manage subscription" link accessible
- Terms of Service and Privacy Policy linked
How to test manually
Android:
- Play Console → License Testing → add test accounts
- Test accounts purchase with sandbox cards; charges do not go through
- Uninstall + reinstall to test restore
- Change system locale to test localized prices
iOS:
- App Store Connect → Users and Access → Sandbox Testers
- Sandbox Apple IDs purchase; no real charges
- StoreKit Configuration file (Xcode 15+) for fully local testing
- Simulator StoreKit testing does not actually reach Apple — useful for UI, not end-to-end
Automated testing
Purchase state automation is constrained — you cannot fully automate the store purchase sheet. What you can automate:
- Product catalog load: assert products present, price format correct
- Server-side receipt validation: feed known receipts, assert outcomes
- UI states post-purchase: mock
PurchasesUpdatedListener/SKPaymentTransactionObservercallbacks - Restore flow: mock receipts and assert entitlement restored
Dedicated libraries (RevenueCat, Qonversion, Purchasely) abstract IAP and provide test mocks. Worth the dependency if IAP is complex.
How SUSA handles IAP
SUSA detects purchase-sheet screens and can:
- Complete test purchases in sandbox mode (if credentials are configured)
- Cancel the sheet and verify the app handles cancellation
- Verify restore flow
- Flag screens where purchase fails to grant entitlement (entitlement still locked after successful payment)
susatest-agent test myapp.apk --iap-test-mode sandbox --iap-account test@example.com
Common production bugs
- Receipt validated client-side only — jailbroken device can fake receipts. Always validate server-side.
- Entitlement not persisted after purchase — user uninstalls, reinstalls, loses access. Fix: server is source of truth.
- Duplicate charges on retry — idempotency by transaction ID.
- Subscription renewal misses grace period — user locked out for 1-3 days after failed payment that eventually succeeded.
- Price displayed wrong after currency change — app caches old price.
IAP is one of the highest-ROI test surfaces. A single broken release can cost thousands in lost revenue. Automate what you can, sandbox-test everything manually, verify on real devices before every release.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free