3.2.0 - Built-in Purchase Verification (aka. Receipt Validation)

Expo IAP 3.2.0 brings built-in purchase verification powered by IAPKit. Now you can verify purchases with enterprise-grade backend validation using a single API callβno server setup required.
Why IAPKit?β
Purchase verification is critical for any production IAP implementation. Without proper server-side validation, your app is vulnerable to receipt tampering, replay attacks, and fraudulent transactions. IAPKit solves this with a battle-tested backend infrastructure. Sign up at iapkit.com to get your API key and start verifying purchases in minutes.
Key Benefitsβ
| Benefit | Description | |
|---|---|---|
| π | Security First | Server-side validation that prevents fraud, receipt tampering, and token reuse. Far more secure than client-only verification. |
| π | Unified API | Single endpoint for both Apple App Store and Google Play. No separate validation logic needed. |
| β‘ | Zero Infrastructure | No server setup required. IAPKit handles Apple and Google API complexity for you. |
| π | Production Ready | Enterprise-grade reliability with comprehensive error handling and detailed responses. |
Getting Startedβ
Use the new verifyPurchaseWithProvider API to verify purchases through IAPKit:
import { verifyPurchaseWithProvider } from 'expo-iap';
// Note: apiKey is automatically injected from config plugin (iapkitApiKey)
// No need to manually pass it - expo-iap reads it from Constants.expoConfig.extra.iapkitApiKey
const result = await verifyPurchaseWithProvider({
provider: 'iapkit',
iapkit: {
// apiKey is auto-filled from config plugin
apple: {
jws: purchase.purchaseToken, // JWS from purchase
},
google: {
purchaseToken: purchase.purchaseToken,
},
},
});
if (result.iapkit?.isValid) {
// Purchase verified - grant entitlement
console.log('Purchase state:', result.iapkit.state);
console.log('Store:', result.iapkit.store);
}
The API returns a VerifyPurchaseWithProviderResult with provider-specific results:
iapkit.isValid- Whether the purchase passed verificationiapkit.state- Detailed purchase state (entitled, pending, expired, etc.)iapkit.store- The store where the purchase was made (apple, google, horizon)
Installationβ
bun add expo-iap@3.2.0
# or
npm install expo-iap@3.2.0
# or
yarn add expo-iap@3.2.0
Config Plugin (v3.2.1+)β
Starting from v3.2.1, you can provide your IAPKit API key through the config plugin:
{
"expo": {
"plugins": [
[
"expo-iap",
{
"iapkitApiKey": "your-iapkit-api-key"
}
]
]
}
}
The apiKey is automatically injected from the config plugin - no need to manually pass it:
import { verifyPurchaseWithProvider } from 'expo-iap';
// The `purchase` object is received from the `onPurchaseSuccess` callback
// apiKey is auto-filled from config plugin
const result = await verifyPurchaseWithProvider({
provider: 'iapkit',
iapkit: {
apple: { jws: purchase.purchaseToken },
google: { purchaseToken: purchase.purchaseToken },
},
});
This approach keeps your API key out of source code and allows easy configuration per environment.
Referencesβ
Questions or feedback? Reach out via GitHub issues.
