Skip to main content

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

๐Ÿš€ Highlightsโ€‹

iOS Alternative Billing (StoreKit External Purchase)โ€‹

Three new APIs for managing external purchases on iOS:

Expo Config Plugin Support: The new iosAlternativeBilling configuration automatically sets up required Info.plist keys and entitlements:

// app.config.ts
export default {
plugins: [
[
'expo-iap',
{
iosAlternativeBilling: {
countries: ['kr', 'nl'], // ISO 3166-1 alpha-2
links: {
kr: 'https://your-site.com/kr',
nl: 'https://your-site.com/nl',
},
enableExternalPurchaseLink: true,
},
},
],
],
};

The plugin handles:

  • SKExternalPurchase - Country codes where external purchases are supported
  • SKExternalPurchaseLink - External purchase URLs per country (iOS 15.4+)
  • SKExternalPurchaseMultiLink - Multiple URLs per country (iOS 17.5+)
  • SKExternalPurchaseCustomLinkRegions - Custom link regions (iOS 18.1+)
  • SKExternalPurchaseLinkStreamingRegions - Streaming regions for music apps (iOS 18.2+)
  • StoreKit entitlements: com.apple.developer.storekit.external-purchase*

Android Alternative Billingโ€‹

Three new APIs for Google Play Alternative Billing flow:

Configuration Support: initConnection() now accepts an optional config parameter:

import {initConnection} from 'expo-iap';

// Initialize with alternative billing mode
await initConnection({
alternativeBillingModeAndroid: 'user-choice', // or 'alternative-only'
});

Two Billing Modes:

  • user-choice - Users choose between Google Play billing (30% fee) or your payment system (lower fee)
  • alternative-only - Only your payment system is available (Google Play billing disabled)

๐Ÿ“š Usage Examplesโ€‹

iOS External Purchaseโ€‹

import {presentExternalPurchaseLinkIOS} from 'expo-iap';

// Redirect user to external purchase website
const result = await presentExternalPurchaseLinkIOS(
'https://your-site.com/checkout',
);

if (result.success) {
console.log('User redirected to external website');
}

Android Alternative Billingโ€‹

User Choice Mode - When using user-choice mode, listen for user selection with userChoiceBillingListenerAndroid():

import {initConnection, userChoiceBillingListenerAndroid} from 'expo-iap';

// Initialize with user-choice mode
await initConnection({
alternativeBillingModeAndroid: 'user-choice',
});

// Listen for when user selects alternative billing
const subscription = userChoiceBillingListenerAndroid((details) => {
console.log('User selected alternative billing');
console.log('Token:', details.externalTransactionToken);
console.log('Products:', details.products);

// Process payment in your system, then report token to Google
await processPaymentAndReportToken(details);
});

// Clean up when done
subscription.remove();

Alternative Only Mode - Manual 3-step flow:

import {
checkAlternativeBillingAvailabilityAndroid,
showAlternativeBillingDialogAndroid,
createAlternativeBillingTokenAndroid,
} from 'expo-iap';

// Step 1: Check availability
const isAvailable = await checkAlternativeBillingAvailabilityAndroid();

// Step 2: Show Google's information dialog
const userAccepted = await showAlternativeBillingDialogAndroid();

if (userAccepted) {
// Step 3: Process payment in your system, then create token
const token = await createAlternativeBillingTokenAndroid(productId);

// Step 4: Report token to Google Play backend within 24 hours
await reportTokenToGooglePlay(token);
}

๐ŸŽจ Example Appโ€‹

A complete alternative billing demo screen has been added to the example app:

  • Platform-specific flows - Demonstrates iOS and Android alternative billing patterns
  • Billing mode toggle (Android) - Switch between alternative-only and user-choice with auto-reconnect
  • External URL input (iOS) - Configure and test external purchase links
  • Real-time results - View purchase flow status and responses
  • Step-by-step guidance - Visual flow diagrams for both platforms

Navigate to example/app/alternative-billing.tsx to explore the implementation.

๐Ÿ”ง OpenIAP Upgradesโ€‹

  • openiap-apple upgraded to 1.2.10 with StoreKit external purchase support
  • openiap-google upgraded to 1.2.12 with alternative billing APIs
  • openiap-gql upgraded to 1.0.12 with updated type definitions

๐Ÿงช Testingโ€‹

Added 30+ comprehensive tests for the iOS config plugin:

  • Info.plist configuration validation
  • Entitlements setup verification
  • URL validation and country code checks
  • Edge case handling

All existing tests continue to pass with 98%+ coverage.

โš ๏ธ Platform Requirementsโ€‹

iOSโ€‹

  • Minimum Version: iOS 16.0+ for external purchase links, iOS 18.2+ for notice sheet
  • App Store Connect: Must request and receive approval for external purchase entitlements
  • Provisioning Profile: Must include StoreKit external purchase entitlements
  • See StoreKit External Purchase documentation

Androidโ€‹

  • Google Play Console: Must be approved for alternative billing program
  • Token Reporting: Must report tokens to Google within 24 hours
  • Backend Integration: Server-side validation and reporting required
  • See Google Play Alternative Billing documentation

๐Ÿ“ฆ Installationโ€‹

bun add expo-iap@3.1.9
# or
npm install expo-iap@3.1.9
# or
yarn add expo-iap@3.1.9

After installation, run prebuild to apply iOS config plugin changes:

npx expo prebuild --clean

๐Ÿšจ Important Notesโ€‹

For iOS Developersโ€‹

Alternative billing on iOS requires explicit approval from Apple. During development:

  1. Keep iosAlternativeBilling commented out in your config
  2. Test regular IAP flows without entitlements
  3. When ready for production, uncomment the config and follow Apple's approval process

For Android Developersโ€‹

Alternative billing on Android requires:

  1. Approval from Google Play Console
  2. Backend integration to report tokens within 24 hours
  3. Proper error handling for users not eligible for alternative billing

No Breaking Changes: All changes are additive. Existing apps will continue to work without modifications.

๐Ÿ”— Referencesโ€‹

Questions or issues? Let us know via GitHub issues.