Mutual authentication, also known as two-way authentication, uses a client certificate in addition to the server certificate. Adyen verifies your certificate on every API request. This adds security on top of your API key.
Adyen acts as a certificate authority (CA) and issues client certificates. You send a certificate signing request (CSR) to the Management API. Adyen returns a signed certificate. You then link the certificate to an API credential. Your private key never leaves your system.
Adyen recommends that you enroll your client certificates with Adyen instead of another certificate authority. Enrollment with Adyen gives you faster onboarding, more control over your certificates, and faster support. If you must use another certificate authority, see Use a certificate from another certificate authority.
Requirements
Before you begin, take into account the following requirements, limitations, and preparations.
| Requirement | Description |
|---|---|
| API credential roles | Make sure that your API credential has the following roles:
|
| Setup steps | Before you begin:
|
| Limitations |
|
How it works
To set up mutual authentication:
- You create a private key and a certificate signing request.
- You send the certificate signing request to Adyen.
- Adyen signs the request and returns your client certificate and certificate chain.
- You link the subject DN of the certificate to an API credential.
- You send API requests to a mutual authentication endpoint with your certificate.
Adyen accepts the request when the subject DN of the certificate matches the subject DN stored for the API credential.
Generate a client certificate
To generate a client certificate:
-
Create a private key and a certificate signing request:
openssl req -new \ -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ -keyout client.key \ -out client.csr \ -subj "/CN=adyen-mtls-client"OpenSSL prompts for a passphrase and encrypts
client.keywith it. Keep both the passphrase andclient.keysecret. You cannot getclient.keyfrom Adyen if you lose it.Adyen does not use the subject in your certificate signing request. Adyen builds the
subjectDNof the signed certificate from the company account in the request path and theapiCredentialin the request body, in the format:UID={apiCredential}-Company.{companyId},CN={apiCredential}-Company.{companyId},O=Company.{companyId}Use any subject in the
-subjvalue. -
Convert the certificate signing request to a Base64-encoded DER string:
openssl req -in client.csr -outform DER | openssl base64 -A -
Make a POST
/companies/{companyId}/clientCertificatesrequest. In the request, include:Parameter Description apiCredentialThe API credential that you want to use the certificate with, in the format: ws_*@Company.*. The credential must belong to the company account in the request path. If you send a merchant-level credential, or a credential from another company account, you get a 403 error.certificateSigningRequestThe certificate signing request from the previous step, as a Base64-encoded DER string. curl https://management-live.adyen.com/v3/companies/YOUR_COMPANY_ACCOUNT/clientCertificates \ -X POST \ -H 'x-API-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "apiCredential": "ws_123456@Company.YourCompanyAccount", "certificateSigningRequest": "YOUR_BASE64_ENCODED_CSR" }'To try this out first, send the same request to management-test.adyen.com. Certificates that you generate in the test environment work only with the test mutual authentication endpoints.
-
Save the response to a file, for example
enrollment.json. Note the following:Parameter Description leafYour signed client certificate, as a Base64-encoded DER string. caChainThe certificate chain, including intermediate and root certificates. This does not include your certificate. subjectDNThe subject DN of your certificate. You need this in the next step. -
Assemble a PEM file that contains your
leafcertificate first, followed by eachcaChainentry in the order that the response returns them. This is the certificate bundle you present on every request.From the saved
enrollment.jsonfile, decode theleafand eachcaChainentry from Base64 DER into PEM. Write theleafandcaChainentries to aclient.crtfile:jq -r '.leaf, .caChain[]' enrollment.json \ | while read -r cert; do \ printf '%s' "$cert" | openssl base64 -d -A | openssl x509 -inform DER; \ done > client.crtUse
client.crt, together with your private key, as the client certificate on every mTLS request.Optionally, verify the bundle:
openssl crl2pkcs7 -nocrl -certfile client.crt | openssl pkcs7 -print_certs -nooutThe output shows the
leaffirst, followed by each CA in the chain up to the root.
Send your certificate and the chain together. If you send only your certificate, the TLS handshake fails with an unknown_ca alert, and you get no HTTP response.
To get the certificates that you already have, make a GET /companies/{companyId}/clientCertificates request. The response includes only the certificates that are neither expired nor revoked.
Link the certificate to your API credential
Adyen matches the certificate you present against the subject DN stored for your API credential. Link them in your Customer Area or with the Management API.
After you link a certificate, every request that uses this API credential to access an API that supports mutual authentication must present the certificate. Requests to those APIs without it fail. Make sure your integration is ready before you save.
Test your setup
Before you link a certificate to a live API credential, test the same process in the test environment.
To test your setup:
-
Generate a certificate with
https://management-test.adyen.com. -
Link the certificate to a test company-level API credential.
-
Send a request to a test mutual authentication endpoint with your certificate and private key:
curl https://checkoutcert-test.adyen.com/v72/paymentMethods \ -X POST \ --cert client.crt \ --key client.key \ -H 'x-API-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "YOUR_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 } }'Because
client.keyis encrypted, curl prompts for the passphrase. To send the request without a prompt, add--pass YOUR_KEY_PASSPHRASE. -
Check that the request returns an HTTP response from Adyen.
If the TLS handshake fails before you get an HTTP response, check that client.crt contains your certificate first, followed by the full chain.
Supported APIs
After you link a certificate, you must send requests to the following APIs over a mutual authentication connection with your client certificate:
Other APIs do not support mutual authentication. These include the Management API, the Balance Platform APIs, the Transfers API, the Legal Entity Management API, and the Terminal Management API. Requests to those APIs use your API key only, and you send them to their standard endpoints.
Endpoints for mutual authentication
When you send an API request, use the endpoint that supports mutual authentication.
For Checkout API:
| Environment | Region | Mutual authentication endpoint |
|---|---|---|
| Test | All | checkoutcert-test.adyen.com |
| Live | EU | checkoutcert-live-eu.adyen.com |
| Live | AU | checkoutcert-live-au.adyen.com |
| Live | US | checkoutcert-live-us.adyen.com |
In the live environment, the Checkout mutual authentication endpoint is regional. Do not use the {PREFIX}-checkout-live.adyenpayments.com endpoint that you use for API key authentication.
For Payment, Recurring, Payout, and BinLookup APIs:
| Environment | Region | Mutual authentication endpoint |
|---|---|---|
| Test | All | palcert-test.adyen.com |
| Live | All | palcert-live.adyen.com |
For example, to send a /paymentMethods request with mutual authentication in the EU region, use https://checkoutcert-live-eu.adyen.com/v72/paymentMethods.
Make a request with your client certificate
Use a certificate from another certificate authority
If you must use a certificate that is signed by another certificate authority, Adyen requires that:
- A certificate authority that Adyen trusts signs the certificate.
- The subject DN of the certificate matches the subject DN stored for the API credential.
After you get your certificate, link it to your API credential. If you are not sure whether Adyen trusts the certificate authority, contact our Support Team.