Installation
This guide will help you install and configure React Native IAP in your React Native or Expo project.
Prerequisites
Before installing React Native IAP, make sure you have:
- React Native 0.64 or later, or Expo SDK 45 or later
- Node.js 16 or later
- iOS 15+ for iOS apps (StoreKit 2 requirement)
- Android API level 21+ for Android apps
Package Installation
Install the package using your favorite package manager:
npm install react-native-iap react-native-nitro-modules
Important for Expo Managed Workflow
If you're using the Expo managed workflow, you must use a custom development client since in-app purchases require native modules that aren't available in Expo Go.
After installing the package, you need to:
-
Configure expo-build-properties for Android (required for Kotlin 2.0+ support):
Starting from version 14.0.0-rc, react-native-iap supports Google Play Billing Library v8.0.0, which requires Kotlin 2.0+. Since
expo-modules-core
doesn't support Kotlin 2.0 yet, you need to manually configure the Kotlin version.Add the following to your
app.json
:{
"expo": {
"plugins": [
"react-native-iap",
[
"expo-build-properties",
{
"android": {
"kotlinVersion": "2.1.20"
}
}
]
]
}
} -
Install the plugin and run prebuild:
npx expo prebuild --clean
This will generate the native iOS and Android directories with the necessary configurations. Learn more about adopting prebuild.
-
Create a development build (see the Platform Configuration section below for details)
Platform Configuration
For Expo Managed Workflow
If you're using Expo managed workflow, you'll need to create a custom development client since in-app purchases require native modules that aren't available in Expo Go.
-
Install EAS CLI (if not already installed):
npm install -g eas-cli
-
Create a development build:
eas build --platform ios --profile development
eas build --platform android --profile development
For React Native CLI Projects
iOS
-
Install pods:
cd ios && pod install
// or npx pod-install -
Add StoreKit capability to your iOS app in Xcode:
- Open your project in Xcode
- Select your app target
- Go to "Signing & Capabilities"
- Click "+ Capability" and add "In-App Purchase"
Android
Important: Starting from version 14.0.0-rc, react-native-iap supports Google Play Billing Library v8.0.0, which requires Kotlin 2.0+.
-
Configure Kotlin version in your root
android/build.gradle
:buildscript {
ext {
kotlinVersion = "2.1.20"
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
} -
Add billing dependencies to your
android/app/build.gradle
:dependencies {
implementation "com.android.billingclient:billing-ktx:8.0.0"
implementation "com.google.android.gms:play-services-base:18.1.0"
}
Quick Start
1. Basic Setup
First, import and initialize the IAP hook:
import { useIAP } from 'react-native-iap'
function MyStore() {
const {
connected,
products,
fetchProducts,
requestPurchase,
currentPurchase,
finishTransaction,
} = useIAP()
const productIds = ['your.product.id', 'your.premium.subscription']
}
2. Fetch Products
Load your products when the store connects:
useEffect(() => {
if (connected) {
// Fetch your products
fetchProducts({ skus: productIds, type: 'inapp' })
}
}, [connected])
3. Display Products
Show available products to users:
return (
<View>
<Text>Store Status: {connected ? 'Connected' : 'Connecting...'}</Text>
{products.map((product) => (
<View key={product.id} style={styles.productItem}>
<Text style={styles.productTitle}>{product.title}</Text>
<Text style={styles.productPrice}>{product.displayPrice}</Text>
<Button title="Buy Now" onPress={() => handlePurchase(product.id)} />
</View>
))}
</View>
)
4. Handle Purchases
Process purchase requests with our platform-specific API (v14.0.0-rc Current):
const handlePurchase = async (productId: string) => {
try {
await requestPurchase({
request: {
ios: {
sku: productId,
},
android: {
skus: [productId],
},
},
})
} catch (error) {
console.error('Purchase failed:', error)
}
}
Note: No more Platform.OS checks! The new API automatically handles platform differences. iOS can only purchase one product at a time, while Android supports purchasing multiple products in a single transaction.
5. Complete Transactions
Finish purchases when they complete:
useEffect(() => {
if (currentPurchase) {
const completePurchase = async () => {
try {
// Grant the purchase to user here
console.log('Purchase completed:', currentPurchase.id)
// Finish the transaction
await finishTransaction({
purchase: currentPurchase,
isConsumable: true, // Set based on your product type
})
} catch (error) {
console.error('Failed to complete purchase:', error)
}
}
completePurchase()
}
}, [currentPurchase])
Complete Basic Example
Here's a complete working example:
import React, { useEffect } from 'react'
import { View, Text, Button, StyleSheet } from 'react-native'
import { useIAP } from 'react-native-iap'
export default function SimpleStore() {
const {
connected,
products,
fetchProducts,
requestPurchase,
currentPurchase,
finishTransaction,
} = useIAP()
const productIds = ['com.example.coins.pack1', 'com.example.premium']
useEffect(() => {
if (connected) {
fetchProducts({ skus: productIds, type: 'inapp' })
}
}, [connected])
useEffect(() => {
if (currentPurchase) {
const completePurchase = async () => {
try {
console.log('Purchase completed:', currentPurchase.id)
await finishTransaction({
purchase: currentPurchase,
isConsumable: true,
})
} catch (error) {
console.error('Failed to complete purchase:', error)
}
}
completePurchase()
}
}, [currentPurchase])
const handlePurchase = async (productId: string) => {
try {
await requestPurchase({
request: {
ios: {
sku: productId,
},
android: {
skus: [productId],
},
},
})
} catch (error) {
console.error('Purchase failed:', error)
}
}
return (
<View style={styles.container}>
<Text style={styles.status}>
Store: {connected ? 'Connected ✅' : 'Connecting...'}
</Text>
{products.map((product) => (
<View key={product.id} style={styles.product}>
<Text style={styles.title}>{product.title}</Text>
<Text style={styles.price}>{product.displayPrice}</Text>
<Button title="Buy Now" onPress={() => handlePurchase(product.id)} />
</View>
))}
</View>
)
}
const styles = StyleSheet.create({
container: { padding: 20 },
status: { fontSize: 16, marginBottom: 20 },
product: {
padding: 15,
marginVertical: 5,
backgroundColor: '#f0f0f0',
borderRadius: 8,
},
title: { fontSize: 16, fontWeight: 'bold' },
price: { fontSize: 14, color: '#666', marginVertical: 5 },
})
Store Configuration
React Native IAP is OpenIAP compliant. For detailed instructions on setting up your products in each store:
- iOS: OpenIAP iOS Setup Guide - App Store Connect configuration
- Android: OpenIAP Android Setup Guide - Google Play Console configuration
Verification
To verify that React Native IAP is properly installed, create a simple test:
import { useIAP } from 'react-native-iap'
function TestComponent() {
const { connected } = useIAP()
console.log('IAP Connection status:', connected)
return null
}
If everything is set up correctly, you should see the connection status logged in your console.
Next Steps
Now that you have React Native IAP installed, you can:
Troubleshooting
If you encounter issues during installation:
-
Clear node_modules and reinstall:
rm -rf node_modules
npm install -
For iOS, clean and rebuild pods:
cd ios
rm -rf Pods Podfile.lock
pod installFor Expo projects, use prebuild instead:
npx expo prebuild --clean
-
For React Native, reset Metro cache:
npx react-native start --reset-cache
For more help, check our Troubleshooting Guide or open an issue on GitHub.