A robust in-app purchase library for React Native that simplifies receipt validation and subscription management through the Iaptic service.
npm install react-native-iaptic
# or
yarn add react-native-iaptic
Here's a complete example to get you started:
import { IapticRN } from 'react-native-iaptic';
// 1. Initialize with your configuration
IapticRN.initialize({
appName: 'app.example.com',
publicKey: 'YOUR_PUBLIC_KEY',
iosBundleId: 'com.yourcompany.app',
products: [{
id: 'premium_monthly',
type: 'paid subscription',
entitlements: ['premium']
},
{
id: 'coins_100',
type: 'consumable',
tokenType: 'coins',
tokenValue: 100
}
]);
The IapticSubscriptionView
component provides a complete subscription management interface with purchase handling.
// In your root node, add the modal component
<IapticSubscriptionView
entitlementLabels={{
premium: {
label: "Premium Features",
detail: "Exclusive content and advanced tools"
}
}}
onPurchaseComplete={() => {
// Update app state after purchase
setEntitlements(IapticRN.listEntitlements());
}}
termsUrl="https://yourdomain.com/terms"
/>
Prop | Type | Description |
---|---|---|
entitlementLabels |
Record<string, { label: string, detail?: string }> |
Labels and descriptions for each entitlement |
onPurchaseComplete |
() => void |
Callback after successful purchase |
termsUrl |
string |
URL for terms & conditions |
theme |
object |
Customize colors (see IapticTheme) |
// AppState.ts
interface AppState {
entitlements: string[];
}
// In your component
<TouchableOpacity
onPress={() => checkAccess('premium')}
style={styles.button}
>
<Text>
Premium Access: {appState.entitlements.includes('premium') ? '✅' : '🔒'}
</Text>
</TouchableOpacity>
Customize styles using the styles
prop:
<IapticSubscriptionView
styles={{
productCard: {
backgroundColor: '#FFFFFF',
borderRadius: 12
},
ctaButton: {
backgroundColor: '#4CAF50'
}
}}
/>
The component automatically handles:
// 4. Handle purchases
const offer = IapticRN.getProduct('premium_monthly')?.offers[0];
if (offer) {
await IapticRN.order(offer);
}
// 5. Check access
if (IapticRN.checkEntitlement('premium')) {
// Unlock premium features
}
Products can be subscriptions, consumables, or non-consumables. Each product can grant one or more entitlements:
IapticRN.setProductDefinitions([
// Subscription that unlocks premium features
{
id: 'premium_monthly',
type: 'paid subscription',
entitlements: ['premium']
},
// Non-consumable that unlocks a specific feature
{
id: 'dark_theme',
type: 'non consumable',
entitlements: ['cool_feature']
},
// Consumable tokens/currency
{
id: 'coins_100',
type: 'consumable',
tokenType: 'coins',
tokenValue: 100
}
]);
Handle purchases with proper error management:
try {
await IapticRN.order(productOffer);
} catch (error) {
showError(error);
}
Allow users to restore their previous purchases:
try {
await IapticRN.restorePurchases((processed, total) => {
console.log(`Processed ${processed} of ${total} purchases`);
});
}
catch (error) {
showError(error);
}
Listen for purchase and subscription updates:
// Listen for subscription updates
IapticRN.addEventListener('subscription.updated', (reason, purchase) => {
console.log(`Subscription ${purchase.id} ${reason}`);
});
// Listen for pending purchase updates
IapticRN.addEventListener('pendingPurchase.updated', (pendingPurchase) => {
console.log(`Purchase ${pendingPurchase.productId} is now ${pendingPurchase.status}`);
});
// Listen for purchase updates
IapticRN.addEventListener('purchase.updated', (purchase) => {
console.log(`Purchase ${purchase.id} ${purchase.status}`);
});
Check if users have access to specific features:
// Check premium access
if (IapticRN.checkEntitlement('premium')) {
showPremiumContent();
} else {
showUpgradePrompt();
}
// List all active entitlements
const unlockedFeatures = IapticRN.listEntitlements();
// ['basic', 'premium', 'cool_feature']
function showError(error: Error | IapticError) {
if (error instanceof IapticError) {
trackAnalyticsEvent(error.code);
if (error.severity === IapticSeverity.INFO) {
console.log('Info:', error.localizedMessage);
return;
}
Alert.alert(error.localizedTitle, error.localizedMessage);
} else {
Alert.alert('Unknown error', error.message);
}
}
For complete API documentation, visit our API Reference.
MIT © Iaptic