Authentication¶
Every call to the Aptean Pay Merchant API is authenticated with headers. There is no OAuth flow and no bearer token to refresh — you send the same credentials on every request.
Your credentials¶
Aptean issues these to you during onboarding. You need all of them before you can make a call.
| Credential | Header | What it is |
|---|---|---|
| API key | x-aptean-apim |
Identifies your product. Specific to one environment. |
| Tenant ID | x-aptean-tenant |
Identifies the merchant you are acting for. |
| Tenant secret | x-aptean-tenant-secret |
Proves you are allowed to act for that tenant. |
| Product ID | x-aptean-product |
Identifies your product to the checkout service. |
Warning
The tenant secret is a secret. It must only ever be sent from your server. Never put it in browser JavaScript, a mobile app bundle, or anything a customer can read. The JS SDK is deliberately designed so that the browser never needs it.
The headers to send¶
For most integrations — creating payments, refunds, payment requests, credit memos — send these three:
{
"x-aptean-apim": "<your api key>",
"x-aptean-tenant": "<your tenant id>",
"x-aptean-tenant-secret": "<your tenant secret>"
}
When you also need x-aptean-product¶
If your API key is provisioned as a checkout API consumer — that is, you are using hosted checkout — the product ID is mandatory and the call is rejected without it:
{
"x-aptean-apim": "<your checkout api key>",
"x-aptean-product": "<your product id>",
"x-aptean-tenant": "<your tenant id>",
"x-aptean-tenant-secret": "<your tenant secret>"
}
Note
This is the single most confusing part of Aptean Pay authentication. Whether
x-aptean-product is required depends on the role attached to your API key, not on which
mutation you are calling. If you have been given a checkout key, always send it. If you get
FORBIDDEN [6], you have a checkout key and you have omitted it — see Errors.
When you also need idempotency-key¶
Two mutations require an idempotency key, because retrying them by accident would take money twice:
createPaymentcreateRefund
{
"x-aptean-apim": "<your api key>",
"x-aptean-tenant": "<your tenant id>",
"x-aptean-tenant-secret": "<your tenant secret>",
"idempotency-key": "<a unique value you generate>"
}
About the idempotency key¶
It is not a credential. It stops a retried createPayment or createRefund from running twice.
How to generate it, and what to do when a retry is refused, is in Idempotency.
Checking your credentials work¶
Open the GraphQL playground in staging, paste your headers into the HTTP HEADERS tab, and run:
A result means your API key, tenant ID and tenant secret are all valid and matched to each other. An error means one of them is wrong — Errors will tell you which.
Production has no playground. Send the same query from your server, as shown in Requests and responses.