Skip to main content

Getting Started

expo-iap is a powerful in-app purchase solution specifically designed for Expo and React Native applications. It provides a unified API for handling in-app purchases across iOS and Android platforms with comprehensive error handling and modern TypeScript support.

This library provides the basic features to consume In-App purchases on the client-side, however you'll have to implement the server-side to validate your receipts (which is probably the most time consuming part to do it correctly). :::

Requirements

  • React Native 0.64 or later, or Expo SDK 45 or later
  • Node.js 16 or later
  • iOS 12+ for iOS apps
  • Android API level 21+ for Android apps

Installation

Install the package using your favorite package manager:

npm install expo-iap

Expo Managed Workflow

Since in-app purchases require native modules that aren't available in Expo Go, you'll need to use expo-dev-client for development builds.

npx expo install expo-dev-client
npx expo run:ios # or npx expo run:android

Learn more about converting from Expo Go to development builds.

React Native CLI Projects

For React Native CLI projects, install expo-modules-core first:

npx install-expo-modules@latest

Learn more about installing Expo modules in existing React Native projects.

iOS Configuration

For iOS projects, you need to configure StoreKit capabilities:

  1. Open your iOS project in Xcode
  2. Select your target in the project navigator
  3. Go to "Signing & Capabilities" tab
  4. Click "+" and add "In-App Purchase" capability

Android Configuration

For Android, ensure your app is configured for Google Play Billing:

  1. Open android/app/build.gradle
  2. Add the billing permission:
android {
defaultConfig {
// ... other configurations
}
}

dependencies {
// ... other dependencies
implementation 'com.android.billingclient:billing:5.0.0'
}

Quick Start

1. Initialize the connection

import {useIAP} from 'expo-iap';

export default function App() {
const {
connected,
products,
purchaseHistory,
getProducts,
requestPurchase,
finishTransaction,
} = useIAP();

// Initialize connection when component mounts
useEffect(() => {
// Connection is automatically handled by useIAP
}, []);

return (
<View>
<Text>Connection Status: {connected ? 'Connected' : 'Disconnected'}</Text>
{/* Your app content */}
</View>
);
}

2. Fetch available products

const productIds = [
'com.example.product1',
'com.example.product2',
'com.example.subscription1',
];

useEffect(() => {
if (connected) {
getProducts({skus: productIds});
}
}, [connected, getProducts]);

3. Request a purchase

const handlePurchase = async (productId: string) => {
try {
await requestPurchase({sku: productId});
} catch (error) {
console.error('Purchase failed:', error);
}
};

4. Handle purchase updates

The useIAP hook automatically handles purchase updates. When a purchase is successful, you should validate the receipt on your server and then finish the transaction:

useEffect(() => {
if (currentPurchase) {
// Validate receipt on your server
validateReceiptOnServer(currentPurchase)
.then(() => {
// If validation successful, finish the transaction
finishTransaction({purchase: currentPurchase});
})
.catch((error) => {
console.error('Receipt validation failed:', error);
});
}
}, [currentPurchase, finishTransaction]);

Best Practices

  1. Handle connection lifecycle: The useIAP hook automatically manages the connection lifecycle, but be aware of when your app is connected before making purchase requests.

  2. Test thoroughly: Test with sandbox accounts and real devices. In-app purchases don't work in simulators/emulators. Use Apple's Sandbox environment and Google Play Console's testing features.

  3. Implement comprehensive error handling: Handle various purchase scenarios including user cancellation, network errors, and invalid products. See our error handling guide for common issues and solutions.

  4. Restore purchases properly: Implement purchase restoration for non-consumable products and subscriptions. This is required by app store guidelines and essential for users who reinstall your app.

  5. Server-side receipt validation is recommended: For production apps, it's highly recommended to validate receipts on your secure server before granting access to content or features. See Apple's receipt validation guide and Google Play's verification guide.

  6. Finish transactions after validation: Always call finishTransaction after successfully validating a purchase on your server. Failing to do so will cause the purchase to remain in a pending state and may trigger repeated purchase prompts.

  7. Check server-side validation libraries: Consider using open-source libraries like node-app-store-receipt-verify for iOS or google-play-billing-validator for Android to simplify server-side validation.

Next Steps