Apple Pay on the web: merchant domain verification step-by-step

Apple Pay on the web requires a domain-association file at /.well-known/apple-developer-merchantid-domain-association. Where it comes from and how to host it correctly.

To accept Apple Pay on the web (Safari, via the Payment Request / Apple Pay JS API), Apple makes you register and verify each domain. Verification is a file hosted at https://yourdomain/.well-known/apple-developer-merchantid-domain-association — no extension, exact path. A wrong content type or a redirect makes the Apple Pay button fail to render with a generic console error.

This is the end-to-end setup and the gotchas that cause “domain verification failed.”

If you only use Apple Pay inside the native app (PKPaymentAuthorizationViewController), you do not need this file — it’s web-only. For the full submission picture see every URL and file Apple requires for an iOS App Store submission.

When you need it

Apple Pay usage Domain-association file needed?
In-app Apple Pay (PKPaymentAuthorizationController) No
Apple Pay on the web (Safari, Apple Pay JS) Yes, per registered domain
Apple Pay via a payment processor’s hosted page Depends — often the processor’s domain, not yours

If your checkout runs Apple Pay on your domain, you register that domain. If it runs inside Stripe/Braintree/Adyen’s hosted fields, the processor often handles their own domain — check their docs first; you may not need this at all.

Step 1: Get the file from the Apple Developer portal

  1. Apple Developer portal → Identifiers → Merchant IDs (create one if needed).
  2. Select the Merchant ID → Merchant Domains → Add Domain.
  3. Enter the exact domain.
  4. Apple provides apple-developer-merchantid-domain-association to download.

Apple’s official environment guide: Configuring your environment for Apple Pay on the web.

Step 2: Host at the exact path, exact content type

Serve the file at:

https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association

Note: no file extension. That’s the single most common mistake — people add .txt or .json. The path is literally the filename with no extension.

Apple’s fetcher requires:

  • Exact path, no extension.
  • HTTPS, valid cert.
  • HTTP 200, no redirects (apex/www redirect kills it — same gotcha as Sign in with Apple).
  • Reachable by Apple’s servers (no bot challenge, no auth wall).

Verify:

curl -i https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
# Expect HTTP 200, no Location header. Content-Type is flexible here
# (Apple checks the body), but octet-stream or text/plain both work.

Step 3: Verify in the portal

After the file is live, click Verify on the domain in the Merchant ID configuration. Apple fetches the file and compares it to what it issued. Success → the domain is registered and ApplePaySession.canMakePayments() will work from it.

The gotchas

1. The extension reflex

Static-site workflows and many editors want to add an extension. apple-developer-merchantid-domain-association.txt is wrong — it must be served at the extension-less path. On hosts that map content type from extension, you may need an explicit rule:

# Cloudflare Pages / Netlify _headers
/.well-known/apple-developer-merchantid-domain-association
  Content-Type: application/octet-stream

2. Redirect on the .well-known path

A catch-all redirect (http→https, apex→www, trailing-slash normalization, SPA fallback to index.html) that touches /.well-known/* breaks verification. Exclude .well-known from SPA rewrite rules.

3. Per-domain, and re-verify after Merchant ID changes

Each domain you serve Apple Pay from needs its own registration. If you recreate the Merchant ID, the file content changes — re-download and re-host. Subdomains are separate domains for this purpose.

How OrbitKit handles it

OrbitKit hosts the Apple Pay merchant domain-association file at the correct extension-less path, served from your custom domain alongside your AASA file, Sign in with Apple file, privacy policy, and support page. Upload the file Apple gives you once; it’s served correctly. Start free or see features.