In-App Purchases And Subscriptions
Quick Answer
The in-app purchase module lives in src/core/inAppPurchase. It provides
subscription UI, purchase state, user subscription persistence, and integration
with react-native-iap.
Current app packages that use react-native-iap also need
react-native-nitro-modules installed alongside it.
Use this module only for apps that sell digital content or subscription access through Apple and Google in-app purchase systems. Physical goods and service payments usually belong in Stripe, PayPal, cash on delivery, or another commerce flow instead.
Source Map
src/core/inAppPurchase
├── IAPManagerWrapped.tsx
├── IMSubscriptionScreen
├── context.ts
├── firebase.ts
├── hooks
└── redux.ts
Important pieces:
| File or export | Purpose |
|---|---|
IAPManagerWrapped | Wraps the app with purchase listeners and subscription state. |
IMSubscriptionScreen | Displays subscription plans and starts purchases. |
IAPConfigProvider | Provides product IDs and subscription screen content. |
redux.ts | Stores plans and active subscription state. |
firebase.ts | Persists user subscription state when Firebase is enabled. |
Required Config
Your app config must provide the product IDs that exist in App Store Connect and Google Play Console:
const iapConfig = {
IAP_SKUS: [
'monthly_vip_subscription',
'annual_vip_subscription',
],
subscriptionSlideContents: [
{
title: 'Premium access',
description: 'Unlock premium features.',
},
],
}
If your app still includes IAP_SHARED_SECRET in mobile config, treat it as a
migration point. Shared secrets and receipt validation credentials should be
moved behind a backend before production release.
Store Setup
At a high level:
- Create matching subscription or in-app product IDs in App Store Connect.
- Create matching products or subscriptions in Google Play Console.
- Add the exact same IDs to
IAP_SKUS. - Configure pricing, localization, review metadata, and testing accounts.
- Test purchase, restore, cancellation, expiration, and renewal behavior.
Do not ship with demo product IDs. Product IDs are part of the store contract and should be stable once released.
Receipt Validation
The mobile app can start purchases and receive receipts, but production validation should happen on a backend:
- verify Apple receipts or App Store Server API data server-side;
- verify Google Play purchase tokens server-side;
- store subscription status per user;
- handle renewals, cancellations, refunds, and grace periods;
- avoid trusting client-only
isVIPorisPlanActiveflags.
The app module can persist subscription state to Firebase, but your production backend should be the source of truth for entitlement status.
Verification Checklist
Test before release:
- product IDs load from the store;
- subscription screen renders real prices;
- purchase starts and completes;
- transaction is finished;
- subscription state is saved to the user profile;
- restore/available purchases works;
- expired subscription removes premium access;
- canceled subscription eventually removes premium access;
- app handles store errors and user cancellation gracefully.
Troubleshooting
| Problem | Fix |
|---|---|
| No products load | Confirm product IDs match exactly and the products are active/testable in store dashboards. |
| Purchase starts but entitlement is not active | Check receipt validation and user subscription writes. |
| iOS receipt validation fails | Move validation to backend and confirm the app-specific shared secret or server API credentials. |
| Android subscription period is wrong | Confirm the subscription period string returned by Google Play and the app's period parsing. |
| App works in debug but fails in release | Test with real store sandbox/internal testing accounts and release bundle IDs/package names. |