Comply with Apple and Google external purchase requirements
Understand your compliance responsibilities for external purchases on Apple and Google, and the SDK and webhook tools Unity provides to help you meet them.
Read time 5 minutesLast updated 3 hours ago
An external purchase sells digital content through your own web checkout (such as a payment provider) instead of Apple's or Google's in-app billing. Apple and Google allow this only in select regions and only under their own program rules, such as the External Purchase program (Apple) and the external offers programs (Google Play). Eligibility, fees, disclosures, and transaction reporting vary by platform, region, and app. In some regions, you might need little or none of these purchase requirements.
To help you build your own compliance flow, Unity provides SDK hooks and webhook data. This page explains the division of responsibilities, the order model your compliance steps build on, and the specific actions you can take.
This page is part of the Integrate Direct to Consumer (D2C) payment providers workflow. Set up your payment provider and purchase flow before you add the compliance handling described here.
Division of responsibilities
Unity provides only technical facilitation. Your payment provider acts as merchant of record for payment processing, tax, and disputes, but it doesn't handle Apple or Google platform reporting. The platform compliance is your responsibility, and Unity doesn't enroll you in any platform program.Unity's technical facilitation
When a Payment Providers purchase proceeds, Unity opens the checkout URL on your behalf. By default it opens in the device's external browser. If you opt into in-app presentation (CheckoutPresentationMode.WebViewYour responsibilities
Unity provides only technical facilitation. You are responsible for the following tasks:- Determine whether your app and region are eligible for each platform's external purchase program.
- Run your own eligibility and disclosure checks before a purchase starts, with Apple's and Google's
ExternalPurchaseClient.ExternalBillingProgramClient - Acquire and report any transaction tokens that Apple or Google requires, with each platform's own APIs.
How Unity creates and opens an order
You normally start a Payment Providers purchase with a single call,PurchaseProduct(catalogListingId)catalogListingId- creates the order and returns its checkout URL, without opening it.
GenerateURL(catalogListingId, tokens) - opens the checkout. If you already called
PurchaseProduct(catalogListingId)for the same listing, it reuses that order. If you didn't, it creates the order itself, with no tokens, and then opens it.GenerateURL
GenerateURLPurchaseProductDecide what your compliance flow needs
The remaining sections are independent. Use the following table to find the steps that apply to your app and platforms:If you need to | Do this | Section |
|---|---|---|
| Enforce your own eligibility rules in-app | Register a compliance callback that runs before each purchase | Gate purchases with a compliance check |
| Show or disclose the checkout URL before the purchase opens | Call | Disclose or render the checkout URL |
| Report external transactions to Apple or Google | Attach tokens with | Attach and report transaction tokens |
Gate purchases with a compliance check
This step is optional. Add it only if you enforce your own eligibility rules in-app. Register a compliance callback to apply your own eligibility rules before a purchase proceeds. When you callPurchaseProductPurchasePaymentProviderComplianceContextCartfalsePurchasingUnavailable-
Define a function that returns a indicating whether the player passed your compliance check:
Task<bool>Task<bool> RunComplianceCheckAsync(PaymentProviderComplianceContext context){ const bool allow = true; return Task.FromResult(allow);} -
Register the function on the Payment Providers purchase service so Unity calls the function when a purchase begins:
m_PurchasingService.PaymentProviders?.SetComplianceCheck(RunComplianceCheckAsync);
-
Use the platform clients inside your check to call the APIs each platform requires for compliance:
- Apple: use to access Apple's external purchase APIs.
ExternalPurchaseClient - Google: use to access Google's external billing APIs.
ExternalBillingProgramClient
- Apple: use
Disclose or render the checkout URL
A platform might require you to display or disclose the external purchase URL before the player proceeds, or you might want to render the checkout in your own web view. In either case, callGenerateURLstring url = await m_PurchasingService.PaymentProviders.GenerateURL(catalogListingId);// Display or disclose the URL, then call PurchaseProduct to open the checkout.
PurchaseProduct(catalogListingId)GenerateURLAttach and report transaction tokens
This step is required when Apple or Google requires you to report external transactions (this varies by program and region). Apple and Google require you to report each external transaction back to them through their server APIs. You get an opaque transaction token from the platform, attach it to the Unity order, and receive it back in the order webhook so you can file your report. You generate the tokens yourself: Apple tokens come fromExternalPurchaseClientExternalBillingProgramClientPurchaseProductGenerateURL(catalogListingId, tokens)PurchaseProductUnity stores the tokens with the order without inspecting or validating them, and surfaces them in order webhooks. They're not returned in the order API response.await m_PurchasingService.PaymentProviders.GenerateURL(catalogListingId, tokenList);m_PurchasingService.PurchaseProduct(catalogListingId);
Tokens in the webhook payload
Order webhooks include anexternalTransactionTokensdata{ "eventType": "order.paid", "data": { "id": "...", "playerId": "...", "status": "paid", "externalTransactionTokens": [ { "store": "apple", "token": "opaque-apple-transaction-token", "type": "acquisition" }, { "store": "google", "token": "opaque-google-transaction-token" } ] }}
Use these tokens to self-report the transaction through Apple's External Purchase Server API or Google's
externalTransactions