Purchase Flow
This guide demonstrates a clean purchase flow using react-native-iap with the useIAP
hook and the new platform‑specific request shape.
Flow Overview
-
Initialize:
useIAP
manages the store connection lifecycle -
Load products:
fetchProducts({ skus, type: 'in-app' })
-
Start purchase:
requestPurchase({ request: { ios: { sku }, android: { skus: [sku] } }, type: 'in-app' })
-
Receive callbacks:
onPurchaseSuccess
/onPurchaseError
(fromuseIAP
) -
Validate server‑side: send receipt/JWS or token to your backend
-
Finish transaction:
finishTransaction({ purchase, isConsumable })
Connect → Fetch Products → Request Purchase → Server Validate → Finish Transaction
Key Concepts
1. Connection Management
useIAP
automatically opens/closes the connection- Exposes
connected
, convenient for showing loading states
2. Product Loading
- Load in‑app products or subscriptions (set
type
) - Handle and log failed product fetches
3. Purchase Flow
- Start purchases via unified request shape (no
Platform.OS
branching) - Use
onPurchaseSuccess
/onPurchaseError
fromuseIAP
- Always call
finishTransaction
after server validation
4. Receipt Validation
- Perform validation on your backend (never only on device)
- iOS: validate the receipt/JWS; Android: validate purchase token + package name
5. User Experience
- Provide clear states for loading, success, and error
- Show subscription management/deep‑links when appropriate
Platform Differences
Purchase Request Parameters
Use the modern, platform‑specific request container (v2.7.0+). This avoids manual Platform.OS
checks:
await requestPurchase({
request: {
ios: {sku: productId, quantity: 1},
android: {skus: [productId]},
},
type: 'in-app',
});
Notes:
- Keep
andDangerouslyFinishTransactionAutomatically
off (default) to validate first.
Key iOS Options
appAccountToken
: set per user to correlate receipts on your backendquantity
: purchase quantity for iOS (consumables)
Purchase Object Properties
Purchase objects have different properties on iOS and Android. When accessing platform-specific properties, TypeScript type casting is required:
// Unified fields
const token = purchase.purchaseToken; // iOS JWS or Android token
// Android-only helpers
// const pkg = (purchase as PurchaseAndroid).packageNameAndroid;
Receipt Validation
Receipt validation requires different approaches:
- iOS: verify receipt/JWS on your server against Apple
- Android: verify token and package name against Google Play Developer API
Usage
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import PurchaseFlow from './purchase-flow';
export default function App() {
return (
<NavigationContainer>
<PurchaseFlow />
</NavigationContainer>
);
}
Customization
You can customize this example by:
- Styling: Modify the
styles
object to match your app's design - Product IDs: Update
PRODUCT_IDS
with your actual product IDs - Validation: Implement proper server-side receipt validation
- Error Handling: Add more specific error handling for your use case
- Features: Add features like purchase restoration, subscription management, etc.
Next Steps
- Implement proper receipt validation
- Add purchase restoration
- Handle subscription management
- Add comprehensive error handling