We are experiencing intermittent 403 Forbidden errors during Apple Pay on web merchant validation in our production and sandbox environment.
- Has anyone else started seeing 403 Forbidden errors recently (since mid-2025)?
- Why would merchant validation be sometimes successful and sometimes fail with 403?
- Could this be related to new Apple Pay gateway changes or stricter validation rules?
- Any additional debug steps or permanent solutions we should try?
Thank you.
Hi @fl1,
You wrote:
We are experiencing intermittent 403 Forbidden errors during Apple Pay on web merchant validation in our production and sandbox environment. [...]
During this time, the intermittent 403s could very well be attributed to Apple's phased TLS 1.3 enforcement rollout combined with the intermediate CA rotation — different merchants were affected at different times depending on which gateway nodes serve their region. Pair that with a hardcoded validationURL hostname allowlist and you have the recipe for the exact intermittent pattern you've described.
However, if anyone else experiences this behavior currently, I want to provide some debugging tips:
A 403 on the server-to-Apple hops is nearly always a certificate, domain, or request-body problem. A 403 on the browser-to-your-server hop is your own auth/CORS issue.
Start your investigation by validating your certificate chain:
# Validate your certificate chain end-to-end
openssl verify -CAfile AppleRootCA-G3.cer -untrusted apple-intermediate.pem merchant.pem
# Check expiry
openssl x509 -in merchant_identity.pem -noout -dates
# Confirm cert and key match (outputs must be identical)
openssl x509 -in merchant.pem -noout -modulus | openssl md5
openssl rsa -in merchant.key -noout -modulus | openssl md5
Apple re-fetches the domain association file on every validation session, not just at registration. It it's unavailable even momentarily, you get a 403.
# Test exactly as Apple does - no redirects, no auth
curl -v --max-redirs 0 \
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
Lastly, verify your merchant session requests:
# 1. Validate cert chain
openssl verify -CAfile apple-root-ca.pem -untrusted apple-intermediate.pem merchant.pem
# 2. Test mTLS handshake directly to Apple's gateway
openssl s_client -connect apple-pay-gateway.apple.com:443 \
-cert merchant.pem -key merchant.key -showcerts
# 3. Check certificate expiry
openssl x509 -in merchant.pem -noout -dates
# 4. Verify domain association file
curl -I https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
# 5. Replicate the Apple validation POST with curl
curl -v \
--cert merchant_identity.pem \
--key merchant_identity.key \
--header "Content-Type: application/json" \
--data '{"merchantIdentifier":"merchant.com.example","domainName":"example.com","displayName":"Example Store","initiative":"web","initiativeContext":"example.com"}' \
"https://apple-pay-gateway.apple.com/paymentservices/startSession"
Cheers,
Paris X Pinkney | WWDR | DTS Engineer