Appearance
Upgrading to Unity IAP v5
This guide walks you through migrating your Metaplay project from Unity Purchasing v4 to v5, including the related Apple StoreKit 2 server configuration.
Appearance
This guide walks you through migrating your Metaplay project from Unity Purchasing v4 to v5, including the related Apple StoreKit 2 server configuration.
com.unity.purchasing package. It replaces the v4 single-listener pattern with a service-based API built around StoreController, ProductService, and PurchaseService.Starting with Release 37, the Metaplay SDK supports Unity Purchasing v5 alongside v4. Upgrading is optional: existing v4 projects continue to work without changes. The SDK detects which version of com.unity.purchasing is installed in your Unity project and automatically selects the matching codepath at compile time.
You should consider upgrading to v5 when:
verifyReceipt endpoint, which Apple has deprecated).You typically don't need to apply any of the changes in Unity's Upgrade to IAP version 5 guide. Metaplay's IAPManager owns the integration on both v4 and v5, and receipt validation happens server-side. For most projects the only Unity-side action is bumping the package version (Step 1); custom IAPClientDelegate subclasses are the one exception, covered in Step 2.
In your Unity project, update com.unity.purchasing to a 5.x release using the Package Manager. The minimum supported version is 5.0.0.
Once the package is updated, the SDK automatically picks up the v5 codepath via a versionDefines entry in its asmdef. You do not need to add a scripting define symbol yourself.
💡 Note
In Release 36, the SDK emitted a #warning when v5 was detected because v5 was not yet supported. That warning is gone in Release 37. If you still see it, you have not picked up the latest SDK code.
IAPClientDelegate Subclasses Most projects do not subclass IAPClientDelegate directly. The SDK's hardcoded delegates handle Apple, Google, and Steam, and TryExtractClientDrivenPurchaseInfo has the same signature under v4 and v5. If you do not have a custom subclass, you can skip this step.
If you do have one, there are two edge cases to check.
args.PurchaseEventArgs in TryExtractClientDrivenPurchaseInfo Unity Purchasing v5 no longer provides a PurchaseEventArgs object, so the ClientDrivenPurchaseArgs.PurchaseEventArgs field is #if'd out under v5. References to it fail at compile time rather than throwing a NullReferenceException at runtime. If your override reads it, switch to the v5-populated fields on ClientDrivenPurchaseArgs (args.UnityReceipt, args.TransactionId, args.PlatformProductId, etc.).
public override bool TryExtractClientDrivenPurchaseInfo(
ClientDrivenPurchaseArgs args,
out ClientPurchaseInfo info,
out string ignoreReason)
{
info = new ClientPurchaseInfo
{
Receipt = args.UnityReceipt.Payload,
Signature = null,
AlternativePurchaseId = null,
};
ignoreReason = null;
return true;
}GetClientDrivenPurchasingModule Under v4, you could override GetClientDrivenPurchasingModule() to return a custom AbstractPurchasingModule (for example, to plug in a non-default store). Unity removed AbstractPurchasingModule from the v5 API; the equivalent extension point is now UnityEngine.Purchasing.IStoreWrapper, registered via UnityIAPServices.AddNewCustomStore and UnityIAPServices.SetStoreAsDefault.
The SDK exposes this as a new v5-only override:
public override PurchasingImpl.IStoreWrapper GetClientDrivenStoreWrapper()
=> new MyCustomStoreWrapper();Returning null (the default) leaves Unity IAP's built-in active store in place, which is what most projects want.
💡 Note
Unity's own v4-to-v5 upgrade guide does not currently walk through migrating a custom purchasing module to an IStoreWrapper. The closest authoritative reference is the UnityIAPServices class reference, which documents AddNewCustomStore / SetStoreAsDefault.
Skip this step if your game does not ship on iOS.
Under Unity Purchasing v5, the Metaplay server validates Apple receipts locally against Apple's signing certificates. There is no extra configuration required for individual-purchase validation.
If your game ships auto-renewing subscriptions, the server additionally needs an Apple In-App Purchase key to authenticate subscription state queries against the App Store Server API. Follow the In-App Purchase Key for StoreKit 2 Subscriptions procedure in the Auto-Renewing Subscriptions guide. It walks through issuing the key in App Store Connect, building the credentials JSON, creating the Kubernetes secret, and pointing AppStoreConnectApiCredentialsPath at it. Once that's done, come back here.
🔒 Optional: Pin Apple's Root Certificates
The server validates Apple's JWS signing chain against Apple's published root CAs. By default the SDK fetches Apple's root certificates from apple.com at server startup.
If you want to pin a known set of fingerprints instead (for example, to validate offline or to defend against a compromised CA fetch), set AppleStore:AppleRootCaFingerprints to a list of hex-encoded SHA-256 fingerprints. Only those exact fingerprints will be trusted; the live fetch is skipped.
⚠️ Double-check every product type before promoting to production
Purchase flows directly affect revenue, so this step is worth more than a quick smoke test. Sweep through every product type your game ships in sandbox before going live.
Run through the following end-to-end checks. For each platform-store check, repeat it for every product type your game uses.
InAppPurchaseEvent.PaymentType reports Sandbox. See Sandbox Purchases for how this is detected.InAppPurchaseEvent.PaymentType reports Sandbox. Google's receipt format and validation path are unchanged by the v5 upgrade, but test it anyway to catch any side-effect regressions.verifyReceipt endpoint, which Apple has deprecated; the v4 path keeps working only while Apple keeps that endpoint up.IAPManager only supports one product per purchase: if Unity ever surfaces a multi-item cart, IAPManager throws InvalidOperationException rather than silently processing a subset. Initiate purchases through IAPManager.TryBeginPurchaseProduct to stay on the supported path.