8.0.0 - Google Play Billing 8.2.0 Features
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:
| Deprecated | Replacement |
|---|---|
checkAlternativeBillingAvailabilityAndroid() | isBillingProgramAvailableAndroid(BillingProgramAndroid.ExternalOffer) |
showAlternativeBillingDialogAndroid() | launchExternalLinkAndroid() |
createAlternativeBillingTokenAndroid() | createBillingProgramReportingDetailsAndroid(BillingProgramAndroid.ExternalOffer) |
Dependencies
Updated OpenIAP versions:
openiap-apple: 1.3.0 -> 1.3.5openiap-google: 1.3.10 -> 1.3.14openiap-gql: 1.3.0 -> 1.3.5
Migration Guide
For detailed migration instructions, see the Migration from v7 guide.
