3.3.5 - External Payments Program (Japan)
· 3 min read
Expo IAP 3.3.5 brings Google Play Billing Library 8.3.0 support with the new External Payments program for Japan.
New Features
External Payments Program (Android 8.3.0+, Japan Only)
The External Payments program introduces a side-by-side choice between Google Play Billing and the developer's external payment option directly in the purchase flow.
Key Differences from User Choice Billing
| Feature | User Choice Billing | External Payments |
|---|---|---|
| Billing Library | 7.0+ | 8.3.0+ |
| Availability | Eligible regions | Japan only |
| When presented | After initConnection() | During requestPurchase() |
| UI | Separate dialog | Side-by-side choice in purchase dialog |
| Listener | userChoiceBillingListenerAndroid | developerProvidedBillingListenerAndroid |
New APIs
developerProvidedBillingListenerAndroid()
New listener that fires when a user selects the developer's payment option in the External Payments dialog.
import {developerProvidedBillingListenerAndroid} from 'expo-iap';
const subscription = developerProvidedBillingListenerAndroid(async (details) => {
console.log('User selected developer billing');
console.log('Token:', details.externalTransactionToken);
// Process payment with your gateway
await processPaymentWithYourGateway(details.externalTransactionToken);
// IMPORTANT: Report to Google within 24 hours
await reportExternalTransactionToGoogle(details.externalTransactionToken);
});
// Clean up
subscription.remove();
OpenIapEvent.DeveloperProvidedBillingAndroid
New event type for the External Payments flow.
import {OpenIapEvent} from 'expo-iap';
// Event: 'developer-provided-billing-android'
console.log(OpenIapEvent.DeveloperProvidedBillingAndroid);
BillingProgramAndroid.ExternalPayments
New billing program type for External Payments.
import {isBillingProgramAvailableAndroid} from 'expo-iap';
// Check if External Payments is available (Japan only)
const result = await isBillingProgramAvailableAndroid('external-payments');
if (result.isAvailable) {
// External Payments is available for this user
}
New Types
// Developer billing option for purchase requests
interface DeveloperBillingOptionParamsAndroid {
billingProgram: BillingProgramAndroid; // should be 'external-payments'
linkUri: string;
launchMode: DeveloperBillingLaunchModeAndroid;
}
// Launch mode options
type DeveloperBillingLaunchModeAndroid =
| 'unspecified'
| 'launch-in-external-browser-or-app'
| 'caller-will-launch-link';
// Details received when user selects developer billing
interface DeveloperProvidedBillingDetailsAndroid {
externalTransactionToken: string;
}
// Updated BillingProgramAndroid
type BillingProgramAndroid =
| 'unspecified'
| 'external-content-link'
| 'external-offer'
| 'external-payments'; // New in 8.3.0
Complete External Payments Flow Example
import {useEffect} from 'react';
import {
initConnection,
isBillingProgramAvailableAndroid,
developerProvidedBillingListenerAndroid,
requestPurchase,
} from 'expo-iap';
import {Platform} from 'react-native';
export default function ExternalPaymentsComponent() {
useEffect(() => {
if (Platform.OS !== 'android') return;
const initialize = async () => {
// Initialize with External Payments program
await initConnection({
enableBillingProgramAndroid: 'external-payments',
});
// Check availability (Japan only)
const result = await isBillingProgramAvailableAndroid('external-payments');
if (!result.isAvailable) {
console.log('External Payments not available');
return;
}
// Set up listener for when user selects developer billing
const subscription = developerProvidedBillingListenerAndroid(
async (details) => {
console.log('User selected developer billing');
// Process payment with your gateway
await processPayment(details.externalTransactionToken);
// Report to Google within 24 hours
await reportToGoogle(details.externalTransactionToken);
},
);
return () => subscription.remove();
};
const cleanup = initialize();
return () => {
cleanup.then((fn) => fn?.());
};
}, []);
const purchaseWithExternalPayments = async (sku: string) => {
// Request purchase with developer billing option
await requestPurchase({
request: {
google: {
skus: [sku],
developerBillingOption: {
billingProgram: 'external-payments',
linkUri: 'https://your-payment-site.com/checkout',
launchMode: 'launch-in-external-browser-or-app',
},
},
},
type: 'in-app',
});
};
// Rest of component
}
OpenIAP Updates
- openiap-google: 1.3.16 → 1.3.18
- openiap-gql: 1.3.8 → 1.3.9
Installation
bun add expo-iap@3.3.5
# or
npm install expo-iap@3.3.5
# or
yarn add expo-iap@3.3.5
References
Questions or feedback? Reach out via GitHub issues.
