Errors¶
Aptean Pay reports problems in three different places depending on what went wrong. Knowing which one you are looking at tells you where to start.
| Where the error appears | What it means |
|---|---|
errors[] at the top level, with data: null |
The request was refused before anything happened: authentication, invalid input, or an operation that is not allowed. Read message and extensions.exception.reasonCode. |
code: "ERROR" with a payment whose status is FAILED |
Aptean Pay sent it; the processor declined. Read message and errorReason. |
code: "SUCCESS" with payment.status: "PENDING" |
Not an error. Accepted and still in progress. See Payment status. |
The shapes are described in Requests and responses.
Authentication: the FORBIDDEN codes¶
These arrive as Context creation failed: FORBIDDEN [n]: Call is forbidden. The number is the
diagnostic, and it is the fastest way to work out which of your four credentials is wrong.
| Code | Meaning | Fix |
|---|---|---|
Not Authenticated |
No x-aptean-apim header at all. |
Send your API key. |
[0] |
Aptean Pay could not determine the client IP. | Unusual. Check for a proxy stripping the connection, then contact Aptean support. |
FORBIDDEN [2] |
The API key is not valid. | Check x-aptean-apim. Keys are environment-specific — a staging key will not work against production. |
FORBIDDEN [3] |
The API key is valid, but that tenant has no subscription to this service. | Check x-aptean-tenant. If it is right, the tenant is not provisioned — contact Aptean support. |
FORBIDDEN [4] |
No role could be resolved for the call. In practice: the tenant secret is missing or wrong. | Check x-aptean-tenant-secret. |
FORBIDDEN [5] |
The API key has no role attached to it. | A provisioning problem, not a code problem. Contact Aptean support. |
FORBIDDEN [6] |
You have a checkout API key and did not send x-aptean-product. |
Add the x-aptean-product header. |
Tip
FORBIDDEN [2] versus FORBIDDEN [4] is the distinction worth memorising. [2] is
your API key; [4] is your tenant secret. Everything else is provisioning.
A plain Response not successful: Received status code 400 from a GraphQL client usually hides one
of these. Look at the response body rather than the status code.
Mutation status codes¶
| Code | Meaning |
|---|---|
SUCCESS |
Accepted. Check the object's own status for what happened next. |
PENDING |
Accepted and still in progress. |
ERROR |
Refused. message says why. |
Idempotency¶
Applies to createPayment and createRefund.
| Message | Cause |
|---|---|
idempotency key is required |
No idempotency-key header. Both mutations require one. |
idempotency key has already been used, a unique key must be provided |
An earlier call with that key succeeded. Do not retry with a new key: find the payment or refund. See Idempotency. |
If you get the second message on what you believe is a first attempt, your code is reusing a key across different operations. Generate one key per payment or refund.
Errors by operation¶
Each guide lists the exact messages for its own mutation:
| Operation | Errors |
|---|---|
| Capture a card / bank details | Card, Bank |
| Create a payment | Common failures |
| Capture | Common failures |
| Cancel | Common failures |
| Refund | Common failures |
| Payment request | Common failures |
Processor declines¶
When code is ERROR and payment.status is FAILED, the card issuer or bank declined it.
Aptean Pay did its job; the money was refused downstream.
You cannot fix a decline in code. What you can do:
- Read
failureReasonand show the payer something useful. - Collect a different payment method. Most declines are card-specific: expired, over limit, reissued, or blocked for that merchant category.
- Do not retry the same card in a loop. Repeated declines are visible to the card networks and count against your merchant account.
- Check you are in the right environment. A real card in staging will always fail, and a test card in production will always fail.
Note
In staging, the most common "mystery decline" is not a bug. Cards outside the
sanctioned test list — 4111 1111 1111 1111 in particular — are
designed to decline. Check your test data before investigating anything else.
Something genuinely wrong?¶
If you have an error you cannot place, gather these before contacting Aptean support:
- The environment and the host you called.
- The mutation or query name — not the whole document.
- The
codeandmessage, andpayment.status/failureReasonif present. - The relevant
id(payment, refund, payment request, checkout session). - Roughly when it happened.
Warning
Never include your tenant secret, your API key, a full card number or a
paymentUrl in a support ticket. None of them are needed to diagnose anything, and all of them
are sensitive.