Upgrade from IAP version 4 to version 5
Follow this guide to migrate from Unity In-App Purchasing version 4 to version 5.
Read time 14 minutesLast updated 10 days ago
In-App Purchasing (IAP) version 5 (v5) introduces significant architectural improvements that give you better control over each step of your connection and purchase flow. While migration requires that you make significant updates to your existing IAP implementation, this guide provides step-by-step instructions and code samples to help you transition.
Overview of changes
The following table summarizes the changes in IAP v5 and what you need to update in your implementation. For more information on the benefits of upgrading, refer to the Why you should upgrade to Unity In-App Purchasing (IAP) v5.x support article.
Change | Required update |
|---|---|
| The Apple App Store implementation moves from StoreKit 1 to StoreKit 2, and Google Play Billing Library moves from version 8.3.0 to version 9.0.0. | Review native store SDK changes |
| Initialization is split into separate async calls for store connection, product fetching, and purchase fetching. | Replace UnityPurchasing.Initialize() |
| Replace ConfigurationBuilder |
| Store Extensions are replaced with Store Extended Services. | Replace ConfigurationBuilder |
| Replace IDetailedStoreListener and IStoreListener |
| Replace IStoreController |
The | Replace purchase flow |
| Restore transactions |
Entitlement checks are now event-based, using | Replace entitlement checks |
| Replace SubscriptionManager |
| Replace SubscriptionManager |
Apple App Store receipt validation is deprecated. Google Play receipt validation now uses | Update receipt validation |
| Update Codeless IAP |
Review native store SDK changes
IAP v5 updates the native store SDKs that the package wraps. These updates change store behavior, receipt formats, and store-specific fields, regardless of how you restructure your C# code. Review them before you migrate.
The following table lists the native SDK version that each IAP version uses:
Store | IAP v4 (4.15.1) | IAP v5 (5.4) |
|---|---|---|
| Apple App Store | StoreKit 1 | StoreKit 2 |
| Google Play Store | Google Play Billing Library 8.3.0 | Google Play Billing Library 9.0.0 |
Update your Apple App Store implementation
IAP v5 uses StoreKit 2 instead of StoreKit 1 on Apple platforms. StoreKit 2 requires the following minimum operating system versions:
Platform | Minimum version for StoreKit 2 |
|---|---|
| iOS | 15.0 |
| iPadOS | 15.0 |
| tvOS | 15.0 |
| macOS | 12.0 |
| visionOS | 1.0 |
IAP v5.0 doesn't support devices below these versions, because it removed StoreKit 1 entirely. As of IAP v5.1.0, a device below these versions automatically falls back to StoreKit 1. The one exception is devices running visionOS, which never fall back automatically. Unless you force StoreKit 1, visionOS uses StoreKit 2.
To use StoreKit 1 regardless of the operating system version, set to before you initialize Unity IAP. This setting overrides the automatic selection on every Apple platform, including visionOS.
StoreKitSelector.forceStoreKit1trueReplace the following Apple-specific fields and APIs:
IAP v4 (StoreKit 1) | IAP v5 (StoreKit 2) |
|---|---|
| |
The App Store | Send |
Local validation with | Not needed under StoreKit 2, which validates transactions locally. Still required for Apple on a device that uses StoreKit 1. |
| Receipt obfuscation for Apple | Not needed under StoreKit 2. Still required for Apple local validation on a device that uses StoreKit 1, through Services > In-App Purchasing > Receipt Validation Obfuscator. |
| Obsolete. Restored purchases arrive through |
Update your Google Play Store implementation
IAP v5.4 uses Google Play Billing Library 9.0.0. IAP v5.0 uses version 8.0.0, and IAP v4.15.1 used version 8.3.0.
Replace the following Google Play-specific fields and APIs:
IAP v4 | IAP v5 |
|---|---|
| |
| Refer to Replace entitlement checks. |
The | No replacement. Google Play Billing removed developer payloads in version 3. |
| |
Local receipt validation with is still supported for Google Play.
CrossPlatformValidatorCheck for removed platform support
IAP v5 removes support for the following platforms and modules:
Removed | Details |
|---|---|
| Universal Windows Platform (Windows Store) | Removed in IAP v5.0. |
| Unity Distribution Portal | Removed from the IAP package in v5.0. You can still implement the Unity Distribution Portal SDK directly, or as a custom store. |
| Amazon Appstore | Not supported in IAP v5. |
Legacy Analytics ( | Removed in IAP v5.0. Use Unity Analytics ( |
IAP v5.4 requires Unity Editor 2022.3 or later, and IAP v5.0 requires Unity Editor 2021.3 or later.
Check third-party analytics and attribution SDKs
External analytics, attribution, and subscription-management SDKs often read Apple purchase data directly rather than through Unity IAP. These SDKs report no error when they stop receiving purchase data, so a loss of iOS purchase events isn't obvious until your reporting is already incomplete.
If you pass Apple purchase data to an SDK or a back-end service, update that handoff before you release:
- Pass where you previously passed the app receipt, and keep your app receipt path for a device where
Order.Info.Apple.jwsRepresentationreturnsStoreKitSelector.UseStoreKit1().true - Check the SDK's documentation for the configuration that StoreKit 2 requires.
- Make a test purchase on a device, then confirm that the purchase appears in the SDK's reporting.
Replace UnityPurchasing.Initialize()
As of IAP v5, you can initialize the Unity IAP package with greater flexibility. You can connect to the store, fetch products, and handle purchases independently and asynchronously. This approach can help you identify and resolve issues that might block a successful initialization.
Follow these steps to replace the behavior of :
UnityPurchasing.Initialize()- Call and await :
StoreController.Connect()- When this call completes, IAP is connected to your current app store.
- Call :
FetchProducts()- You can add products to an instance of , similar to adding products to the
CatalogProvider. You can also pass a list ofConfigurationBuildertoProductDefinitionsorProductService.FetchProducts(). For more information, refer to Code sample of new initialization process.StoreController.FetchProducts() - Your event handler is called when the request has successfully completed. If no specified products could be fetched,
OnProductsFetchedis invoked.OnProductsFetchFailed
- You can add products to an instance of
- Call after your products have been successfully fetched:
FetchPurchases()- Your event handler is called when the request has successfully completed. The
OnPurchasesFetchedobject contains a filterable collection of all deferred, pending, and completed orders returned by the app store. On failure,Ordersis invoked.OnPurchasesFetchFailed
- Your
Code sample of new initialization process using StoreController
The following example shows how to initialize IAP v5:
StoreController m_StoreController; async void InitializeIAP() { m_StoreController = UnityIAPServices.StoreController(); m_StoreController.OnPurchasePending += OnPurchasePending; await m_StoreController.Connect(); m_StoreController.OnProductsFetched += OnProductsFetched; m_StoreController.OnPurchasesFetched += OnPurchasesFetched; var initialProductsToFetch = new List<ProductDefinition> { new(goldProductId, ProductType.Consumable), new(diamondProductId, ProductType.Consumable) }; m_StoreController.FetchProducts(initialProductsToFetch); } void OnProductsFetched(List<Product> products) { // Handle fetched products m_StoreController.FetchPurchases(); } void OnPurchasesFetched(Orders orders) { // Process purchases, for example, check for entitlements from completed orders }
Replace IDetailedStoreListener and IStoreListener
IAP v5 no longer requires an implementation of or for handling purchases or initialization. Replace functionality previously handled by by attaching event handlers to , or to the individual , , and services.
IDetailedStoreListenerIStoreListenerIDetailedStoreListenerStoreControllerProductServicePurchaseServiceStoreServiceFor an example of adding event handlers to , refer to Code sample of new initialization process.
StoreControllerTo migrate, replace each function with the following:
IDetailedStoreListener
| IAP v5 replacement |
|---|---|
| Add an event handler to |
| Continue execution after |
| Add event handlers to |
| Add an event handler to |
| Add an event handler to |
Replace ConfigurationBuilder
Replace the following functions with the following behaviours:
ConfigurationBuilder
| IAP v5 replacement |
|---|---|
| Rather than calling |
| You can find functionality in |
Replace IStoreController
Replace with . exposes IAP functionality similar to , but you can fetch by calling at any time.
IStoreControllerStoreControllerStoreControllerIStoreListenerStoreControllerUnityIAPServices.StoreController()Replace these methods from with the following methods from :
IStoreControllerStoreControllerIStoreController | StoreController | Notes |
|---|---|---|
| | |
| | |
| | |
| | |
Replace purchase flow
To initiate a purchase, call or on or . To confirm a pending purchase, call or with the you want to confirm. For more information about the purchase flow, refer to Purchases.
Purchase()PurchaseProduct()StoreControllerPurchaseServiceStoreController.ConfirmPurchase(PendingOrder)PurchaseService.ConfirmPurchase(PendingOrder)PendingOrderIn IAP v4 and earlier, the method automatically handled all purchase events. In IAP v5, purchase handling uses the following callbacks:
ProcessPurchase- : Called for new purchases.
OnPurchasePending - : Called for restored purchases.
OnPurchasesFetched
Use your existing logic within both of these new callbacks.
ProcessPurchaseConfirmation can also fail. delivers an that is either a or a , so check the type of the order before you treat a purchase as complete. For more information, refer to Handle a failed confirmation.
OnPurchaseConfirmedOrderConfirmedOrderFailedOrderRestore transactions
RestoreTransactionsStoreControllerPurchaseServiceConfirmed purchases are automatically restored when you call or through calling .
FetchPurchases()CheckEntitlement()Replace entitlement checks
To check a user's entitlement to a product, IAP relies on events. You can check the entitlements for all your fetched products by calling and handling the event. To check the entitlement for a single product, call and handle the event.
FetchPurchasesOnPurchasesFetchedCheckEntitlementOnCheckEntitlementProduct.hasReceiptConfirmedOrdersPendingOrdersOrdersOnPurchasesFetchedCheckEntitlementReplace SubscriptionManager
The class is obsolete in IAP v5. It did two unrelated jobs, and each one migrates differently:
SubscriptionManager- Reading subscription information.
- Moving a user between subscription tiers.
Read subscription information
In IAP v4, you construct a from a purchased product, then call . In IAP v5, the order carries this information. Each order exposes a list of objects through , and each of those objects has a property. For a product that isn't a subscription, is .
SubscriptionManagergetSubscriptionInfo()IPurchasedProductInfoOrder.Info.PurchasedProductInfosubscriptionInfosubscriptionInfonullReplace the following calls:
IAP v4 | IAP v5 |
|---|---|
| |
| |
SubscriptionInfoHelperSubscriptionInfoSubscriptionManagerThe following example reads the subscription status of a product from a confirmed order in the event handler:
OnPurchasesFetchedvoid OnPurchasesFetched(Orders orders) { foreach (var order in orders.ConfirmedOrders) { var purchasedProductInfo = order.Info.PurchasedProductInfo .FirstOrDefault(productInfo => productInfo.productId == vipSubscriptionId); if (purchasedProductInfo?.subscriptionInfo?.IsSubscribed() == Result.True) { // Grant access to the subscription content } } }
Change a subscription tier
SubscriptionManager.UpdateSubscriptionSubscriptionManager.UpdateSubscriptionInGooglePlayStoreSubscriptionManager.UpdateSubscriptionInAppleStoreStore | IAP v5 replacement |
|---|---|
| Google Play Store | Call |
| Apple App Store | Purchase the new product with |
The argument has no replacement in IAP v5.
developerPayloadFetch additional products
Call on either or with a list of additional products to trigger your event handler. Alternatively, you can call on a instance. For an example of fetching products via , refer to Code sample of new initialization process. For an example of calling on , refer to Create a catalog in the Editor.
FetchProductsStoreControllerProductServiceOnPurchasesFetchedFetchProductsCatalogProviderProductServiceFetchProductsCatalogProviderReceipt validation
Receipt validation for Apple App Store receipts has been deprecated. Receipt validation is supported only for Google Play Store. To fetch receipts, use from instead of .
Order.Info.ReceiptOrderProduct.ReceiptFor more information about how to confirm that a purchase is legitimate, refer to Transaction verification.
Codeless IAP specifics
Replace the following function with the following:
CodelessIAPStoreListener
| IAP v5 replacement |
|---|---|
| |