14.7.4 - Android Input Type Field Naming Simplification
This release simplifies field naming in Android input types (RequestPurchaseAndroidProps and RequestSubscriptionAndroidProps). Since these types are already Android-specific, their fields no longer need the Android suffix.
Breaking Changes
Simplified Field Names in Android Input Types
Fields inside platform-specific input types no longer require the platform suffix. The parent type name already indicates the platform context.
Why this change?
When you write google: { offerToken: "..." }, the google key already tells you this is Android-specific. Adding Android suffix to fields inside is redundant:
// Redundant - we know it's Android from the parent
google: { offerTokenAndroid: "..." }
// Cleaner - parent context is sufficient
google: { offerToken: "..." }
Migration Guide
| Old Name (v14.7.3) | New Name (v14.7.4) |
|---|---|
obfuscatedAccountIdAndroid | obfuscatedAccountId |
obfuscatedProfileIdAndroid | obfuscatedProfileId |
purchaseTokenAndroid | purchaseToken |
replacementModeAndroid | replacementMode |
Before (v14.7.3):
await requestPurchase({
request: {
google: {
skus: ['subscription_id'],
subscriptionOffers: [{sku: 'subscription_id', offerToken: 'token'}],
purchaseTokenAndroid: currentPurchaseToken,
replacementModeAndroid: 1,
obfuscatedAccountIdAndroid: 'user_123',
},
},
type: 'subs',
});
After (v14.7.4):
await requestPurchase({
request: {
google: {
skus: ['subscription_id'],
subscriptionOffers: [{sku: 'subscription_id', offerToken: 'token'}],
purchaseToken: currentPurchaseToken,
replacementMode: 1,
obfuscatedAccountId: 'user_123',
},
},
type: 'subs',
});
Important: Response Types Keep Suffixes
The suffix removal only applies to input types (request parameters). Response types still use suffixes because they're cross-platform:
// Response fields KEEP the Android suffix
const purchase = purchases[0] as PurchaseAndroid;
// These response fields still have Android suffix
console.log(purchase.purchaseTokenAndroid); // Keep suffix
console.log(purchase.obfuscatedAccountIdAndroid); // Keep suffix
// But input fields don't need it anymore
await requestPurchase({
request: {
google: {
skus: [product.id],
obfuscatedAccountId: 'user_123', // Input: no suffix
},
},
type: 'in-app',
});
New Features
One-Time Purchase Discount Offers (Android 7.0+)
This release adds support for discount offers on one-time (in-app) purchases:
import {fetchProducts, requestPurchase} from 'react-native-iap';
import type {ProductAndroid} from 'react-native-iap';
// 1. Fetch products with discount offers
const products = await fetchProducts({
skus: ['premium_upgrade'],
type: 'in-app',
});
const product = products[0] as ProductAndroid;
// 2. Get the discount offer
const discountOffer = product.discountOffers?.[0];
// 3. Purchase with the discount
if (discountOffer?.offerTokenAndroid) {
await requestPurchase({
request: {
google: {
skus: [product.id],
offerToken: discountOffer.offerTokenAndroid, // Use simplified input field
},
},
type: 'in-app',
});
}
Naming Convention Summary
| Field Location | Suffix Required? | Example |
|---|---|---|
Inside RequestPurchaseAndroidProps | NO | offerToken |
Inside RequestSubscriptionAndroidProps | NO | purchaseToken |
| Cross-platform response type | YES | PurchaseAndroid.purchaseTokenAndroid |
OpenIAP Versions
| Package | Version |
|---|---|
| openiap-gql | 1.3.15 |
| openiap-google | 1.3.26 |
| openiap-apple | 1.3.13 |
For detailed changes, see the OpenIAP Release Notes.
