Skip to main content

7 posts tagged with "iOS"

iOS platform specific features

View All Tags

v3.4.3 - Win-Back Offers & Advanced Billing Features

· 3 min read
Hyo
Expo IAP Maintainer

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';

// Apply a win-back offer during subscription purchase
await requestPurchase({
request: {
apple: {
sku: 'premium_monthly',
winBackOffer: {
offerId: 'winback_50_off', // iOS 18+
},
},
},
type: 'subs',
});

Win-back offers are automatically presented via StoreKit Message when eligible, or can be applied programmatically.

JWS Promotional Offers (iOS 15+)

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...', // Server-signed JWS
},
},
},
type: 'subs',
});

Introductory Offer Eligibility Override (iOS 15+)

Override system-determined introductory offer eligibility.

await requestPurchase({
request: {
apple: {
sku: 'premium_monthly',
introductoryOfferEligibility: true, // Force eligible
},
},
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':
// Product available
break;
case 'not-found':
// SKU doesn't exist in Play Console
break;
case 'no-offers-available':
// User not eligible for any offers
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, // Include suspended subs
});

// Check if subscription is suspended
purchases.forEach((purchase) => {
if (purchase.isSuspendedAndroid) {
// Direct user to resolve payment issues
// Do NOT grant entitlements for suspended subscriptions
}
});

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.

// SubResponseCodeAndroid provides additional context:
// - 'no-applicable-sub-response-code'
// - 'payment-declined-due-to-insufficient-funds'
// - 'user-ineligible'

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

TypePlatformDescription
WinBackOfferInputIOSiOS 18+Win-back offer configuration
PromotionalOfferJwsInputIOSiOS 15+JWS promotional offer input
ProductStatusAndroidAndroid 8.0+Product fetch status codes
SubResponseCodeAndroidAndroid 8.0+Granular purchase error codes
BillingResultAndroidAndroid 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

PackageVersion
openiap-gql1.3.14
openiap-google1.3.25
openiap-apple1.3.13

For detailed changes, see the OpenIAP Release Notes.

3.1.9 - Alternative Billing Support

· 5 min read
Hyo
Expo IAP Maintainer

Expo IAP 3.1.9 introduces Alternative Billing support for both iOS and Android platforms, enabling developers to offer external payment options in compliance with App Store and Google Play requirements.

This release integrates StoreKit External Purchase APIs (iOS 16.0+) and Google Play Alternative Billing APIs, providing a unified interface for alternative payment flows across platforms.

👉 View the 3.1.9 release

3.1.0 - Full OpenIAP Ecosystem Adoption

· 4 min read
Hyo
Expo IAP Maintainer

Expo IAP 3.1.0 graduates the project into the full OpenIAP ecosystem. The release ships with three dedicated native stacks:

From 3.1.0 onward, Expo IAP stays in lockstep with these modules: Apple v1.2.2, Google v1.2.6, and GQL v1.0.8. That shared version alignment gives Expo IAP stable native compatibility and a unified type system straight from the OpenIAP schema.

👉 View the 3.1.0 release