Skip to main content
Version: 3.1

iOS Specific APIs

The following iOS‑only helpers expose StoreKit and App Store specific capabilities. Most day‑to‑day flows are covered by the cross‑platform Unified APIs; use these only when you need iOS features.

Alternative Billing (iOS 16.0+)

Transaction Management

clearTransactionIOS()

Clears all pending transactions from the iOS payment queue. Useful if your app previously crashed or missed finishing transactions.

import {clearTransactionIOS, getPendingTransactionsIOS} from 'expo-iap';

// Inspect then clear
const pending = await getPendingTransactionsIOS();
if (pending.length) {
await clearTransactionIOS();
}

Returns: Promise<void>

getPromotedProductIOS()

Gets the currently promoted product, if any. Requires iOS 11+.

import {getPromotedProductIOS} from 'expo-iap';

const promoted = await getPromotedProductIOS();
if (promoted) {
// Show your purchase UI for the promoted product
}

Returns: Promise<Product | null>

requestPurchaseOnPromotedProductIOS()

Initiates the purchase flow for the currently promoted product. Requires iOS 11+.

import {requestPurchaseOnPromotedProductIOS} from 'expo-iap';

await requestPurchaseOnPromotedProductIOS();
// Purchase result is delivered via purchase listeners/useIAP callbacks

Returns: Promise<void>

getPendingTransactionsIOS()

Returns all transactions that are pending completion in the StoreKit payment queue.

import {getPendingTransactionsIOS} from 'expo-iap';

const pending = await getPendingTransactionsIOS();

Returns: Promise<Purchase[]>

isEligibleForIntroOfferIOS()

Checks if the user is eligible for an introductory offer for a subscription group. Requires iOS 12.2+.

import {isEligibleForIntroOfferIOS, fetchProducts} from 'expo-iap';

// Example: derive group ID from a fetched subscription product
const [sub] = await fetchProducts({skus: ['your_sub_sku'], type: 'subs'});
const groupId = sub?.subscriptionInfoIOS?.subscriptionGroupId ?? '';
const eligible = groupId ? await isEligibleForIntroOfferIOS(groupId) : false;

Returns: Promise<boolean>

subscriptionStatusIOS()

Returns detailed subscription status information using StoreKit 2. Requires iOS 15+.

import {subscriptionStatusIOS} from 'expo-iap';

const statuses = await subscriptionStatusIOS('your_sub_sku');

Returns: Promise<SubscriptionStatusIOS[]>

currentEntitlementIOS()

Returns the current entitlement for a given SKU using StoreKit 2. Requires iOS 15+.

import {currentEntitlementIOS} from 'expo-iap';

const entitlement = await currentEntitlementIOS('your_sub_or_product_sku');

Returns: Promise<Purchase | null>

latestTransactionIOS()

Returns the most recent transaction for a given SKU using StoreKit 2. Requires iOS 15+.

import {latestTransactionIOS} from 'expo-iap';

const last = await latestTransactionIOS('your_sku');

Returns: Promise<Purchase | null>

showManageSubscriptionsIOS()

Opens the native subscription management interface and returns purchases for subscriptions whose auto‑renewal status changed while the sheet was open. Requires iOS 15+.

import {showManageSubscriptionsIOS} from 'expo-iap';

const changed = await showManageSubscriptionsIOS();
if (changed.length > 0) {
// Update your UI / server using returned purchases
}

Returns: Promise<Purchase[]>

beginRefundRequestIOS()

Presents the refund request sheet for a specific SKU. Requires iOS 15+.

import {beginRefundRequestIOS} from 'expo-iap';

const status = await beginRefundRequestIOS('your_sku');
// status: 'success' | 'userCancelled'

Returns: Promise<'success' | 'userCancelled'>

isTransactionVerifiedIOS()

Verifies the latest transaction for a given SKU using StoreKit 2. Requires iOS 15+.

import {isTransactionVerifiedIOS} from 'expo-iap';

const ok = await isTransactionVerifiedIOS('your_sku');

Returns: Promise<boolean>

getTransactionJwsIOS()

Returns the JSON Web Signature (JWS) for a transaction derived from a given SKU. Use this for server‑side validation. Requires iOS 15+.

import {getTransactionJwsIOS} from 'expo-iap';

const jws = await getTransactionJwsIOS('your_sku');

Returns: Promise<string>

getReceiptDataIOS()

Returns the base64‑encoded receipt data for server validation.

import {getReceiptDataIOS} from 'expo-iap';

const receipt = await getReceiptDataIOS();

Returns: Promise<string>

syncIOS()

Forces a sync with StoreKit to ensure all transactions are up to date. Requires iOS 15+.

import {syncIOS} from 'expo-iap';

await syncIOS();

Returns: Promise<void>

presentCodeRedemptionSheetIOS()

Presents the system sheet for redeeming App Store promo/offer codes.

import {presentCodeRedemptionSheetIOS} from 'expo-iap';

await presentCodeRedemptionSheetIOS();

Returns: Promise<boolean>

getAppTransactionIOS()

Gets app transaction information for iOS apps (iOS 16.0+). AppTransaction represents the initial purchase that unlocked the app, useful for premium apps or apps that were previously paid.

Runtime: iOS 16.0+; Build: Xcode 15.0+ with iOS 16.0 SDK. Older SDKs will throw.

import {getAppTransactionIOS} from 'expo-iap';

const fetchAppTransaction = async () => {
try {
const appTransaction = await getAppTransactionIOS();
if (appTransaction) {
console.log('App Transaction ID:', appTransaction.appTransactionId);
console.log(
'Original Purchase Date:',
new Date(appTransaction.originalPurchaseDate),
);
console.log('Device Verification:', appTransaction.deviceVerification);
}
} catch (error) {
console.error('Failed to get app transaction:', error);
}
};

Returns: Promise<AppTransaction | null>

interface AppTransaction {
appTransactionId?: string; // iOS 18.4+
originalPlatform?: string; // iOS 18.4+
bundleId: string;
appVersion: string;
originalAppVersion: string;
originalPurchaseDate: number; // ms since epoch
deviceVerification: string;
deviceVerificationNonce: string;
environment: string;
signedDate: number;
appId?: number;
appVersionId?: number;
preorderDate?: number;
}

canPresentExternalPurchaseNoticeIOS()

Check if the device can present an external purchase notice sheet. Requires iOS 18.2+.

import {canPresentExternalPurchaseNoticeIOS} from 'expo-iap';

const canPresent = await canPresentExternalPurchaseNoticeIOS();
if (canPresent) {
console.log('External purchase notice sheet is available');
}

Returns: Promise<boolean>

Platform: iOS 18.2+

Note: This notice sheet must be presented before redirecting users to external purchase links on iOS 18.2+.

presentExternalPurchaseNoticeSheetIOS()

Present an external purchase notice sheet to inform users about external purchases. This must be called before opening an external purchase link on iOS 18.2+.

import {presentExternalPurchaseNoticeSheetIOS} from 'expo-iap';

const result = await presentExternalPurchaseNoticeSheetIOS();

if (result.error) {
console.error('Failed to present notice:', result.error);
} else if (result.result === 'continue') {
// User chose to continue to external purchase
console.log('User accepted external purchase notice');
} else if (result.result === 'dismissed') {
// User dismissed the sheet
console.log('User dismissed notice');
}

Returns: Promise<ExternalPurchaseNoticeResultIOS>

interface ExternalPurchaseNoticeResultIOS {
error: string | null;
result: 'continue' | 'dismissed';
}

Platform: iOS 18.2+

See also: StoreKit External Purchase documentation

presentExternalPurchaseLinkIOS()

Open an external purchase link in Safari to redirect users to your website for purchase. Requires iOS 16.0+.

import {presentExternalPurchaseLinkIOS} from 'expo-iap';

const result = await presentExternalPurchaseLinkIOS(
'https://your-site.com/checkout',
);

if (result.error) {
console.error('Failed to open link:', result.error);
} else if (result.success) {
console.log('User redirected to external purchase website');
}

Parameters:

  • url (string): The external purchase URL to open

Returns: Promise<ExternalPurchaseLinkResultIOS>

interface ExternalPurchaseLinkResultIOS {
error: string | null;
success: boolean;
}

Platform: iOS 16.0+

Requirements:

  • Must configure iosAlternativeBilling in your Expo config plugin
  • Requires Apple approval and proper provisioning profile with external purchase entitlements
  • URLs must be configured in Info.plist via the config plugin

Example Config:

// 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,
},
},
],
],
};

See also: