> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Failures

> Understand every Dodo Payments transaction failure code, whether it is a soft or hard decline, and the recommended action to recover the payment.

## Overview

When a payment attempt fails, Dodo Payments returns a standardized failure code that tells you why. The codes are the same across payment methods and payment processors, so one set of handling rules covers every failed payment.

The `payment.failed` webhook and the payment object expose these fields for a failed payment:

* `error_code`: a standardized failure code from the table below.
* `error_message`: an explanation written for **you**, the merchant. When `error_code` is one of the standardized codes below, this is a headline plus the recommended action, not the raw text from the payment processor.
* `retry_attempt`: `0` for the original charge, and `1` or higher for each scheduled subscription renewal retry. Payments that are not subscription renewals keep the value `0`.

Use these codes to give customers clear feedback, decide whether a retry can succeed, and recover more revenue.

### Merchant Copy vs. Customer Copy

Each standardized failure code maps to two messages, one for you and one for your customer:

| Audience | Where it appears | What it says |
| - | - | - |
| **You** | `error_message` on the payment, the payment details page in the dashboard, and the payment-failed email that merchants receive | The real reason plus a recommended action, for example *"The card hasn't been activated by the cardholder. Ask the customer to activate it with their bank, then retry."* |
| **Your customer** | The checkout failure screen, the [Customer Portal](/features/customer-portal), and [dunning](/features/recovery/subscription-dunning) emails | A short, plain-language explanation they can act on, for example *"Your card hasn't been activated yet. Please activate it with your bank and try again."* |

<Note>
  The Customer Portal returns the customer wording in `error_message`, while the merchant API returns the merchant wording for the same payment. The `error_code` is the same in both.
</Note>

<Card title="Handle Payment Failures" icon="screwdriver-wrench" href="/developer-resources/handle-payment-failures">
  A step-by-step developer guide for reading these codes from webhooks and the API, showing them to customers, and deciding when to retry.
</Card>

## Soft vs. Hard Declines

Each failure code is either a soft decline or a hard decline. The type tells you whether a later attempt with the same payment details can succeed, or whether the customer must act first.

| Decline type | What it means | What to do | Examples |
| - | - | - | - |
| **Soft decline** | Temporary. The same payment details can succeed on a later attempt. | Retry after a delay. | `INSUFFICIENT_FUNDS`, `GENERIC_DECLINE`, `CARD_VELOCITY_EXCEEDED`, `PROCESSING_ERROR`, `NETWORK_ERROR`, `NETWORK_TIMEOUT`, `TRY_AGAIN_LATER` |
| **Hard decline** | A retry with the same payment details and no action from the customer does not change the outcome. | Do **not** retry the same details. Ask the customer to correct their details, complete authentication, contact their bank, or use a different payment method. | `STOLEN_CARD`, `LOST_CARD`, `PICKUP_CARD`, `DO_NOT_HONOR`, `FRAUDULENT`, `INVALID_ACCOUNT`, `INCORRECT_CVC` |

For subscription renewals, Dodo Payments applies this classification automatically. [Subscription Payment Retries](/features/recovery/payment-retries) re-attempt soft declines. A hard decline ends the retry chain immediately; recover it with [Subscription Dunning](/features/recovery/subscription-dunning).

<Warning>
  **Never reveal the real reason for `STOLEN_CARD`, `LOST_CARD`, `PICKUP_CARD`, or `FRAUDULENT` to the customer.** Revealing these reasons can alert a fraudulent actor. Show the customer a generic decline message (for example, *"Your card was declined. Please contact your bank or use another card."*), and log the specific code only internally.

  Dodo Payments applies this rule on the surfaces it controls. For these four codes, checkout, the Customer Portal, and dunning emails show a generic decline message, while your merchant copy keeps the real reason. Apply the same rule anywhere you show `error_message` from the merchant API to a customer.
</Warning>

## Transaction Failure Reasons

The following table lists every failure code with its decline type, whether the customer can resolve it, a description, and the recommended action.

| Failure Code | Type | User Error | Description | Recommended Action |
| - | - | - | - | - |
| `AUTHENTICATION_FAILURE` | Hard | Yes | Authentication failed during the transaction | Ask the customer to retry and complete 3DS authentication, or use another card |
| `AUTHENTICATION_REQUIRED` | Hard | Yes | Additional authentication is needed to complete the transaction | Prompt the customer to complete 3DS authentication. For subscription renewals, ask the customer to return and authenticate |
| `AUTHENTICATION_TIMEOUT` | Soft | Yes | The authentication process timed out | Ask the customer to retry and complete authentication promptly |
| `CARD_DECLINED` | Soft | No | The issuing bank declined the card without a specific reason (generic decline) | Ask the customer to retry, contact their bank, or use another card |
| `CARD_NOT_ACTIVATED` | Soft | Yes | The cardholder has not activated the card | Ask the customer to activate the card with their bank, then retry |
| `CARD_VELOCITY_EXCEEDED` | Soft | Yes | Too many transactions were attempted in a short period | Ask the customer to wait and retry later, or contact their bank about limits |
| `CUSTOMER_CANCELLED` | Hard | Yes | The customer cancelled the transaction | Let the customer restart checkout when they are ready |
| `DO_NOT_HONOR` | Hard | No | The issuing bank explicitly refused the transaction (ISO 8583 code 05, do not honor). Card networks treat this as terminal | Ask the customer to contact their bank. Don't retry the same card |
| `EXPIRED_CARD` | Hard | Yes | The card has expired | Ask the customer to use a card with a valid expiry date |
| `FRAUDULENT` | Hard | Yes | The transaction was flagged as potentially fraudulent | Show the customer a generic decline message, without the reason. Ask them to use another card |
| `GENERIC_DECLINE` | Soft | No | The transaction was declined for an unspecified reason | Ask the customer to contact their bank or try another card |
| `INCORRECT_CVC` | Hard | Yes | The CVC entered was incorrect | Ask the customer to re-enter the correct CVC |
| `INCORRECT_NUMBER` | Hard | Yes | The card number was entered incorrectly | Ask the customer to re-enter the correct card number |
| `INSUFFICIENT_FUNDS` | Soft | Yes | The account doesn't have enough funds to complete the transaction | Ask the customer to use another payment method or retry once funds are available |
| `INVALID_ACCOUNT` | Hard | Yes | The account details provided are invalid | Ask the customer to contact their bank or use another card |
| `INVALID_AMOUNT` | Hard | Yes | The transaction amount is invalid | Verify the amount and any purchase limits with the customer |
| `INVALID_CARD_NUMBER` | Hard | Yes | The card number format is invalid | Ask the customer to re-enter a valid card number |
| `INVALID_CARD_OWNER` | Hard | Yes | The card owner information is invalid | Ask the customer to correct the cardholder name |
| `INVALID_CVC` | Hard | Yes | The CVC format is invalid | Ask the customer to re-enter a valid CVC |
| `INVALID_EXPIRY_YEAR` | Hard | Yes | The card expiry year is invalid | Ask the customer to enter a valid expiry date |
| `INVALID_PIN` | Hard | Yes | The PIN entered is incorrect | Ask the customer to re-enter the correct PIN |
| `INVALID_REQUEST` | Hard | Yes | The transaction request contains invalid data | Check the payment request fields and resubmit with valid data |
| `INVALID_UPI_ID` | Hard | Yes | The UPI ID provided is invalid | Ask the customer to enter a valid UPI ID |
| `LIMIT_EXCEEDED` | Soft | Yes | The transaction exceeds the card or account limit | Ask the customer to contact their bank about limits, or use another method |
| `LIVE_MODE_TEST_CARD` | Hard | Yes | A test card was used in live mode | Use a real card. A test card always fails in live mode |
| `LOST_CARD` | Hard | Yes | The card has been reported as lost | Show the customer a generic decline message, without the reason. Ask them to use another card |
| `MANDATE_INVALID` | Hard | Yes | The payment mandate is invalid | Ask the customer to set up the payment mandate again |
| `MANDATE_REQUIRED` | Hard | Yes | A mandate is required for this transaction | Set up a mandate and ask the customer to authorize it before charging |
| `MANDATE_REQUIRED_SYSTEM` | Hard | No | The system requires a mandate for this transaction type | Complete the mandate setup flow before charging |
| `NETWORK_ERROR` | Soft | No | A network error occurred during the transaction | Transient. Retry the payment after a short delay |
| `NETWORK_TIMEOUT` | Soft | No | The network request timed out | Transient. Retry the payment after a short delay |
| `ORDER_ALREADY_EXISTS` | Hard | No | An order already exists for this transaction (duplicate order creation) | Check the status of the existing order before retrying. Contact support if it persists |
| `ORDER_CREATION_FAILED` | Soft | No | The order for the transaction could not be created | Transient or system error. Retry the payment, and contact support if it persists |
| `PAYMENT_METHOD_PROVIDER_DECLINED` | Hard | Yes | The payment method provider declined the transaction | Ask the customer to contact their provider or use another payment method |
| `PAYMENT_METHOD_UNSUPPORTED` | Hard | Yes | The payment method is not supported for this transaction | Ask the customer to use a supported payment method |
| `PICKUP_CARD` | Hard | Yes | The card has been reported as lost or stolen and flagged for pickup | Show the customer a generic decline message, without the reason. Ask them to use another card |
| `PROCESSING_ERROR` | Soft | No | An error occurred while processing the transaction | Transient. Retry the payment. If it persists, ask the customer to contact their bank |
| `PROVIDER_UNSUPPORTED` | Hard | No | The payment provider does not support this transaction type | Ask the customer to use another payment method |
| `REENTER_TRANSACTION` | Soft | Yes | The transaction needs to be entered again | Ask the customer to retry the payment |
| `REVOCATION_OF_AUTHORIZATION` | Hard | Yes | The authorization for the transaction was revoked | Ask the customer to use another payment method |
| `STOLEN_CARD` | Hard | Yes | The card has been reported as stolen | Show the customer a generic decline message, without the reason. Ask them to use another card |
| `SUBSCRIPTION_NOT_ACTIVE` | Hard | No | The subscription is not active, so the recurring charge could not be processed | Reactivate the subscription (for example, by updating the payment method) before you attempt the charge again |
| `TRANSACTION_NOT_ALLOWED` | Soft | Yes | The transaction is not allowed for this card or account | Retry after a delay. If it keeps failing, ask the customer to contact their bank to allow this transaction type, or use another card |
| `TRANSACTION_NOT_APPROVED` | Soft | Yes | The transaction was not approved | Retry after a delay. If it keeps failing, ask the customer to contact their bank or try another card |
| `TRY_AGAIN_LATER` | Soft | No | The transaction should be retried later | Transient. Retry the payment later |
| `UNKNOWN_ERROR` | Soft | No | An unknown error occurred | Retry the payment. If it persists, contact support |

<Note>
  **User Error** shows whether the customer can resolve the decline. `Yes` means the customer can fix the issue, for example by entering correct card details. `No` means a system-level issue or a bank restriction caused the decline, and the customer can't resolve it directly.
</Note>

<Info>
  An issuing bank can also decline a card because its own risk engine flags the cardholder as high-risk, independent of the merchant or the transaction details. These declines usually appear as generic codes such as `DO_NOT_HONOR`, `GENERIC_DECLINE`, `CARD_DECLINED`, `TRANSACTION_NOT_APPROVED`, or `FRAUDULENT`. The bank doesn't share the specific reason, and neither Dodo Payments nor the merchant can override the decision. Ask the customer to contact their bank to resolve the flag, or to use a different card or payment method.
</Info>

## Handling Failures Programmatically

Read `error_code` from the `payment.failed` webhook or the payment object, map it to the recommended action in the table, and decide whether to retry. For subscription renewals, Dodo Payments retries soft declines for you. See [Subscription Payment Retries](/features/recovery/payment-retries).

For API and business-logic errors that are not card declines, such as `PAYMENT_NOT_SUCCEEDED` or `REFUND_WINDOW_EXPIRED`, see the [Error Codes](/api-reference/error-codes) reference.

## Related

<CardGroup cols={2}>
  <Card title="Handle Payment Failures" icon="screwdriver-wrench" href="/developer-resources/handle-payment-failures">
    End-to-end guide to detecting, surfacing, and retrying failed payments.
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/api-reference/error-codes">
    API and business-logic error codes for non-decline failures.
  </Card>

  <Card title="Subscription Payment Retries" icon="arrow-rotate-right" href="/features/recovery/payment-retries">
    Automatic retries that recover soft declines on subscription renewals.
  </Card>

  <Card title="Subscription Dunning" icon="repeat" href="/features/recovery/subscription-dunning">
    Email sequences that recover hard declines by prompting a payment method update.
  </Card>
</CardGroup>

## Support

For more help with transaction failures or integration issues, contact the support team at [support@dodopayments.com](mailto:support@dodopayments.com).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.