Skip to main content

8.0.0 - Google Play Billing 8.2.0 Features

· 3 min read
Hyo
Maintainer of flutter_inapp_purchase & expo-iap

We're excited to announce flutter_inapp_purchase v8.0.0, bringing support for Google Play Billing Library 8.2.0 features including the Billing Programs API, one-time product discounts, and purchase suspension status.

What's New

Billing Programs API (Google Play Billing Library 8.2.0+)

The new Billing Programs API provides a unified way to handle external billing programs on Android, replacing the previous Alternative Billing APIs.

import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';

// Check if external offer is available
final result = await iap.isBillingProgramAvailableAndroid(
BillingProgramAndroid.ExternalOffer,
);

if (result.isAvailable) {
// Launch external link
await iap.launchExternalLinkAndroid(
LaunchExternalLinkParamsAndroid(
billingProgram: BillingProgramAndroid.ExternalOffer,
launchMode: ExternalLinkLaunchModeAndroid.LaunchInExternalBrowserOrApp,
linkType: ExternalLinkTypeAndroid.LinkToDigitalContentOffer,
linkUri: 'https://your-payment-site.com/purchase',
),
);

// Get reporting token after external payment
final details = await iap.createBillingProgramReportingDetailsAndroid(
BillingProgramAndroid.ExternalOffer,
);

// Send details.externalTransactionToken to your server
// to report the transaction to Google Play within 24 hours
}

One-Time Product Discounts (Google Play Billing Library 7.0+)

Products can now have multiple discount offers. The oneTimePurchaseOfferDetailsAndroid field is now an array instead of a single object.

final products = await iap.fetchProducts<Product>(
skus: ['product_id'],
type: ProductQueryType.InApp,
);

for (final product in products) {
final offers = product.oneTimePurchaseOfferDetailsAndroid ?? [];

for (final offer in offers) {
print('Offer: ${offer.offerId ?? "default"}');
print('Price: ${offer.formattedPrice}');

// Check for discount info
if (offer.discountDisplayInfo != null) {
final discount = offer.discountDisplayInfo!;
print('Discount: ${discount.percentageDiscount}% off');
if (discount.discountAmount != null) {
print('Save: ${discount.discountAmount!.formattedDiscountAmount}');
}
}

// Check offer validity
if (offer.validTimeWindow != null) {
final window = offer.validTimeWindow!;
print('Valid until: ${DateTime.fromMillisecondsSinceEpoch(
int.parse(window.endTimeMillis)
)}');
}
}
}

Purchase Suspension Status (Google Play Billing Library 8.1.0+)

You can now check if a subscription is suspended due to payment issues:

final purchases = await iap.getAvailablePurchases();

for (final purchase in purchases) {
if (purchase is PurchaseAndroid && purchase.isSuspendedAndroid == true) {
// Subscription is suspended - payment method failed
// Do NOT grant entitlements
// Direct user to Google Play to fix payment method
print('Subscription ${purchase.productId} is suspended');
}
}

Breaking Changes

oneTimePurchaseOfferDetailsAndroid is now an array

This is a breaking change to support multiple discount offers per product.

Before (v7.x):

final price = product.oneTimePurchaseOfferDetailsAndroid?.formattedPrice;

After (v8.x):

final offers = product.oneTimePurchaseOfferDetailsAndroid;
final price = offers?.isNotEmpty == true ? offers![0].formattedPrice : null;

verifyPurchase API changed

The verification APIs now use platform-specific options objects.

Before (v7.x):

final result = await iap.verifyPurchase(sku: 'product_id');

After (v8.x):

// iOS
final result = await iap.verifyPurchase(
apple: VerifyPurchaseAppleOptions(sku: 'product_id'),
);

// Android
final result = await iap.verifyPurchase(
google: VerifyPurchaseGoogleOptions(
sku: 'product_id',
accessToken: 'your-oauth-token',
packageName: 'com.your.app',
purchaseToken: purchase.purchaseToken,
),
);

Bug Fixes

Web Build Error

Fixed dart:io import that was causing web build failures. The library now uses defaultTargetPlatform from Flutter foundation instead of dart:io Platform.

Note that IAP functionality is still iOS/Android only - this fix only enables web compilation for projects that include this package.

Deprecated APIs

The following APIs are deprecated in favor of the new Billing Programs API:

DeprecatedReplacement
checkAlternativeBillingAvailabilityAndroid()isBillingProgramAvailableAndroid(BillingProgramAndroid.ExternalOffer)
showAlternativeBillingDialogAndroid()launchExternalLinkAndroid()
createAlternativeBillingTokenAndroid()createBillingProgramReportingDetailsAndroid(BillingProgramAndroid.ExternalOffer)

Dependencies

Updated OpenIAP versions:

Migration Guide

For detailed migration instructions, see the Migration from v7 guide.

Resources