Domain configuration for Apple Pay
To enable Apple Pay in your store, you must serve the .well-known/apple-developer-merchantid-domain-association file at the root of every domain where the payment button will be shown.
Required in every integration model
This step is required even if you install the Appmax app via the AppStore (integrated model, with a client_id/external_id per store). What changes between models is only who registers the domain with Apple — you always publish the .well-known file yourself. See Apple Pay payment for the full flow and the distinction between models.
What is this file for?
Apple requires this file as part of its domain verification process. It proves that Appmax is authorized to process Apple Pay payments on the domains you inform.
Apple uses this file to validate that the domain is correctly linked to the Merchant ID configured by Appmax. Without it, the "Pay with Apple Pay" button won't work in production — the PaymentSheet won't open, or domain validation fails on every transaction attempt.
The .well-known file is not the Apple Token
The Apple Token is the tokenized card, generated per transaction (see Apple Pay payment). The .well-known file is static, the same on every domain, tied to Appmax's merchantIdentifier — not to the transaction.
1. File content
Save the text below to a file named apple-developer-merchantid-domain-association (no extension). It is the same content for every domain in your implementation:
7b2276657273696f6e223a312c227073704964223a2238383637324534354136323336423032384645463731323938334343354338354339334633353231433430374142313338414543354144434641334330334442222c22637265617465644f6e223a313735323630333939333937337d
Copy it exactly as is — with no trailing newline
Apple validates the content byte for byte: one extra space or line break invalidates the domain verification.
This is the most common cause of failure, because virtually every text editor appends a \n on save, and echo does the same. The file is exactly 228 bytes. To create it without a trailing newline, use printf (not echo):
printf '%s' '7b2276657273696f6e...' > apple-developer-merchantid-domain-associationIf your editor can't save without the trailing newline, generate the file from the command line.
2. Publish the file on each domain
The file must be published at the following path on each domain where Apple Pay will be used, without renaming it:
https://<store-domain>/.well-known/apple-developer-merchantid-domain-associationExamples:
https://domain1.com/.well-known/apple-developer-merchantid-domain-associationhttps://domain2.com/.well-known/apple-developer-merchantid-domain-associationhttps://store3.com/.well-known/apple-developer-merchantid-domain-association
3. Verify accessibility
After publishing the file, confirm it's accessible:
curl -sI https://<store-domain>/.well-known/apple-developer-merchantid-domain-associationThe expected response should contain:
HTTP/2 200 OK(orHTTP/1.1 200 OK)Content-Type: text/plain- No redirects (neither
301/302fromhttptohttps, nor fromwwwto the root domain or vice versa)
Check the size too — this is what catches the extra newline:
# must print exactly 228
curl -s https://<store-domain>/.well-known/apple-developer-merchantid-domain-association | wc -ccurl -I alone proves nothing
On HEAD requests, many servers don't return Content-Type — so the command can give the impression everything is fine without checking the content at all. Run both: -sI for status and headers, and wc -c for the byte count.
The file has no extension
Because the filename has no extension, many servers and CDNs serve it as application/octet-stream, or force it to download as an attachment. Apple requires it to respond as text/plain. The three most common situations:
Nginx — declare the type for that exact path:
location = /.well-known/apple-developer-merchantid-domain-association {
default_type text/plain;
add_header Cache-Control "public, max-age=3600";
}Apache — in the root .htaccess:
<Files "apple-developer-merchantid-domain-association">
ForceType text/plain
Header set Cache-Control "public, max-age=3600"
</Files>Frameworks (Next.js, Nuxt, Laravel) — when the static folder doesn't let you control the header, serve it from a dedicated route. Next.js (App Router) example:
// app/.well-known/apple-developer-merchantid-domain-association/route.ts
export function GET() {
return new Response(process.env.APPLE_MERCHANT_ASSOCIATION!, {
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'public, max-age=3600',
},
});
}Be careful when storing the content in an environment variable: some dashboards append a newline. A .trim() on the value avoids the problem.
4. Registering the domain with Apple
Once the file is published and accessible, how the domain gets registered with Apple depends on your integration model:
- Integrated model (AppStore installation): registration is done by Appmax, via API, as soon as the domain is informed during app installation (the
domain_nameordomain_namesparameter). The file just needs to already be published by then. - Direct flow: you register the domain yourself, in the Apple Developer portal, under your own Apple account. Apple validates the
.well-knownfile at registration time.
In both cases, if the store's domain changes, the new domain is treated as a new one — republish the .well-known file on it and register it again (no need to create a new merchant).
Best practices
- HTTPS is mandatory: the domain must respond only over a secure connection.
- Avoid redirects: the URL must respond directly with a 200 status, without going through
www, anhttp→httpsredirect, or any other redirect before reaching the file. - Don't change the file's content: its internal hash is validated by Apple.
- Content-Type: serve the file as
text/plain. - Suggested Cache-Control:
public, max-age=3600.
If you have questions, contact Appmax technical support.