Skip to main content
Version: 3.3 (Current)

Android Specific APIs

The following Android‑only helpers expose Google Play Billing specific capabilities. Most day‑to‑day flows are covered by the cross‑platform Unified APIs; use these only when you need Android-specific features.

Billing Programs API (8.2.0+)

New in Google Play Billing Library 8.2.0, the Billing Programs API provides a unified way to handle external billing programs:

isBillingProgramAvailableAndroid()

Check if a specific billing program is available for the current user.

import {isBillingProgramAvailableAndroid} from 'expo-iap';

const result = await isBillingProgramAvailableAndroid('external-offer');
if (result.isAvailable) {
console.log('External offer program is available');
} else {
console.log('External offer program not available for this user');
}

Parameters:

  • program (BillingProgramAndroid): The billing program to check
    • 'external-offer' - External offer programs
    • 'external-content-link' - External content link programs

Returns: Promise<BillingProgramAvailabilityResultAndroid>

interface BillingProgramAvailabilityResultAndroid {
billingProgram: BillingProgramAndroid;
isAvailable: boolean;
}

Platform: Android 8.2.0+

launchExternalLinkAndroid()

Launch an external link for the specified billing program. This opens the external purchase flow.

import {launchExternalLinkAndroid} from 'expo-iap';

await launchExternalLinkAndroid({
billingProgram: 'external-offer',
launchMode: 'launch-in-external-browser-or-app',
linkType: 'link-to-digital-content-offer',
linkUri: 'https://your-payment-site.com/offer',
});

Parameters:

  • params (LaunchExternalLinkParamsAndroid):
    • billingProgram: The billing program type
    • launchMode: How to launch the external link
      • 'launch-in-external-browser-or-app' - Launch in external browser
      • 'caller-will-launch-link' - App will handle launching
    • linkType: The type of external link
      • 'link-to-digital-content-offer' - Digital content offer
      • 'link-to-app-download' - App download link
    • linkUri: The URI to launch

Returns: Promise<void>

Platform: Android 8.2.0+

createBillingProgramReportingDetailsAndroid()

Get the external transaction token for reporting transactions made outside of Google Play.

import {createBillingProgramReportingDetailsAndroid} from 'expo-iap';

const details = await createBillingProgramReportingDetailsAndroid('external-offer');
console.log('Token:', details.externalTransactionToken);

// Report this token to Google Play within 24 hours
await reportToGooglePlayBackend(details.externalTransactionToken);

Parameters:

  • program (BillingProgramAndroid): The billing program type

Returns: Promise<BillingProgramReportingDetailsAndroid>

interface BillingProgramReportingDetailsAndroid {
billingProgram: BillingProgramAndroid;
externalTransactionToken: string;
}

Platform: Android 8.2.0+

Important:

  • Token must be reported to Google Play backend within 24 hours
  • Requires server-side integration with Google Play Developer API
  • Failure to report will result in refund and possible account suspension

Complete Billing Programs Flow Example

import {
isBillingProgramAvailableAndroid,
launchExternalLinkAndroid,
createBillingProgramReportingDetailsAndroid,
} from 'expo-iap';

async function purchaseWithBillingProgram(productId: string) {
// Step 1: Check availability
const availability = await isBillingProgramAvailableAndroid('external-offer');
if (!availability.isAvailable) {
throw new Error('External offer program not available');
}

// Step 2: Launch external link
await launchExternalLinkAndroid({
billingProgram: 'external-offer',
launchMode: 'launch-in-external-browser-or-app',
linkType: 'link-to-digital-content-offer',
linkUri: `https://your-payment-site.com/purchase/${productId}`,
});

// Step 3: After payment completes, get reporting token
const details = await createBillingProgramReportingDetailsAndroid('external-offer');

// Step 4: Report to Google (must be done within 24 hours)
await reportToGooglePlayBackend(details.externalTransactionToken, productId);

return {success: true, token: details.externalTransactionToken};
}

See also:


Alternative Billing (Legacy)

Deprecated

The following methods are deprecated in favor of the Billing Programs API. They will continue to work but you should migrate to the new API.

Purchase Management

checkAlternativeBillingAvailabilityAndroid()

Deprecated

Check if alternative billing is available for the current user. This must be called before showing the alternative billing dialog.

import {checkAlternativeBillingAvailabilityAndroid} from 'expo-iap';

const isAvailable = await checkAlternativeBillingAvailabilityAndroid();
if (isAvailable) {
console.log('Alternative billing is available');
} else {
console.log('Alternative billing not available for this user');
}

Returns: Promise<boolean>

Platform: Android

Requirements:

  • Must initialize connection with alternative billing mode
  • User must be eligible for alternative billing (determined by Google)

See also: Google Play Alternative Billing documentation

showAlternativeBillingDialogAndroid()

Deprecated

Show Google's required information dialog to inform users about alternative billing. This must be called after checking availability and before processing payment.

import {showAlternativeBillingDialogAndroid} from 'expo-iap';

const userAccepted = await showAlternativeBillingDialogAndroid();
if (userAccepted) {
console.log('User accepted alternative billing');
// Proceed with your payment flow
} else {
console.log('User declined alternative billing');
}

Returns: Promise<boolean>

Platform: Android

Note: This dialog is required by Google Play's alternative billing policy. You must show this before redirecting users to your payment system.

createAlternativeBillingTokenAndroid()

Generate a reporting token after successfully processing payment through your payment system. This token must be reported to Google Play within 24 hours.

import {createAlternativeBillingTokenAndroid} from 'expo-iap';

// After successfully processing payment in your system
const token = await createAlternativeBillingTokenAndroid('com.example.product');

if (token) {
console.log('Token created:', token);
// Send this token to your backend to report to Google
await reportTokenToGooglePlay(token);
} else {
console.error('Failed to create token');
}

Parameters:

  • sku (string, optional): The product SKU that was purchased

Returns: Promise<string | null>

Platform: Android

Important:

  • Token must be reported to Google Play backend within 24 hours
  • Requires server-side integration with Google Play Developer API
  • Failure to report will result in refund and possible account suspension

Alternative Billing Configuration

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

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

// To change mode, reinitialize
await endConnection();
await initConnection({
alternativeBillingModeAndroid: 'alternative-only',
});

Billing Modes:

  • user-choice - Users choose between Google Play billing or your payment system
  • alternative-only - Only your payment system is available

Complete Flow Example (Legacy)

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

async function purchaseWithAlternativeBilling(productId: string) {
// Step 1: Check availability
const isAvailable = await checkAlternativeBillingAvailabilityAndroid();
if (!isAvailable) {
throw new Error('Alternative billing not available');
}

// Step 2: Show required dialog
const userAccepted = await showAlternativeBillingDialogAndroid();
if (!userAccepted) {
throw new Error('User declined alternative billing');
}

// Step 3: Process payment in your system
const paymentResult = await processPaymentInYourSystem(productId);
if (!paymentResult.success) {
throw new Error('Payment failed');
}

// Step 4: Create reporting token
const token = await createAlternativeBillingTokenAndroid(productId);
if (!token) {
throw new Error('Failed to create token');
}

// Step 5: Report to Google (must be done within 24 hours)
await reportToGooglePlayBackend(token, productId, paymentResult);

return {success: true, token};
}

See also:


Purchase Acknowledgment & Consumption

acknowledgePurchaseAndroid()

Acknowledge a non‑consumable purchase or subscription on Android.

import {acknowledgePurchaseAndroid} from 'expo-iap';

await acknowledgePurchaseAndroid({token: purchase.purchaseToken!});

Notes:

  • finishTransaction() calls this automatically when isConsumable is false. You typically do not need to call it directly.

consumePurchaseAndroid()

Consume a purchase (consumables only). This marks an item as consumed so it can be purchased again.

Notes:

  • finishTransaction() calls Android consumption automatically when isConsumable is true.
  • A direct JS helper is not exposed; consumption is handled internally via the native module.

flushFailedPurchasesCachedAsPendingAndroid (Removed)

This legacy helper from older libraries has been removed. The modern flow is:

// On app startup (Android)
const purchases = await getAvailablePurchases();

for (const p of purchases) {
if (/* consumable */) {
// finishTransaction will consume on Android when isConsumable is true
await finishTransaction({ purchase: p, isConsumable: true });
} else {
// finishTransaction will acknowledge on Android when isConsumable is false
await finishTransaction({ purchase: p, isConsumable: false });
}
}

This ensures pending transactions are surfaced and properly resolved without a separate "flush" API.