When a transaction does not result in an approval, the response and the Transaction Processed Webhook carry four fields that explain the outcome. Understanding the difference between them is essential for building reliable decline-handling logic.
Deciding the Outcome
Read an authorize response in two steps:
- Which branch came back. The response carries exactly one of
result,action,redirectorform_submit. Anything other thanresultmeans the customer has a step to complete first, such as 3-D Secure or a redirect; the final outcome arrives later by webhook or through the Transaction Status API. result.status.APPROVEDmeans the payment succeeded, andresult.approvedistrueexactly then.PENDINGmeans wait for the webhook.DECLINED,INVALID,CANCELEDandSESSION_EXPIREDmean it failed.
Use processing_code to explain a failure, not to detect success. An INVALID transaction carries a 2xxx code (2000 when nothing more specific applies) or 1001, with the reasons in errors. A request rejected before a transaction is created gets HTTP 422 with errors and no result. Webhooks carry the same status and processing_code in payload.
Response Fields
A transaction response and a webhook payload carry the following outcome fields. The API response leaves out a field that has no value; the webhook sends it as null.
| Field | Source | Stability | Intended Use |
|---|---|---|---|
processing_code |
Gateway (normalized) | Stable, enumerated | Primary field for decline-handling logic. |
response_message |
Gateway (normalized) | Stable, enumerated | The processing code's name, for example TRX_STATUS_DECLINED for 1000 or RISK_FAILED_FRAUD for 4101. If provider details are enabled for your account, it can carry the provider's own message instead. |
payment_provider_response_code |
Upstream PSP (raw) | Varies per provider and over time | Logging, support investigations, reconciliation. |
payment_provider_response_message |
Upstream PSP (raw) | Varies per provider and over time | Logging and diagnostics only — do not branch on this value. |
On a merchant-level response or webhook, payment_provider_response_code and payment_provider_response_message have no value unless provider details are enabled for your account. To receive payment_provider_response_message on a webhook endpoint, ask Finrelay to include it for that endpoint. The merchant portal has no setting for it.
Recommendation
Decide success on status, and map your decline-handling logic to processing_code. The gateway normalizes upstream PSP responses into a stable, enumerated set of processing codes. PSP codes differ between providers, change over time, and are not guaranteed to be stable — use them for logs and support tickets, not for logic.
Processing Code Reference
Processing codes are grouped into families by the leading digit. Handling guidance for each family is summarized below the table.
0000 — Approved
| Code | Description |
|---|---|
0000 |
Transaction approved successfully |
1xxx — Transaction lifecycle and basic declines
| Code | Description |
|---|---|
1000 |
Transaction declined (generic decline from the issuer/PSP) |
1001 |
Transaction failed |
1002 |
Transaction pending (not yet in a terminal state) |
1003 |
Transaction canceled |
1004 |
Transaction declined — insufficient funds |
1005 |
Session expired |
2xxx — Invalid request
Validation and configuration errors. These will not succeed on retry with the same input.
| Code | Description |
|---|---|
2000 |
Invalid request (generic) |
2001 |
Payment method expired |
2002 |
Payment method invalid |
2003 |
Payment method not found or invalid |
2004 |
Payment method type not supported |
2005 |
Payment method blocked |
2006 |
Payment method inactive |
2007 |
Installments not supported for this payment method |
2008 |
Payment link expired |
2009 |
Payment link not found |
2010 |
Transaction type not supported |
2011 |
Transaction feature not supported |
2012 |
Installments not supported |
2013 |
Terminal not found |
2014 |
Terminal inactive |
2015 |
Terminal not accepting payments |
2016 |
Terminal does not support installments |
2017 |
Merchant inactive |
2018 |
Feature not enabled |
2019 |
Merchant does not support tokenization |
2020 |
Card CVV invalid |
2021 |
Payment provider account inactive |
2022 |
Shop (location) inactive |
2023 |
Account inactive |
2024 |
Payment provider inactive |
3xxx — Authentication (3DS)
| Code | Description |
|---|---|
3000 |
Authentication not performed or incomplete |
3001 |
Authentication rejected by the issuer |
3002 |
Authentication unavailable |
4xxx — Risk
Declined by the gateway's risk engine before reaching the PSP. Retrying the same transaction will produce the same result.
| Code | Description |
|---|---|
4100 |
Blacklist rule matched (customer, card, or merchant) |
4101 |
Fraud check failed |
4200 |
Velocity check failed (generic) |
4201 |
Velocity check failed — customer limit exceeded |
4202 |
Velocity check failed — merchant limit exceeded |
4203 |
Velocity check failed — PSP limit exceeded |
Handling Guidance
Use the following patterns to map processing codes to user-facing behavior:
| Family | Retryable? | Recommended action |
|---|---|---|
0000 |
— | Treat the transaction as successful. |
1000, 1001, 1004 |
Sometimes | Prompt the customer to try a different payment method or contact their issuer. Do not retry the same card automatically. |
1002 |
Wait | Do not finalize the order. Wait for the final webhook (transaction-svc:transaction:authorized / transaction-svc:transaction:declined) or poll the Transaction Status API. |
1003 |
No | Transaction was canceled; offer the customer to start a new checkout. |
1005 |
No | The checkout session has expired — start a new session. |
2001, 2002, 2003, 2020 |
No (same input) | Prompt the customer to correct card details or use a different card. |
2004, 2005, 2006, 2007, 2010, 2011, 2012, 2019 |
No | Offer an alternative payment method. The selected method/feature is not supported for this transaction. |
2008, 2009 |
No | The payment link is no longer valid. Generate a new payment link. |
2013 – 2018, 2021 – 2024 |
No (configuration) | Non-retryable configuration issues. Log the response and contact Finrelay support. |
3000, 3001, 3002 |
No (as-is) | 3DS authentication did not succeed. Prompt the customer to retry authentication or use a different card. |
4xxx |
No | The transaction was blocked by the risk engine. Do not retry automatically. Inform the customer and, where appropriate, escalate to support. |
Logging PSP details
When you receive payment_provider_response_code and payment_provider_response_message, persist them alongside processing_code in your transaction records. These raw values are invaluable when reconciling with PSPs or when contacting Finrelay support about a specific decline.