This release syncs with OpenIAP v1.3.14, introducing iOS 18+ win-back offers, JWS promotional offers, Android 8.0+ product status codes, and important type cleanup.
New Features
Win-Back Offers (iOS 18+)
Win-back offers allow you to re-engage churned subscribers with special discounts or free trials.
import {requestPurchase} from 'expo-iap';
await requestPurchase({
request: {
apple: {
sku: 'premium_monthly',
winBackOffer: {
offerId: 'winback_50_off',
},
},
},
type: 'subs',
});
Win-back offers are automatically presented via StoreKit Message when eligible, or can be applied programmatically.
A new simplified format for promotional offers using compact JWS strings, back-deployed to iOS 15.
await requestPurchase({
request: {
apple: {
sku: 'premium_yearly',
promotionalOfferJWS: {
offerId: 'promo_20_off',
jws: 'eyJhbGciOiJFUzI1NiI...',
},
},
},
type: 'subs',
});
Introductory Offer Eligibility Override (iOS 15+)
Override system-determined introductory offer eligibility.
await requestPurchase({
request: {
apple: {
sku: 'premium_monthly',
introductoryOfferEligibility: true,
},
},
type: 'subs',
});
Product Status Codes (Android 8.0+)
Get detailed feedback on why products couldn't be fetched.
import {fetchProducts} from 'expo-iap';
import type {ProductAndroid} from 'expo-iap';
const result = await fetchProducts({
skus: ['product_1', 'product_2'],
type: 'in-app',
});
result.forEach((product) => {
const androidProduct = product as ProductAndroid;
if (androidProduct.productStatusAndroid) {
switch (androidProduct.productStatusAndroid) {
case 'ok':
break;
case 'not-found':
break;
case 'no-offers-available':
break;
}
}
});
Suspended Subscriptions Support (Android 8.1+)
Include suspended subscriptions when fetching available purchases. This feature required native code updates to pass the option through to the OpenIAP SDK.
import {getAvailablePurchases} from 'expo-iap';
const purchases = await getAvailablePurchases({
includeSuspendedAndroid: true,
});
purchases.forEach((purchase) => {
if (purchase.isSuspendedAndroid) {
}
});
Important: Suspended subscriptions should NOT be granted entitlements. Users should be directed to the Play Store subscription center to resolve payment issues.
Sub-Response Codes (Android 8.0+)
More granular error information for purchase failures.
Type Cleanup
Subscription-Only Fields Removed from RequestPurchaseIosProps
The following fields have been removed from RequestPurchaseIosProps because they only apply to subscription purchases:
winBackOffer - Win-back offers are subscription-only (iOS 18+)
promotionalOfferJWS - JWS promotional offers are subscription-only
introductoryOfferEligibility - Introductory eligibility is subscription-only
These fields remain available in RequestSubscriptionIosProps where they belong.
Migration: If you were incorrectly using these fields with one-time purchases, move them to subscription purchases with type: 'subs'.
New Types
| Type | Platform | Description |
|---|
WinBackOfferInputIOS | iOS 18+ | Win-back offer configuration |
PromotionalOfferJwsInputIOS | iOS 15+ | JWS promotional offer input |
ProductStatusAndroid | Android 8.0+ | Product fetch status codes |
SubResponseCodeAndroid | Android 8.0+ | Granular purchase error codes |
BillingResultAndroid | Android 8.0+ | Extended billing result with sub-response |
Updated Types
SubscriptionOfferTypeIOS now includes 'win-back' type
RequestSubscriptionIosProps now supports:
winBackOffer
promotionalOfferJWS
introductoryOfferEligibility
withOffer (promotional offer)
PurchaseOptions now supports includeSuspendedAndroid
ProductAndroid and ProductSubscriptionAndroid now include productStatusAndroid
OpenIAP Versions
| Package | Version |
|---|
| openiap-gql | 1.3.14 |
| openiap-google | 1.3.25 |
| openiap-apple | 1.3.13 |
For detailed changes, see the OpenIAP Release Notes.