A0018, A0001 and C0005. They look alike —
a code, a short message, no detail — but they need completely different responses. This page is the
decision tree. Per-code reference is the published
Error code list; the
mechanics of each code are in
Common Errors Troubleshooting and
Limits, Currency & Configuration Errors.
Which of these am I looking at?
The first letter is the fastest triage there is:
A is yours to fix, C is on the Waffo or
payment-method side, E means undetermined. Never treat an E as a failure — the rule and the
retry pattern are in the published
Error handling.
Is A0018 “not enabled yet”, or did I send something wrong?
Both are possible, and this is the crux of the question. A0018 does not mean “the payment method
you named is not signed”. It means nothing you are contracted for survived the whole request,
and the request narrows the candidates on many dimensions at once. Any one of them can empty the
set, and they all come back as the same code and the same message.
Work through them in this order — the first mismatch you find is your answer:
So: not-enabled and sent-wrong are distinguished by elimination, not by the code. The fastest
way to separate them:
- Call
/api/v1/paymethodconfig/inquiry. If the method, country and currency combination is not in the response, it is a setup question — nothing you change in the payload will help. - If it is in the response with an availability of “available”, the combination is contracted and the rejection came from something the request itself added — one of rows 1, 6, 7, 8, 9 above. Remove the optional narrowing parameters one at a time and retry.
A0018 and mean the opposite of a missing contract — they mean you have
more than one match and must be specific: A0022 (name the product) and A0033 (name the
payment-method country).
Why isn’t an unsupported currency its own error code?
Because the currency is one of the dimensions above, not a separate check. An order currency or a currency pair you are not contracted for comes back asA0018, with the payment-method wording. Do
not wait for a currency-specific code — see
Do I have to enable a currency before I can use it?.
The same code appeared on a subscription. Does it mean the same thing?
The code is shared but the reading differs. On the acquiring side it is the contract mismatch above. On the subscription side it means there is no usable payment method left to charge that subscriber with — for example the saved method has been removed. The published code list glosses it the second way; the message text you receive is the contract wording. Read it together with the API you called. One consequence worth building for: on a renewal after the first period, this code is treated as not retryable — the schedule will not keep trying it. Fix the payment method rather than waiting for a retry. See Subscription retries & payment methods.I rotated my keys and now I get A0001. Is the new key broken?
Usually not. Three things to rule out, in order:
How long that window is, the exact order in which the key, its scope, the signature and your IP
allowlist are checked, and how
A0001 differs from A0002 and from a scope refusal, are in
API Credential Scope & Auth Error Triage. The
submission and rotation procedure, and where to see why a submission was rejected, are in
Production API Keys & Public Keys.
If the key is accepted but the call is refused anyway, the cause is usually what that key is
permitted to do — a different rejection, not A0001.
What does C0005 actually tell me, and where is the reason?
C0005 — Payment channel rejection — means the payment method refused the payment. On its own it
tells you almost nothing, because it is the code a wide range of underlying refusals map to,
including every card decline.
The detail is in the failure reason returned with the order, which has two halves:
They arrive together as
orderFailedReason on
Order inquiry, and the Portal shows the same pair on the transaction
record as Order Failure Code and Order Failure Description — see
Transaction Field Reference.
So the routine is: never branch on C0005; branch on the failure code inside it. Descriptions
such as an authentication step that could not be started, or a card refused by the issuing bank on
fraud or on legal grounds, are exactly the sort of thing that arrives this way, and they call for
very different handling.
Which C0005 failures are worth retrying?
Retryability belongs to the underlying reason, not to C0005. The classification and what to do
about each class — including which declines must never be retried and which need the customer to
re-enter their credential — is in
A card was declined. Should I retry?.
Two rules on top of that:
- Show the customer a usable message and offer another payment method. Waffo checks exactly this behaviour during integration acceptance for channel rejections and system-unavailable responses — see the published Acceptance criteria.
- In the sandbox, several reserved amounts return
C0005on purpose so you can build that path. If you getC0005on an amount you did not expect to be special, check the reserved list before concluding anything — see Sandbox simulator.
A refund came back A0017. Can that order ever be refunded by API?
A0017 — the order cannot be refunded because the payment channel does not support it — comes
from the payment method itself, and it is not retryable. Sending it again unchanged produces the
same answer.
Before treating it as final, separate it from the other refund rejections:
All four, and what to do in each case, are in
Payment Method Refunds & Limits and
Refund FAQ.