Appearance
Server Configuration for Apple App Store
This page explains the server configuration needed for App Store IAP validation.
Appearance
This page explains the server configuration needed for App Store IAP validation.
If you use in-app purchases on App Store, there is some configuration the server needs to validate purchases. This should be done as part of step 9. Configure the Servers for Real Purchase Validation of the basic IAP guide.
Configure at least the application's bundle ID.
AppleStore:
# App Store / iOS configuration, needed to validate App Store IAPs:
IosBundleId: com.examplecompany.examplegame⚠️ IAP Receipt Reuse
If IosBundleId is not set, the backend cannot check the receipt came from the correct application. A malicious actor could successfully use receipts from another application that has the same product IDs.
By default, real-money (non-sandbox) purchases are only accepted in production environments. If you need to use real-money App Store purchases also in your development or staging environments, you can set option AppleStore:AcceptProductionPurchases to true in the appropriate Options.<env>.yaml file.
If you plan to use Auto-Renewing Subscriptions, you'll also need to configure credentials for the server to make queries to Apple's APIs.
The configuration required depends on whether you're using Unity IAP v4 or v5.
If your application doesn’t already have a shared secret, please follow Apple’s developer documentation on generating it. It can be either a primary shared secret or an app-specific shared secret.
The shared secret is a hexadecimal string. Store it as a secret in the correct environment:
# Below, replace my-environment with the environment ID (e.g. your production environment).
# Your local file apple-shared-secret.txt must contain the generated Shared Secret value.
metaplay secrets create my-environment user-apple-shared-secret --from-file=secret=apple-shared-secret.txtUpdate the server’s Options.*.yaml file accordingly:
AppleStore:
# ... pre-existing values omitted from this snippet ...
AppleSharedSecretPath: "kube-secret://user-apple-shared-secret#secret"If you need to test the secret on your local machine, you can put it in a temporary file and use file://your/path/to/shared-secret instead of kube-secret://.... You should not commit it, as it's best to avoid putting secrets in a code repository.
If your project uses Unity Purchasing v5, it uses Apple's StoreKit 2 by default, and the server needs an Apple In-App Purchase key in addition to the shared secret. The key authenticates against Apple's App Store Server API for subscription state queries; the shared secret is still used for purchases made on v4 clients or older iOS versions with StoreKit 1.
In App Store Connect, go to Users and Access → Integrations → Keys → In-App Purchase and click Generate In-App Purchase Key. Download the .p8 private key file, and note the Key ID and the Issuer ID shown at the top of the page. Generating the key requires the Account Holder or Admin role in App Store Connect; the key itself is not role-scoped.
Build a JSON document with the three values:
{
"issuerId": "57246542-96fe-1a63-e053-0824d011072a",
"keyId": "2X9R4HXF34",
"privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
}Store the document as a secret. As with the shared secret, the recommended approach is a Kubernetes Secret:
# Below, replace my-environment with the environment ID.
metaplay secrets create my-environment user-app-store-connect-api --from-file=credentials=app-store-connect.jsonReference the secret from your runtime options:
AppleStore:
# ... pre-existing values omitted ...
AppStoreConnectApiCredentialsPath: "kube-secret://user-app-store-connect-api#credentials"