Migration One section per coordinated major train. Each train lists the versions that drop the previously deprecated, OpenIAP-owned compatibility surface and the canonical call to use instead.
2.x → 3.0# The coordinated major train removes the previously deprecated, OpenIAP-owned compatibility surface. Use this catalog to update calls before upgrading.
Breaking major release
The listed versions do not include compatibility wrappers, deprecated schema members, or legacy custom-wire aliases. Upgrade coordinated native and framework dependencies together.
Removal boundaries# OpenIAP specification and native packages Package Last compatible major Removed in OpenIAP Spec 2.x3.0.0openiap-apple 2.x3.0.0openiap-google 2.x3.0.0
Framework libraries IAPKit is a hosted service rather than a versioned framework library. Its scoped keys, client payloads, verification, and staged data migrations are unchanged by this SDK-only major train.
Generated Swift, Kotlin, TypeScript, Dart, GDScript, and C# contracts now expose only the canonical schema. The former declarations remain listed below solely as migration reference.
Raw JavaScript objects, plugin configuration, custom MethodChannel payloads, and direct Godot dictionaries must also use canonical keys. Removed aliases are rejected or ignored; they never override missing canonical input.
Flutter purchase payload compatibility# PurchaseAndroid.dataAndroid is the only public, schema-defined field for Google Play's raw signed purchase JSON.originalJsonAndroid is not a public Purchase field and is never the preferred output key.
Flutter 9.x accepted the following legacy native or custom MethodChannel payload shapes. Flutter 10 accepts only the canonical forms in the middle column.
Legacy Flutter 9.x input Emit instead Platform originalJsonAndroiddataAndroidAndroid purchaseStateAndroidpurchaseStateAndroid transactionStateIOSpurchaseStateiOS transactionReceiptpurchaseTokeniOS id used as a transactionId fallbackan explicit transactionId; keep id as the purchase identityAndroid and iOS top-level { sku } for verifyPurchase / validateReceiptIOS{ apple: { sku } }iOS and macOS
The canonical id purchase identity is not deprecated. Flutter 10 requires an explicit transactionId.
Issue #248 and Android raw purchase JSON Before Flutter 9.6.1, issue #248 caused canonical dataAndroid input to be lost by the Dart compatibility converter. The patch in PR #251 read dataAndroid first and accepted originalJsonAndroid only as a temporary Flutter 9.x input fallback. If both keys exist, dataAndroid wins. Flutter 10 removes that fallback. Custom native adapters, MethodChannel fixtures, and mocks must emit dataAndroid. See the canonical field reference in PurchaseAndroid .
Flutter 10 package-specific migrations# In addition to the generated OpenIAP schema surfaces below,flutter_inapp_purchase 10.0.0 removes these Flutter-only compatibility APIs:
Deprecated Flutter surface Migrate to ReplacementMode / ReplaceModeAndroidReplacementModeTypeInAppProductQueryTypebuilder replacementModesubscriptionProductReplacementParamsbuilder useAlternativeBillingInitConnectionConfig.enableBillingProgramAndroidpurchaseUpdatedpurchaseUpdatedListenerPurchaseResult / purchaseErrorPurchaseError / purchaseErrorListenerConnectionResult / connectionUpdatedthe initConnection resultrequestPurchaseOnPromotedProductIOSpurchasePromoted, then requestPurchase
Custom MethodChannel integrations Applications normally use the Dart API and never call these internal channel names. Flutter 10 custom integrations must use the replacements:
Legacy channel method Migrate to getAvailableItemsByTypegetAvailablePurchasesgetPurchaseHistoryByTypegetAvailablePurchases for active purchasesbuyItemByTyperequestPurchaseacknowledgePurchasefinishTransaction or acknowledgePurchaseAndroidconsumeProduct / consumePurchasefinishTransaction with isConsumableshowInAppMessagesshowInAppMessagesAndroidgetAppTransactiongetAppTransactionIOSgetSubscriptionStatussubscriptionStatusIOS
Custom MethodChannel payloads The official Dart API emits the canonical forms below. Flutter 10 no longer normalizes the historical custom-channel inputs.
Legacy payload shape Emit instead product type 'inapp''in-app'requestPurchase.request.ios / requestSubscription.request.iosapplerequestPurchase.request.android / requestSubscription.request.androidgoogleproductId / sku used as a product ididdiscounts / subscription product metadatadiscountOffers or subscriptionOffers, plus subscriptionGroupIdIOS when applicablesubResponseCodesubResponseCodeAndroidfetchProducts skuArr / productIdsskusofferTokenArrofferToken for one-time products or subscriptionOffers for subscriptionsobfuscatedAccountIdAndroid / obfuscatedProfileIdAndroidobfuscatedAccountId / obfuscatedProfileIdpurchaseTokenAndroid / tokenpurchaseTokenfinishTransaction transactionIdentifiertransactionIdreplacementModeAndroid / replacementModesubscriptionProductReplacementParamsunsuffixed deep-link sku / packageNameskuAndroid / packageNameAndroidnumeric-indexed iOS SKU maps{ skus: [...] }
Removed schema migration catalog# The following OpenIAP-owned schema surfaces were removed by the package versions above.
Validation and storefront APIs Deprecated surface Migrate to validateReceiptverifyPurchasevalidateReceiptIOSverifyPurchasegetStorefrontIOSgetStorefrontrequestPurchaseOnPromotedProductIOSthe SDK's promoted-product listener or callback, then requestPurchasecheckAlternativeBillingAvailabilityAndroidisBillingProgramAvailableAndroid with the BillingProgramAndroid value your app is enrolled inshowAlternativeBillingDialogAndroidshowBillingProgramInformationDialogAndroid (the in-app Billing Programs dialog); launchExternalLinkAndroid covers the external-link flows (External Offer, External Content Link, Billing Choice external links)createAlternativeBillingTokenAndroidcreateBillingProgramReportingDetailsAndroid with the BillingProgramAndroid value your app is enrolled in
Purchase and connection inputs Deprecated surface Migrate to RequestPurchasePropsByPlatforms.ios / RequestSubscriptionPropsByPlatforms.iosappleRequestPurchasePropsByPlatforms.android / RequestSubscriptionPropsByPlatforms.androidgoogleuseAlternativeBillingenableBillingProgramAndroid in InitConnectionConfigalternativeBillingModeAndroidenableBillingProgramAndroidRequestSubscriptionAndroidProps.replacementModesubscriptionProductReplacementParams for item-level replacement (Play Billing 8.1+)
Shared fields and errors Deprecated surface Migrate to PurchaseCommon.platform / PurchaseInput.platform / PurchaseIOS.platform / PurchaseAndroid.platformstorewillExpireSoondaysUntilExpirationIOSpresentCodeRedemptionSheetIOS Boolean resultnullable PurchaseIOS result: verified on Apple 27+ with Xcode 27+; null after the system sheet on iOS 15–26 and visionOS 1–26; Catalyst 16–26 throws StoreKitError.unknown and Catalyst 15 has no effectreceipt-failedpurchase-verification-failedreceipt-finishedpurchase-verification-finishedreceipt-finished-failedpurchase-verification-finish-failed
Offer and billing-program models Deprecated surface Migrate to SubscriptionOfferIOSSubscriptionOfferDiscountIOS / DiscountOfferIOSSubscriptionOfferProductAndroidOneTimePurchaseOfferDetailDiscountOfferProductSubscriptionAndroidOfferDetailsSubscriptionOfferProductAndroid.oneTimePurchaseOfferDetailsAndroidProductAndroid.discountOffersProductSubscriptionAndroid.oneTimePurchaseOfferDetailsAndroidsubscriptionOffers; one-time offer fields do not apply to subscriptionsProductSubscriptionAndroid.discountOfferssubscriptionOffers; one-time offer fields do not apply to subscriptionsProductAndroid.subscriptionOfferDetailsAndroid / ProductSubscriptionAndroid.subscriptionOfferDetailsAndroidsubscriptionOffersProductIOS.subscriptionInfoIOS / ProductSubscriptionIOS.discountsIOSsubscriptionOffersProductSubscriptionIOS.subscriptionInfoIOSsubscriptionOffers for offers and subscriptionGroupIdIOS for the group identifierAlternativeBillingModeAndroidBillingProgramAndroidAlternativeBillingModeAndroid value 'user-choice'BillingProgramAndroid value 'user-choice-billing'AlternativeBillingModeAndroid value 'alternative-only'BillingProgramAndroid value 'external-offer'ExternalOfferAvailabilityResultAndroidBillingProgramAvailabilityResultAndroid from isBillingProgramAvailableAndroidExternalOfferReportingDetailsAndroidBillingProgramReportingDetailsAndroid from createBillingProgramReportingDetailsAndroid
Removed package-specific compatibility shims# These public aliases and wrappers were package-local rather than GraphQL schema members. They are absent from the major versions named in each heading.
openiap-apple (OpenIAP 3.0) Deprecated package surface Migrate to ReceiptValidationProps / ReceiptValidationResult / ReceiptValidationResultIOSVerifyPurchaseProps / VerifyPurchaseResult / VerifyPurchaseResultIOSOpenIapErrorCode / OpenIapEvent / OpenIapPlatformErrorCode / IapEvent / IapPlatformgetStorefrontIOSWithCompletiongetStorefrontWithCompletionrequestPurchaseOnPromotedProductIOSWithCompletionpromotedProductListenerIOS followed by requestPurchaseshort requestSubscriptionWithSku(_:offer:completion:) overloadthe extended overload with compactJWS, promotionalOfferJWS, winBackOfferId, and billingPlanTyperaw/custom purchase id used as a transactionId fallbackan explicit transactionId; keep id as the canonical purchase identityOpenIapStore.deepLinkToSubscriptionsIOSdeepLinkToSubscriptionsOpenIapVersion.gqlVersion / OpenIapVersionInfo.gqlVersionOpenIapVersion.specVersion
openiap-google (OpenIAP 3.0) Deprecated package surface Migrate to ReceiptValidationProps / ReceiptValidationResult / ReceiptValidationResultIOSVerifyPurchaseProps / VerifyPurchaseResult / VerifyPurchaseResultIOSAlternativeBillingModeBillingProgramAndroid through InitConnectionConfig.enableBillingProgramAndroidPlay OpenIapModule(context, AlternativeBillingMode, legacy listeners)OpenIapModule(context), then register listeners and pass InitConnectionConfig.enableBillingProgramAndroid to initConnectionPlay OpenIapModule(context, enableAlternativeBilling) / OpenIapStore(context, enableAlternativeBilling)construct normally, then pass InitConnectionConfig.enableBillingProgramAndroid to initConnectionPlay OpenIapStore(context, AlternativeBillingMode, userChoiceBillingListener)OpenIapStore(context), then register listeners and pass InitConnectionConfig.enableBillingProgramAndroid to initConnectionAmazon OpenIapModule(context, enableAlternativeBilling)OpenIapModule(context); Amazon ignores the legacy optionAmazon OpenIapModule(context, AlternativeBillingMode, legacy listeners)OpenIapModule(context); Amazon ignores the legacy options, then register listeners with add/remove APIsAmazon OpenIapStore(context, AlternativeBillingMode, userChoiceBillingListener)OpenIapStore(context); Amazon ignores the legacy optionsHorizon OpenIapModule / OpenIapStore constructors with AlternativeBillingMode or legacy listenersOpenIapModule(context) / OpenIapStore(context); Horizon ignores the legacy optionsHorizon manifest keys com.meta.horizon.platform.ovr.OCULUS_APP_ID / com.meta.horizon.platform.ovr.HORIZON_APP_ID / com.oculus.vr.APP_IDcom.meta.horizon.platform.HORIZON_APP_IDsetUserChoiceBillingListener / setDeveloperProvidedBillingListenerthe corresponding add/remove listener APIsUserChoiceDetails / UserChoiceBillingListenerUserChoiceBillingDetails / OpenIapUserChoiceBillingListenerDeveloperProvidedBillingDetails / DeveloperProvidedBillingListenerDeveloperProvidedBillingDetailsAndroid / OpenIapDeveloperProvidedBillingListenerOpenIapStore.connectionStatusOpenIapStore.isConnectedOpenIapError.InvalidReceiptOpenIapError.InvalidPurchaseVerificationcheckAlternativeBillingAvailabilityisBillingProgramAvailable with BillingProgramAndroid.ExternalOffershowAlternativeBillingInformationDialoglaunchExternalLinkcreateAlternativeBillingReportingTokencreateBillingProgramReportingDetails with BillingProgramAndroid.ExternalOfferOpenIapLog.d / i / w / edebug / info / warn / error
react-native-iap 16.0.0 Deprecated package surface Migrate to ProductTypeInput 'inapp''in-app'request.ios / request.androidrequest.apple / request.googlereplacementModesubscriptionProductReplacementParamsuseIAP().alternativeBillingModeAndroidenableBillingProgramAndroidacknowledgePurchaseacknowledgePurchaseAndroidconsumePurchaseconsumePurchaseAndroidrequestPromotedProductIOSgetPromotedProductIOSgetReceiptIOSgetReceiptDataIOSrequestPurchaseOnPromotedProductIOSpromotedProductListenerIOS, then requestPurchaseuseIAP().requestPurchaseOnPromotedProductIOSonPromotedProductIOS, then requestPurchase
expo-iap 5.0.0 Deprecated package surface Migrate to ProductTypeInput 'inapp''in-app'request.ios / request.androidrequest.apple / request.googleAndroid custom-channel skuArrskusAndroid custom-channel offerTokenArrsubscriptionOffers for subscriptionsreplacementModesubscriptionProductReplacementParamsuseIAP().alternativeBillingModeAndroidenableBillingProgramAndroidacknowledgePurchaseacknowledgePurchaseAndroidconsumePurchaseconsumePurchaseAndroidgetReceiptIOSgetReceiptDataIOSvalidateReceiptAndroidverifyPurchaseAndroid deep-link sku / packageNameskuAndroid / packageNameAndroidrequestPurchaseOnPromotedProductIOSpromotedProductListenerIOS, then requestPurchaseuseIAP().requestPurchaseOnPromotedProductIOSonPromotedProductIOS, then requestPurchaseconfig.iosAlternativeBillingconfig.ios.alternativeBillingconfig.horizonAppId / config.android.horizonAppIdconfig.android.horizon.appIdconfig.android.amazon.fireOS / boolean config.android.amazon.vegaOSconfig.modules.amazon.fireOS / config.modules.amazon.vegaOS
godot-iap 3.0.0 Deprecated package surface Migrate to godot-iap get_storefront_iosget_storefrontgodot-iap validate_receipt_ios / validate_receiptverify_purchasegodot-iap request_purchase_on_promoted_product_iospromoted_product_ios, then request_purchasegodot-iap check_alternative_billing_availability_androidis_billing_program_available_android with BillingProgramAndroid.EXTERNAL_OFFERgodot-iap show_alternative_billing_dialog_androidlaunch_external_link_androidgodot-iap create_alternative_billing_token_androidcreate_billing_program_reporting_details_android with BillingProgramAndroid.EXTERNAL_OFFERflattened verify_purchase_with_provider IAPKit keyskeep provider at the top level and nest apiKey, baseUrl, includeClientPayload, apple, google, and amazon under iapkitProductQueryType 'inapp' / 'in_app''in-app'ProductQueryType 'subscription''subs'raw request selector and ios / android purchase envelopesrequestPurchase or requestSubscription with apple / googleraw offer_tokenofferTokenraw obfuscatedAccountIdAndroid / obfuscatedProfileIdAndroid / purchaseTokenAndroidthe corresponding unsuffixed Google request keysraw replacementModeAndroid / replacementModesubscriptionProductReplacementParamsraw skuArr / numeric-indexed iOS SKU mapsskusraw offerTokenArrofferToken for a one-time product or subscriptionOffers for a subscriptionAndroid native requestPurchaseJsonrequestPurchaseiOS simple requestPurchase(sku:) / top-level sku requestrequestPurchaseWithPayload using an apple request envelope
kmp-iap 3.0.0 Deprecated package surface Migrate to kmp-iap requestPurchaseOnPromotedProductIOSpromotedProductListener, then requestPurchasekmp-iap getStorefrontIOSgetStorefrontkmp-iap validateReceiptIOS / validateReceiptverifyPurchasePurchaseRequestBuilder.ios / PurchaseRequestBuilder.androidPurchaseRequestBuilder.apple / PurchaseRequestBuilder.googleAndroidOptionsBuilder.replacementModesubscriptionProductReplacementParamsgenerated RequestPurchasePropsByPlatforms.ios / .android and RequestSubscriptionPropsByPlatforms.ios / .androidapple / googlegenerated RequestPurchaseProps.useAlternativeBilling / InitConnectionConfig.alternativeBillingModeAndroidInitConnectionConfig.enableBillingProgramAndroidgenerated RequestSubscriptionAndroidProps.replacementModesubscriptionProductReplacementParams
OpenIap.Maui 2.0.0 Deprecated package surface Migrate to OpenIap.Maui Iap facadeOpenIapClientnet9.0, net9.0-android, net9.0-ios, and net9.0-maccatalyst targetsthe matching net10.0 target frameworks with the .NET 10 MAUI workloadRequestPurchaseOnPromotedProductIOSAsyncPromotedProductIOS, then RequestPurchaseAsync
What this schedule does not remove# The schedule applies to OpenIAP-owned deprecated schema members and explicit compatibility shims. It does not automatically remove:
redirects kept so existing documentation links continue to work; documentation that describes an upstream StoreKit or Play Billing legacy technology still supported by the stores; or StoreKit, Play Billing, Amazon, or Horizon response-shape normalization, including upstream names such as productIdentifier, localizedPrice, and historical receipt payload labels; internal React Native, Expo, KMP, or Godot recovery of native response fields that applications do not author; input normalization that accepts historical error-code spellings; safe fallbacks used when an operating-system version does not support a newer store API; or staged IAPKit storage migrations with their own retention and rollback requirements. Check the release notes before every major upgrade for the final removal list and package-specific migration steps.