# Changelog ## [4.11.0] - 2024-03-06 ### Added - GooglePlay - `IGooglePlayConfiguration.SetMaxConnectionAttempts(int maxConnectionAttempts)` has been added to specify the max connection attempts to the Google Play Store. - Apple - Added privacy manifest to comply with Apple's new privacy requirements. More details on how the Unity Engine supports this can be found [here](https://forum.unity.com/threads/apple-privacy-manifest-updates-for-unity-engine.1529026/). - Added `ConfigurationBuilder.logUnavailableProducts` to specify if unavailable products should be logged. ### Changed - GooglePlay - The default max connection attempt to the Google Play Store has been increased from 1 to 3. See `IGooglePlayConfiguration.SetMaxConnectionAttempts` to configure this to a different value. - Apple - The log when retrieving products (SKProductsResponse) now also contains the invalid products count. - Improved `IStoreListener.OnInitializeFailed` for `InitializationFailureReason.NoProductsAvailable` by adding a message to clarify whether the store returned products or not. ### Fixed - GooglePlay - Fixed AndroidJavaObject not being disposed causing a global reference table overflow in an edge case. - GooglePlay - Fixed bug causing BillingClient duplication resulting in ANR. - Apple - Fixed isFamilyShareable on tvOS to be only available on supported versions (14.0 and above). - Apple - Error codes when a purchase fails now always returns the code from Apple instead of defaulting to `SKErrorUnknown`. - Fixed Analytics' transactionServer being null. ## [4.10.0] - 2023-09-07 ### Changed - Unity Distribution Portal - IAP will retract support for UDP at some point in the near future (Announcement TBD). Until then, all UDP features will continue to function, but the public interfaces, as well as some private functions are now marked `[Obsolete]`. In the next major update these will all be removed and UDP will cease to function with that version of In-App Purchasing and those that follow. - Unity Distribution Portal - If the editor is unable to connect to the UDP backend, the developer can now use some UDP catalog features in offline mode. This allows the developer to continue to enter prices, meaning that prices will need to be synced manually. In this case, we strongly suggest you sync your prices properly once connection is re-established. A warning message will display in the Catalog if the editor is unable to connect to the UDP backend. - Analytics - The Legacy Analytics built-in module, com.unity.modules.unityanalytics, is now no longer a dependency. You may now remove it from your project if you don't use it. Make sure it is in your project if you do use it. - Project Settings - In the Services Project Settings page of the Editor, we have changed the endpoint from which the Google Play Key is obtained. Also, instead of setting the key directly in the editor, there is now a dashboard link to set it directly on the backend to avoid future errors. ### Fixed - Google Play - Some versions of the Unity Editor compiler were stripping `GooglePurchaseUpdatedListener.onPurchasesUpdated`, which was assigned as a callback to the Google Billing module, causing a lack of purchase failure callbacks, and logging `"No such proxy method:"`. Also fixed this for `BillingClientStateListener.onBillingServiceDisconnected`, `BillingClientStateListener.onBillingSetupFinished` and `SkuDetailsResponseListener.onSkuDetailsResponse`. ## [4.9.4] - 2023-08-01 ### Changed - Google Play - Billing Library updated to 5.2.1 (was previously 5.1.0). No new feature support was added, this is simply to add compatibility with Android 14. - Apple - Using the CrossPlatformValidation (or AppleValidator), receipts will now be validated if their certificate chain is encoded in SHA-256 instead of SHA-1. Old receipts encoded in SHA-1 will still be validated. See [Apple Technical Note](https://developer.apple.com/documentation/technotes/tn3138-handling-app-store-receipt-signing-certificate-changes). ## [4.9.3] - 2023-05-17 ### Changed - Analytics events are now sent when a purchase has been confirmed (`ConfirmPendingTransaction` or `ProcessPurchase` returning `PurchaseProcessingResult.Complete`). This will improve the accuracy of revenue tracking by no longer considering pending purchases. - Updated `Product.transactionID`, `Product.hasReceipt` and `Product.receipt` documentation to include pending transaction use cases. - Updated samples to use `IDetailedStoreListener` and its improved `OnPurchaseFailed` callback. - Added a new `RefreshAppReceipt(Action successCallback, Action errorCallback)` callback containing more information when the errorCallback is invoked in `IAppleExtensions : IStoreListener`. ### Fixed - `OnPurchaseFailed` will no longer log an error when there's only new IAP Buttons with no IAP Listener. - Apple - Improved the accuracy of `Product.appleProductIsRestored` when using the restore transaction button. These will now correctly be flagged as true. - Codeless - `OnPurchaseFailed(Product, PurchaseFailureDescription)` callback was not invoked in `IAP Listener` ## [4.8.0] - 2023-04-12 ### Added - Added new [IAP Button](https://docs.unity3d.com/Packages/com.unity.purchasing@4.8/manual/CodelessIAPButton.html) in the editor. This new button allows for more UI customization. The new button will no longer update the button fields by default. - Added a new event `OnProductFetched(Product)` to the [IAP Listener](https://docs.unity3d.com/Packages/com.unity.purchasing@4.8/manual/IAPListener.html) and to the [IAP Button](https://docs.unity3d.com/Packages/com.unity.purchasing@4.8/manual/CodelessIAPButton.html) it is called after fetching products from the app stores. - Added a new `OnPurchaseFailed(Product, PurchaseFailureDescription)` callback containing more information on the failed purchase in `IDetailedStoreListener : IStoreListener` ### Changed - [IAP Button](https://docs.unity3d.com/Packages/com.unity.purchasing@4.8/manual/IAPButton.html) is now obsolete. - Google Play - Billing Library update from version 4.0.0 to 5.1.0 [Google Release Notes](https://developer.android.com/google/play/billing/release-notes). New Google Billing features are not supported yet, they will be included in a future major update. - Removed the nullable operator `?` from public interfaces and classes. - `IStoreListener.OnPurchaseFailed` is now obsolete. - When present, Analytics 4.4.0 and above will now use the new interface `IAnalyticsStandardEventComponent` from Services Cores 1.8.1. - Upgraded `com.unity.services.core` from 1.5.2 to 1.8.1. ### Fixed - Samples - Some samples had IAP 4.6.0 `IStoreListener` changes not completely implemented causing compilation errors. ## [4.7.0] - 2023-02-09 ### Added - Added `storeSpecificErrorCode` to `PurchaseFailureDescription.message` when available. ### Fixed - Unity IAP will consider the call to `UnityPurchasing.initialize` completed before invoking the correct callback `IStoreListener.OnInitialized` or `IStoreListener.OnInitializeFailed`. This prevents these callbacks from being invoked more than once per initialization. - GooglePlay - Fixed `No such proxy method` exception in our representation of `BillingClientStateListener.onBillingServiceDisconnected()` introduced by Unity IAP 4.6.0 - Apple - Fixed a `NullReferenceException` happening when the receipt isn't found. ### Changed - Removed `com.unity.services.analytics` from the IAP SDK dependencies ## [4.6.0] - 2023-02-02 ### Added - Added a new restore transaction callback `RestoreTransactions(Action callback)` to obtain the error string when RestoreTransactions is not successful (`IAppleExtensions` and `IGooglePlayStoreExtensions`). - Added a new initialize failed callback `IStoreListener.OnInitializeFailed(InitializationFailureReason, string)` to obtain the error string when OnInitializeFailed is invoked. - Added a new setup failed callback `IStoreCallback.OnSetupFailed(InitializationFailureReason, string)` to obtain the error string when OnSetupFailed is invoked. - Added a new FetchAdditionalProducts. The failCallback contains an error string. `IStoreController.FetchAdditionalProducts(HashSet, Action, Action)` - Apple - `Product.appleOriginalTransactionId` : Returns the original transaction ID. This field is only available when the purchase was made in the active session. - Apple - `Product.appleProductIsRestored` : Indicates whether the product has been restored. - GooglePlay - `IGooglePlayConfiguration.SetFetchPurchasesExcludeDeferred(bool exclude)` has been added to revert to the previous behaviour. This is not recommended and should only be used if `Deferred` purchases are handled in your `IStoreListener.ProcessPurchase`. - GooglePlay - `IGooglePlayStoreExtensions.GetPurchaseState(Product product)` has been added to obtain the `GooglePurchaseState` of a product. - GooglePlay - Added missing values to `GoogleBillingResponseCode` in order to output it in `PurchaseFailureDescription`'s message when available. - Codeless - Added to the [IAP Button](https://docs.unity3d.com/Packages/com.unity.purchasing@4.6/manual/IAPButton.html) the option to add a script for the On Transactions Restored: `void OnTransactionsRestored(bool success, string? error)` ### Changed - Upgraded `com.unity.services.core` from 1.3.1 to 1.5.2 - Upgraded `com.unity.services.analytics` from 4.0.1 to 4.2.0 - The old OnInitializeFailed `OnInitializeFailed(InitializationFailureReason error)` was marked `Obsolete` - The old OnSetupFailed `OnSetupFailed(InitializationFailureReason reason)` was marked `Obsolete` - The old FetchAdditionalProducts `FetchAdditionalProducts(HashSet additionalProducts, Action successCallback, Action failCallback)` was marked `Obsolete` - The old restore transaction callback `RestoreTransactions(Action callback)` was marked `Obsolete` (`IAppleExtensions` and `IGooglePlayStoreExtensions`). - Apple - Transactions received from Apple that are invalid (where the product is not entitled) will no longer output the `Finishing transaction` log. This only affects transactions that never reached the `ProcessPurchase`. - GooglePlay - The enum `GooglePurchaseState` now recognizes `4` as `Deferred`. ### Fixed - Analytics - A ServicesInitializationException introduced in Analytics 4.3.0 is now handled properly. - Analytics - Fixed an issue where transactions events were invalidated when there was no localization data for a product. - GooglePlay - Fixed a `NullReferenceException` when querying sku details while the BillingClient is not ready. - GooglePlay - Fixed [Application Not Responding (ANR)](https://developer.android.com/topic/performance/vitals/anr) when foregrounding the application while disconnected from the Google Play Store. - GooglePlay - Limited the occurence of `PurchasingUnavailable` errors when retrieving products while in a disconnected state to once per connection. - GooglePlay - `Deferred` purchases are, by default, no longer sent to `IStoreListener.ProcessPurchase` when fetching purchases. This avoids the possibility of granting products that were not paid for. These purchases will only be processed once they become `Purchased`. This can be reverted with `IGooglePlayConfiguration.SetFetchPurchasesExcludeDeferred(bool exclude)` to not exclude them, but `Deferred` purchases will need to be handled in `IStoreListener.ProcessPurchase`. - Unity IAP will consider the call to `UnityPurchasing.initialize` completed before invoking the correct callback `IStoreListener.OnInitialized` or `IStoreListener.OnInitializeFailed`. This prevents these callbacks from being invoked more than once per initialization. ## [4.5.2] - 2022-10-28 ### Fixed - Removed unused exception variable causing a compiler warning CS0168. - Telemetry - Calls to telemetry reporting were occasionally tripping a `NullReferenceException`, `IndexOutOfRangeException` or `KeyNotFoundException`, for some users. These exceptions are now caught safely and logged. These failures are also mitigated by moving all Telemetry calls to the main thread. Issue noticed in IAP 4.4.1, but may be older. - Apple - Optimized memory usage when processing transactions to prevent out of memory crash when processing transactions on launch. - Batch Mode - Calls to `UnityPurchasingEditor.TargetAndroidStore` to select UDP will now successfully check UDP package installation and log an error instead of throwing a blocking popup when executed as part of a Batch Mode command. - Analytics - Removed escape characters for receipt JSON which was causing parsing issues in the backend. - GooglePlay - Fixed a bug causing a crash when retrying to finish a transaction while disconnected ## [4.5.1] - 2022-10-13 ### Fixed - GooglePlay - Fixed deferred purchases being processed when the app is foregrounded. Issue introduced in Unity IAP 4.5.0. - GooglePlay - Fixed a `NullReferenceException` in `DequeueQueryProducts` happening when launching the app. Issue introduced in Unity IAP 4.2.0. - Analytics - Fixed a `NullReferenceException` when reporting failed transactions of purchase unavailable products. Issue introduced in Unity IAP 4.2.0. - Analytics - Legacy Analytics will no longer report events in custom UGS environments, which would cause misreported live sales figures. Issue introduced in Unity IAP 4.2.0. ## [4.5.0] - 2022-09-23 ### Added - Apple - Add support for [Family Sharing](https://developer.apple.com/app-store/subscriptions/#family-sharing). - API `IAppleConfiguration.SetEntitlementsRevokedListener(Action>` called when entitlement to a products are revoked. The `Action` will be called with the list of revoked products. See documentation "Store Guides" > "iOS & Mac App Stores" for a sample usage. - API - Product metadata is now available in `AppleProductMetadata` from `ProductMetadata.GetAppleProductMetadata()` via `IStoreController.products`. - API `AppleProductMetadata.isFamilyShareable` indicated if the product is family shareable. - `Apple App Store - 11 Family Sharing` sample that showcases how to use Unity IAP to manage family shared purchases. ### Fixed - GooglePlay - Processing out-of-app purchases such as Promo codes no longer requires the app to be restarted. The purchase will be processed the next time the app is foregrounded. Technical limitation: In the case of promo codes, if the app is opened while the code is redeemed, you might receive an additional call to `IStoreListener.OnPurchaseFailed` with `PurchaseFailureReason.Unknown`. This can be safely ignored. - GooglePlay - Fixed a `NullReferenceException` that would rarely occur when retrieving products due to a concurrency issue introduced in Unity IAP 4.2.0 ## [4.4.1] - 2022-08-11 ### Fixed - GooglePlay - Fixed NullReferenceException and ArgumentException that would rarely occur due to a concurrency issue introduced in Unity IAP 4.2.0 - Amazon - Set android:export to true to support Android API level 31+ ## [4.4.0] - 2022-07-11 ### Added - GooglePlay - Google Play Billing Library version 4.0.0. - The Multi-quantity feature is not yet supported by the IAP package and will come in a future update. **Do not enable `Multi-quantity` in the Google Play Console.** - Add support for the [IMMEDIATE_AND_CHARGE_FULL_PRICE](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode#IMMEDIATE_AND_CHARGE_FULL_PRICE) proration mode. Use `GooglePlayProrationMode.ImmediateAndChargeFullPrice` for easy access. - The `"skuDetails"` in the receipt json is now an array of the old structure, not just one object. It will only have one element in most cases, so if this is being parsed in your app, treat it like an array and get the first element by default. ### Fixed - GooglePlay - Fix `IGooglePlayConfiguration.SetDeferredPurchaseListener` and `IGooglePlayConfiguration.SetDeferredProrationUpgradeDowngradeSubscriptionListener` callbacks sometimes not being called from the main thread. - GooglePlay - When configuring `IGooglePlayConfiguration.SetQueryProductDetailsFailedListener(Action retryCount)`, the action will be invoked with retryCount starting at 1 instead of 0. - GooglePlay - Added a validation when upgrading/downgrading a subscription that calls `IStoreListener.OnPurchaseFailed` with `PurchaseFailureReason.ProductUnavailable` when the old transaction id is empty or null. This can occur when attempting to upgrade/downgrade a subscription that the user doesn't own. ## [4.3.0] - 2022-06-16 ### Added - GooglePlay - API `IGooglePlayConfiguration.SetQueryProductDetailsFailedListener(Action)` called when Unity IAP fails to query product details. The `Action` will be called on each query product details failure with the retry count. See documentation "Store Guides" > "Google Play" for a sample usage. ## [4.2.1] - 2022-06-14 ### Fixed - Downgrade `com.unity.services.core` from 1.4.1 to 1.3.1 due to a new bug found in 1.4.1 ## [4.2.0] - 2022-06-13 ### Added - Feature to automatically initialize **Unity Gaming Services** through the catalog UI. Please see the [documentation](https://docs.unity3d.com/Packages/com.unity.purchasing@4.2/manual/UnityIAPInitializeUnityGamingServices.html) for more details. ### Changed - The In-App Purchasing package now requires **Unity Gaming Services** to have been initialized before it can be used. For the time being **IAP** will continue working as usual, but will log a warning if **Unity Gaming Services** has not been initialized. In future releases of this package, initializing **Unity Gaming Services** will be mandatory. Please see the [documentation](https://docs.unity3d.com/Packages/com.unity.purchasing@4.2/manual/UnityIAPInitializeUnityGamingServices.html) for more details. ## [4.2.0-pre.2] - 2022-04-28 ### Added - Support for Unity Analytics TransactionFailed event. - Sample showcasing how to initialize [Unity Gaming Services](https://unity.com/solutions/gaming-services) using the [Services Core API](https://docs.unity.com/ugs-overview/services-core-api.html) ### Changed - The Analytics notice in the In-App Purchasing service window has been removed for Unity Editors 2022 and up. ## [4.2.0-pre.1] - 2022-04-07 ### Added - Support for the [new Unity Analytics](https://unity.com/products/unity-analytics) [transaction event](https://docs.unity.com/analytics/AnalyticsSDKAPI.html#Transaction). - The package will now send telemetry diagnostic and metric events to help improve the long-term reliability and performance of the package. ### Changed - The minimum Unity Editor version supported is 2020.3. - The In-App Purchasing service window now links to the [new Unity Dashboard](https://dashboard.unity3d.com/) for Unity Editors 2022 and up. ### Fixed - GooglePlay - Fixed OnInitializeFailed never called if GooglePlay BillingClient is not ready during initialization. - GooglePlay - GoogleBilling is allowed to initialize correctly even if the user's Google account is logged out, so long as it is linked. The user will need to log in to their account to continue making purchases. - Fixed a build error `DirectoryNotFoundException` that occurred when the build platform was iOS or tvOS and the build target was another platform. ## [4.1.5] - 2022-05-17 ### Fixed - GooglePlay - Fixed a null reference exception introduced in Unity IAP 4.1.4 that could happen when cancelling an in-app purchase. ## [4.1.4] - 2022-03-30 ### Fixed - GooglePlay - Fixed issue where if an app is backgrounded while a purchase is being processed, an `OnPurchaseFailed` would be called with the purchase failure reason `UserCancelled`, even if the purchase was successful. ## [4.1.3] - 2022-01-11 ### Fixed - Removed deprecated UnityWebRequest calls, updating them to use safer ones. This avoids compiler warnings that may occur. - Fixed a serious edge case where Apple StoreKit receipt parsing might fail, preventing validation. A portion of receipts on iOS could be affected and cause Unity IAP to freeze after the purchase completed, but before the SDK can finalize the purchase. The user will have to uninstall and reinstall your app in order to recover from this. Your customer service will have to refund the user's purchase or apply the purchase in some other way outside of Unity IAP. This bug was accidentally introduced in Unity IAP 4.1.0. To avoid encountering this problem with your app, we suggest you update to this version. ## [4.1.2] - 2021-11-15 ### Fixed - Various internal obsolete warnings have been removed, allowing the project to be compiled with errors as warnings enabled. ## [4.1.1] - 2021-10-28 ### Changed - A default store will be selected for each platform. For Android the default store will be Google. All other platforms already had default stores. ## [4.1.0] - 2021-09-20 ### Added - Apple - Add support for receipt validation with [StoreKit Test](https://developer.apple.com/documentation/Xcode/setting-up-storekit-testing-in-xcode). See the [Receipt Validation Obfuscator manual](https://docs.unity3d.com/Packages/com.unity.purchasing@4.0/manual/UnityIAPValidatingReceipts.html) for a usage recommendation. See also the [sample](https://docs.unity3d.com/Packages/com.unity.purchasing@4.0/manual/Overview.html#learn-more) "05 Local Receipt Validation" for an example. - GooglePlay - Add support for controlling automatic fetching of purchases at initialization, with `IGooglePlayConfiguration.SetFetchPurchasesAtInitialize(bool)`. Use to help distinguish previously seen purchases from new purchases. Then to fetch previously seen purchases use `IGooglePlayExtensions.RestorePurchases(Action)`. ### Changed - Menu items for this package were renamed from *Unity IAP -> In-App Purchasing* and have been moved from *Window > Unity IAP* to *Services > In-App Purchasing*. - Choosing an Android app store target before building the Android Build Target is now required. A build error will be emitted otherwise. Set this with the Store Selector window (*Services > In-App Purchasing > Switch Store ...*) or the API (`UnityPurchasingEditor.TargetAndroidStore()`). The default Android app store is now AppStore.NotSpecified and is visible in the window as `