In-App Purchase Integration
Unity IAP looks simple at first: connect package, register products, call BuyProductID(). In practice—first InitializationFailureReason.PurchasingUnavailable in production on iOS 17 forces spending hours in StoreKit 2 documentation understanding entitlement misconfiguration for In-App Purchase in App Store Connect.
IAP integration is not "add SDK". This is link between client, store payment system and backend working correctly under unstable internet, interrupted transactions and fraud attempts.
Where It Most Often Fails
Pending transactions. User clicked "Buy", money charged, connection died—ProcessPurchase didn't call. Unity IAP saves transaction in queue, attempts completion on next run. But if backend doesn't implement idempotency by transactionID, player gets item twice or not at all. Saw projects where PendingOrderResponse accumulated for weeks due to missing ConfirmPendingPurchase() in right place.
Receipt validation. Without server receipt validation game vulnerable to fraud purchases via modified APK or jailbroken devices. Apple returns base64-encoded receipt in Product.receipt, Google—JSON with signature. Local check via UnityEngine.Purchasing.Security.CrossPlatformValidator—minimum barrier, insufficient. Full validation: send receipt to own server, check via Apple App Store Server API (/verifyReceipt or new StoreKit 2 JWS-token) or Google Play Developer API (purchases.products.get).
Restore Purchases on iOS. Apple requires restore button for non-consumable and subscriptions—app won't pass review without it. IAppleExtensions.RestoreTransactions() must be accessible from UI, OnTransactionsRestored handler correctly update inventory without duplicates.
Separate pain—subscriptions. SubscriptionManager in Unity IAP parses expiry date and renewal status, only with valid receipt. On Android with Google Play Billing Library 5+ need explicitly query queryPurchasesAsync on each start—cache gets stale.
What We Do in Integration
Start with audit: is there backend, need server validation, what monetization model (consumable, non-consumable, subscriptions, all). Design schema under this.
Set up product configuration in Unity IAP via ProductCatalog or programmatically via ConfigurationBuilder. For multi-platform games—single catalog with platform-specific IDs (Apple/Google often require different identifiers).
Implement full cycle: UnityPurchasing.Initialize() → handle ProcessPurchase → confirm ConfirmPendingPurchase() → deliver item → record in database. If backend—add server validation with retry logic on timeouts.
For iOS additionally: StoreKit environment setup for testing (Xcode Sandbox), handle promo offers via IAppleExtensions.SetStorePromotionOrder(), correct Family Sharing work if needed.
For Android: test account setup in Google Play Console, verify work in alpha/internal track before publication.
Testing—Separate Stage
Scenarios checked mandatory: successful purchase, purchase with network off during transaction, duplicate purchase request, purchase restore, purchase on device without payment method, subscription upgrade/downgrade.
iOS Sandbox testing has limits—some scenarios (like billing retry) only reproducible in TestFlight. Android—via internal testing track with licensed test accounts.
Timeline
| Complexity | Timeline |
|---|---|
| Consumable IAP, one platform, no backend | 2–4 days |
| Full integration (two platforms + server validation) | 1–2 weeks |
| Subscriptions with backend management + analytics | 2–4 weeks |
Cost calculated after analyzing project architecture and monetization model requirements.





