Skip to main content

3.4.9 - BillingClient 5.0+ and 7.0+ Fields

· 2 min read
Hyo
Expo IAP Maintainer

Expo IAP 3.4.9 syncs with OpenIAP to add new Android BillingClient fields for subscription management and installment plans.

New Features

PendingPurchaseUpdateAndroid (BillingClient 5.0+)

Track pending subscription upgrades and downgrades. When a user changes their subscription plan, the change may be pending until the current billing period ends.

import {getAvailablePurchases} from 'expo-iap';

const purchases = await getAvailablePurchases();

purchases?.forEach((purchase) => {
if ('pendingPurchaseUpdateAndroid' in purchase && purchase.pendingPurchaseUpdateAndroid) {
console.log('Pending upgrade to:', purchase.pendingPurchaseUpdateAndroid.products);
console.log('Pending token:', purchase.pendingPurchaseUpdateAndroid.purchaseToken);
}
});

Type Definition:

interface PendingPurchaseUpdateAndroid {
// Product IDs the user is switching to
products: string[];
// Purchase token for the pending transaction
purchaseToken: string;
}

// Added to PurchaseAndroid
interface PurchaseAndroid {
// ... existing fields
pendingPurchaseUpdateAndroid?: PendingPurchaseUpdateAndroid | null;
}

InstallmentPlanDetailsAndroid (BillingClient 7.0+)

Support for installment subscription plans where users commit to a series of payments.

import {fetchProducts} from 'expo-iap';

const result = await fetchProducts({skus: ['premium_sub'], type: 'subs'});

result?.forEach((product) => {
product.subscriptionOffers?.forEach((offer) => {
if (offer.installmentPlanDetailsAndroid) {
const {commitmentPaymentsCount, subsequentCommitmentPaymentsCount} =
offer.installmentPlanDetailsAndroid;

console.log(`Initial commitment: ${commitmentPaymentsCount} payments`);
console.log(`Renewal commitment: ${subsequentCommitmentPaymentsCount} payments`);

// subsequentCommitmentPaymentsCount = 0 means plan reverts to normal upon renewal
}
});
});

Type Definition:

interface InstallmentPlanDetailsAndroid {
// Payments required after initial signup (e.g., 12 for yearly commitment)
commitmentPaymentsCount: number;
// Payments required upon renewal (0 = reverts to normal plan)
subsequentCommitmentPaymentsCount: number;
}

// Added to SubscriptionOffer
interface SubscriptionOffer {
// ... existing fields
installmentPlanDetailsAndroid?: InstallmentPlanDetailsAndroid | null;
}

purchaseOptionIdAndroid (BillingClient 7.0+)

New field on DiscountOffer to identify which purchase option was selected.

const discountOffer = product.discountOffers?.[0];
if (discountOffer?.purchaseOptionIdAndroid) {
console.log('Selected option:', discountOffer.purchaseOptionIdAndroid);
}

OpenIAP Updates

PackageVersion
openiap-gql1.3.17
openiap-apple1.3.14
openiap-google1.3.28

Installation

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

References

Questions or feedback? Reach out via GitHub issues.