What does the API return when a payment is declined by risk?
Two codes, both returned on the order request itself with HTTP406:
They are the risk decision surfacing directly. Treat both as final for that order — they are a
decline, not a retryable transport failure and not a review queue you can wait on.
D0001 also
exists on the payout, card, and point-topup surfaces with the same meaning, so a single handler can
cover it; D0002 belongs to the payin surface.
How do I tell a risk decline from a payment method decline in my code?
It depends which surface you are reading, and this is the part that catches people out.
Concretely, on the asynchronous surfaces the failure arrives as
orderFailedReason, a JSON value
with orderFailedCode and orderFailedDescription. orderFailedCode is a category, not the
specific code you saw on the synchronous response, and orderStatus is the ordinary closed-order
status — there is no risk-specific order status.
Two practical rules follow:
- Record the synchronous code when you get one. It is the only place the distinction is machine-readable. Persist it against your own order.
- Do not branch on the description string. It is free text intended for a human reading a support ticket, and it is not a stable interface.
My payment was refused for a limit. Which limit, and can I change it?
Limits come from several places and they use different codes from the risk codes above:
Which of these you can influence, how the daily figure is counted, and when headroom is released
are covered in Error Codes & Limits Supplement and
Payin Agreements & Limits. The short version: the
amount range and the ceilings come from what your account is set up with, so changing them is a
conversation, not a Portal setting — with one exception, below.
Can I set my own per-card or per-user restrictions?
Yes, through the transaction limit rule API, which is the one risk-adjacent control you operate yourself. It is API-only — there is no Portal screen for it. Endpoints, request shape, what a rule can key on, and how to read or stop one are in Transaction Limit Rules. Three things worth knowing before you arm one:- A triggered rule declines the payment as a risk decision — the shopper’s payment fails with the risk codes above, not with a distinct “your rule fired” code. So on the asynchronous surfaces you cannot attribute a decline to your own rule; keep your own record of what you restricted.
- A rule can affect an order that already exists. Risk is consulted when the shopper actually pays, not when you created the order, so an order created before you armed the rule but paid after will be evaluated against it. Only payments that already succeeded are untouched.
- It only ever adds restriction. There is no rule direction that exempts a card or a user from screening.
When does 3D Secure happen, and can I decide it?
You can express a preference on the order, usingthreeDsDecision inside the card information:
Any other value is rejected as invalid card information. But the field is a preference, not a
switch, and three things sit above it:
- The risk decision. Your value is one input to risk, which returns the decision that is actually used.
- What the payment method can do. The decision has to be satisfiable by the route the payment takes. Where nothing can satisfy it, the order fails rather than silently downgrading.
- The issuer. Even on a 3D Secure payment, whether the shopper is challenged or passes without interaction is the issuer’s call, not ours and not yours.
3DS_FORCE is best read as “do not skip this”, and NO_3DS as “skip it if that is allowed”.
I sent NO_3DS and the shopper was still asked to verify. Did I send it wrong?
Probably not. Given the order above, an authentication step can still appear because the risk
decision or the payment route required it. The field is validated, so a genuinely malformed value
would have failed the request with an invalid-card-information error rather than being ignored — if
your order was accepted, the value was understood.
The other case to rule out is scope: the field is only effective for card, Apple Pay and Google
Pay payments where the shopper is present. On any other payment method it does nothing.
Can I set a 3D Secure decision on a subscription renewal or another merchant-initiated charge?
No, and this is why it looks like it is being ignored: the value is accepted and validated but not applied to merchant-initiated card transactions. Subscription renewals are merchant-initiated, so athreeDsDecision on one has no effect and produces no error.
Where authentication for a recurring series happens is at the point the shopper is present — the
first payment, or the mandate setup. See
Subscriptions and
Tokenization.
How does a challenge reach the shopper, and what must my own front end handle?
Whenever an extra step is needed, the order comes back with the status that means authorization is required, and anorderAction describing where to send the shopper:
If you use the Waffo-hosted checkout, this is handled for you — the shopper is taken to the
authentication page and brought back. If you build your own front end, you must:
- Detect the authorization-required status on the create response (and on inquiry).
- Parse
orderActionand branch onactionType. - Perform a full-page navigation. Do not attempt it inside a small frame: authentication pages commonly refuse to render framed, and the shopper is left staring at an empty box.
- On return, do not treat the return itself as the result. Poll an order inquiry, or wait for the payment notification.
actionData can carry for methods that need a code, a QR
or bank details, is in Order create field guide and
Redirects & action types.
Is risk evaluated on every transaction in real time?
Yes. The evaluation happens inside the payment request, before the payment is attempted, and the outcome is applied to that order immediately. There is no batch pass and no later re-scoring of a payment that already went through. That also explains a pattern that looks inconsistent: a shopper’s first payment succeeding and a second one being declined is entirely normal. Each payment is assessed on its own, in its own context — amount, method, history, what happened in between — so the outcome can differ between two payments from the same person minutes apart.Where can I see risk-declined transactions in the Portal?
Per order, not as a category:
So the workflow is: find the volume in failure analysis, then use your own records to pull the
individual orders. The filters the payment list does offer are in
Portal List Filters & Date Ranges.
What does the failure analysis tell me, and can I drill down to the orders?
It tells you how many and why, grouped as: failures attributable to the payment method side, to the customer side, and to your side, each expanding to individual failure descriptions with their counts and share. It does not drill down to orders. The request behind the panel is parameterised by product, subscription stage, countries, payment methods and the interval — never by order, and the response carries counts rather than order identifiers. There is no link that carries a failure reason into the payment list as a filter. What the panel counts, and why analytics figures do not tie exactly to a list count, is in Portal Dashboards & Analytics.Do declined transactions count against my success rate?
Yes. The success rate is successful orders divided by orders created, so every order that was created and then declined — for any reason, risk included — stays in the denominator. The Portal shows this alongside two narrower ratios: how many created orders reached the payment step, and how many of those succeeded. Because a risk decline happens at the payment step, it lands in the denominator of the narrower ratio too, not only in the overall one. Practical consequence: pre-qualifying traffic before you create an order improves the ratio; declining it after you create one does not.Can I see my own chargeback rate and fraud-report rate?
Yes, on Chargeback Analytics, where they are reported per card scheme rather than as one blended number, because the schemes define them differently:
Note both numerators are received in the period, not “belonging to payments made in the period” —
a chargeback lands months after the payment, so the ratio is a period measure, not a cohort measure.
The screen also gives chargeback counts and amounts, a trend, a reason-code distribution, and cases
approaching their deadline. Data is a day behind, and the period you can select is bounded.
What each ratio card measures and which period it reports on is also in
Portal Dashboards & Analytics. What to do about a case is in
Chargebacks and
Chargeback Evidence.
Are fraud reports the same thing as chargebacks, and can I query them separately?
They are not the same thing: a fraud report is the issuer telling the scheme a transaction was fraudulent, and it may arrive without a chargeback ever following — which is why it appears in its own ratio above. Individual fraud reports can be queried separately, through the Reported Fraud list API (/api/v1/fraud-report/list, filtered by report date, scheme or a single order). There is no
Portal list page for them — the Portal shows only the aggregate inside Chargeback Analytics. Field
by field, see Reason codes & Reported Fraud.
A payment was declined and I think it should not have been. Can I appeal, or have a card allowlisted?
There is no self-serve mechanism for either — no appeal endpoint, no allowlist or exemption for a card, a shopper or a range, and no Portal screen for it. The only merchant-operated risk control is the limit rule API, and it only adds restriction. So the route is your support contact, with the order identifiers. Do not rebuild the payment as a retry loop: repeated attempts on a declined instrument are themselves a risk signal. The IP allowlist is a different feature and is self-serve — it restricts which of your servers may call the API, and has nothing to do with screening shoppers. See Portal Self-Service Security Configuration.Can I test a risk decline or a 3D Secure challenge in the sandbox?
Not directly. The sandbox simulator drives outcomes by order amount, and the outcomes it can produce are payment failure, system error and unknown status on create, cancel and refund paths — listed in Sandbox simulator. None of them produces a risk-decline code, and none forces an authentication challenge. What you can and should do instead:- Exercise your handling, not the trigger. Your code paths for a declined order and for an authorization-required order are the same regardless of which reason produced them, so simulate a failure and an authorization step and prove your handling.
- Handle the risk codes defensively in production from day one, since you cannot rehearse them.