Skip to content

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 failureReason and 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 code and message, and payment.status / failureReason if 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.