Releases: hyochan/flutter_inapp_purchase
8.2.0
Breaking Changes
-
Parameter naming:
RequestPurchaseProps.inApp()andRequestPurchaseProps.subs()now useapple/googlefields instead ofios/android- This aligns with the OpenIAP GQL schema
- The type generation script now dynamically reads field names from the schema
// Before (8.1.x) RequestPurchaseProps.inApp(( ios: RequestPurchaseIosProps(sku: 'product_id'), android: RequestPurchaseAndroidProps(skus: ['product_id']), )) // After (8.2.0) RequestPurchaseProps.inApp(( apple: RequestPurchaseIosProps(sku: 'product_id'), google: RequestPurchaseAndroidProps(skus: ['product_id']), useAlternativeBilling: null, ))
Deprecated
-
AlternativeBillingModeAndroid: UseBillingProgramAndroidinsteadAlternativeBillingModeAndroid.alternativeOnly->BillingProgramAndroid.ExternalOfferAlternativeBillingModeAndroid.userChoice->BillingProgramAndroid.UserChoiceBilling
-
alternativeBillingModeAndroidparameter: UseenableBillingProgramAndroidininitConnection()instead
Dependencies
- Updated OpenIAP versions:
openiap-gql: 1.3.10 -> 1.3.11
8.1.2
New Features
-
External Payments Program (Android 8.3.0+, Japan Only): Support for Google Play Billing Library 8.3.0's External Payments program
- Presents a side-by-side choice between Google Play Billing and the developer's external payment option directly in the purchase flow
- New
BillingProgramAndroid.ExternalPaymentsbilling program type - New
DeveloperBillingOptionParamsAndroidto configure external payment option in purchase flow - New
DeveloperBillingLaunchModeAndroidenum for how to launch the external payment link - New
DeveloperProvidedBillingDetailsAndroidtype containingexternalTransactionTokenwhen user selects developer billing - New
developerProvidedBillingAndroidstream for listening to developer billing selection events - New
developerBillingOptionfield inRequestPurchaseAndroidPropsandRequestSubscriptionAndroidProps
// Listen for developer billing selection iap.developerProvidedBillingAndroid.listen((details) { // User selected developer billing // Report transaction to Google within 24 hours using details.externalTransactionToken print('External transaction token: ${details.externalTransactionToken}'); }); // Request purchase with external payments option await iap.requestPurchaseWithBuilder( build: (builder) { builder.google.skus = ['product_id']; builder.google.developerBillingOption = DeveloperBillingOptionParamsAndroid( billingProgram: BillingProgramAndroid.ExternalPayments, launchMode: DeveloperBillingLaunchModeAndroid.LaunchInExternalBrowserOrApp, linkUri: 'https://example.com/checkout', ); builder.type = ProductQueryType.InApp; }, );
-
New Event:
IapEvent.DeveloperProvidedBillingAndroid- Fired when user selects developer billing in External Payments flow -
enableBillingProgramAndroid in InitConnectionConfig: Enable a specific billing program during connection initialization
// Enable External Payments during connection await iap.initConnection( enableBillingProgramAndroid: BillingProgramAndroid.ExternalPayments, );
This provides a cleaner alternative to calling
enableBillingProgram()separately beforeinitConnection().
Dependencies
- Updated OpenIAP versions:
openiap-gql: 1.3.8 -> 1.3.10openiap-google: 1.3.16 -> 1.3.19openiap-apple: 1.3.7 -> 1.3.8
Full Changelog: 8.1.0...8.1.2
8.1.0
New Features
-
Advanced Commerce Data (iOS 15+): Support for StoreKit 2's
Product.PurchaseOption.customAPI- New
advancedCommerceDatafield inRequestPurchaseIosPropsandRequestSubscriptionIosProps - Pass campaign tokens, affiliate IDs, or other attribution data during purchases
await iap.requestPurchaseWithBuilder( build: (builder) { builder.ios.sku = 'com.example.premium'; builder.ios.advancedCommerceData = 'campaign_summer_2025'; builder.type = ProductQueryType.InApp; }, );
- New
-
googlefield support (Android): Newgooglefield in request parameters withandroidfallback- Aligns with OpenIAP specification for consistent cross-platform naming
androidfield is now deprecated; usegoogleinstead
Deprecated
-
requestPurchaseOnPromotedProductIOS(): UsepurchasePromotedstream +requestPurchase()instead- In StoreKit 2, promoted products can be purchased via the standard purchase flow
// Recommended approach iap.purchasePromoted.listen((productId) async { if (productId != null) { await iap.requestPurchaseWithBuilder( build: (builder) { builder.ios.sku = productId; builder.type = ProductQueryType.InApp; }, ); } });
Dependencies
- Updated OpenIAP versions:
openiap-apple: 1.3.5 -> 1.3.7openiap-google: 1.3.14 -> 1.3.15openiap-gql: 1.3.5 -> 1.3.8
8.0.0
8.0.0
Breaking Changes
-
oneTimePurchaseOfferDetailsAndroidis now an array: Changed fromProductAndroidOneTimePurchaseOfferDetail?toList<ProductAndroidOneTimePurchaseOfferDetail>?to support multiple discount offers per product (Google Play Billing 7.0+)// Before (v7.x) final price = product.oneTimePurchaseOfferDetailsAndroid?.formattedPrice; // After (v8.x) final offers = product.oneTimePurchaseOfferDetailsAndroid; final price = offers?.isNotEmpty == true ? offers![0].formattedPrice : null;
-
verifyPurchaseandvalidateReceiptAPI changed: Now uses platform-specific options instead of deprecatedskuandandroidOptionsparameters// Before (v7.x) final result = await iap.verifyPurchase(sku: 'product_id'); final result = await iap.verifyPurchase( sku: 'product_id', androidOptions: VerifyPurchaseAndroidOptions(...), ); // After (v8.x) - iOS final result = await iap.verifyPurchase( apple: VerifyPurchaseAppleOptions(sku: 'product_id'), ); // After (v8.x) - Android final result = await iap.verifyPurchase( google: VerifyPurchaseGoogleOptions( sku: 'product_id', accessToken: 'your-oauth-token', // From your backend packageName: 'com.your.app', purchaseToken: purchase.purchaseToken, ), );
New Features
-
Billing Programs API (Android 8.2.0+): Support for external billing programs
isBillingProgramAvailableAndroid()- Check if a billing program is availablecreateBillingProgramReportingDetailsAndroid()- Get external transaction token for reportinglaunchExternalLinkAndroid()- Launch external link for billing programs
// Check availability 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 final details = await iap.createBillingProgramReportingDetailsAndroid( BillingProgramAndroid.ExternalOffer, ); // Send details.externalTransactionToken to your server }
-
One-Time Product Discounts (Android 7.0+): New fields in
ProductAndroidOneTimePurchaseOfferDetailofferId- Unique offer identifierfullPriceMicros- Full (non-discounted) pricediscountDisplayInfo- Discount percentage and amountlimitedQuantityInfo- Maximum and remaining quantityvalidTimeWindow- Offer validity periodofferTags- List of offer tagsofferToken- Token for purchase requestspreorderDetailsAndroid- Pre-order release dates (Android 8.0+)rentalDetailsAndroid- Rental period information (Android 8.0+)
-
Purchase Suspension Status (Android 8.1.0+): New
isSuspendedAndroidfield inPurchaseAndroid- Check if a subscription is suspended due to payment issues
- Do NOT grant entitlements for suspended subscriptions
for (final purchase in purchases) { if (purchase is PurchaseAndroid && purchase.isSuspendedAndroid == true) { // Subscription suspended - do not grant access // Direct user to fix payment method } }
Deprecated
checkAlternativeBillingAvailabilityAndroid()- UseisBillingProgramAvailableAndroid(BillingProgramAndroid.ExternalOffer)insteadshowAlternativeBillingDialogAndroid()- UselaunchExternalLinkAndroid()insteadcreateAlternativeBillingTokenAndroid()- UsecreateBillingProgramReportingDetailsAndroid(BillingProgramAndroid.ExternalOffer)instead
Fixes
- Web Build Error: Fixed
dart:ioimport causing web build failures- Replaced
dart:io PlatformwithdefaultTargetPlatformfrom Flutter foundation - Added
kIsWebguards to prevent native API calls on web - Note: IAP functionality is still iOS/Android only; this fix only enables web compilation
- Replaced
Dependencies
- Updated OpenIAP versions:
openiap-apple: 1.3.0 → 1.3.5openiap-google: 1.3.12 → 1.3.14openiap-gql: 1.3.2 → 1.3.5
Migration Guide
See Migration from v7 for detailed upgrade instructions.
What's Changed
- feat: android billing 8.2.0 by @hyochan in #598
- fix: add web platform support by replacing dart:io Platform by @hyochan in #601
Full Changelog: 7.2.0...8.0.0
7.2.0
Flutter In-App Purchase now provides built-in purchase verification—no server required.
Flutter In-App Purchase 7.2.0 brings built-in purchase verification powered by IAPKit. Now you can verify purchases with enterprise-grade backend validation using a single API call—no server setup required.
Checkout 👉 https://hyochan.github.io/flutter_inapp_purchase/blog/release-7.2.0
What's Changed
Full Changelog: 7.1.21...7.2.0
7.1.21
What's Changed
- feat: add verifyPurchaseWithProvider for IAPKit integration by @hyochan in #594
- Fix parsing purchase result map on iOS26 by @salario07 in #593
New Contributors
- @dependabot[bot] made their first contribution in #589
- @salario07 made their first contribution in #593
Full Changelog: 7.1.20...7.1.21
7.1.20
Full Changelog: 7.1.19...7.1.20
7.1.19
Full Changelog: 7.1.17...7.1.19
