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

# Decline Codes

> Common decline reasons, what they mean, and how SmartRetry handles them.

When a transaction fails, the issuing bank returns a **decline code** - a specific reason code that explains exactly why the authorization was refused. SmartRetry reads these codes in real time and uses them to decide whether and how to attempt recovery.

## What are decline codes?

Decline codes are standardized response codes generated by the **issuing bank** at the end of the authorization flow. After the card network routes your transaction to the issuer, the issuer evaluates it against account status, fraud rules, balance, and velocity limits - then returns an approval or a specific decline reason.

Without decline codes, merchants would have no way to distinguish a stolen card from a temporary funds issue. SmartRetry uses these codes as the primary input to its recovery decision logic.

The `reasonCode` field on the [transaction status object](/docs/concepts/transaction-statuses) contains the specific decline reason. The `domain` field tells you which part of the payment chain produced it.

## Hard vs. soft declines

Not all declines are equal. The most important distinction in payment recovery is between **hard declines** and **soft declines**.

<Tabs>
  <Tab title="Soft declines">
    A soft decline indicates a **temporary issue**. The underlying payment method is structurally valid, but something situational prevented the authorization from succeeding right now.

    Common causes include:

    * Insufficient funds at the time of the attempt
    * Temporary fraud filters that may clear on a second attempt
    * Velocity or spending limits that reset over time
    * Network timeouts or transient processor errors

    Soft declines are the primary target for SmartRetry's recovery logic. By analyzing the specific reason code, timing, and issuer behavior, SmartRetry can retry the transaction with a realistic chance of success.
  </Tab>

  <Tab title="Hard declines">
    A hard decline is a **permanent rejection**. The issuing bank has determined that the payment method itself is invalid, compromised, or fundamentally unusable.

    Common causes include:

    * Stolen or lost card reported by the cardholder
    * Closed or frozen account
    * Invalid card number
    * Suspected fraud with account action taken by the issuer

    SmartRetry does **not** retry hard declines. Retrying a hard-declined card wastes processing fees, can generate unnecessary network charges, and degrades your standing with card networks over time. When SmartRetry identifies a hard decline, it flags the transaction as unrecoverable and surfaces the reason so you can take the appropriate action - such as prompting the customer for a new payment method.
  </Tab>
</Tabs>

## Common decline reason codes

The API returns exact `DOMAIN.REASON` values in `reasonCode`. The following source-backed examples are not a retry-policy matrix; determine any retry action from your SmartRetry configuration and the transaction context.

| Reason code                                        | Description                                                                   |
| -------------------------------------------------- | ----------------------------------------------------------------------------- |
| `PAYER_ACCOUNT.INSUFFICIENT_FUNDS`                 | The payer's account does not have enough funds to cover the transaction.      |
| `PAYER_ACCOUNT.DO_NOT_HONOR`                       | The issuer declined the transaction without providing a more specific reason. |
| `PAYER_ACCOUNT.INVALID_EXPIRY_DATE`                | The payment instrument expiry date is invalid.                                |
| `PAYER_ACCOUNT.SUSPECTED_FRAUD`                    | The payer account was flagged for suspected fraud.                            |
| `PAYER_ACCOUNT.STOLEN_INSTRUMENT.STOLEN_CARD`      | The payment instrument was reported stolen.                                   |
| `PAYER_ACCOUNT.LOST_INSTRUMENT.LOST_CARD`          | The payment instrument was reported lost.                                     |
| `PAYER_ACCOUNT.INVALID_SECURITY_CODE`              | The payment instrument security code is invalid.                              |
| `AUTH.3DS_CHALLENGE_FAILED`                        | The payer did not complete the 3DS authentication challenge.                  |
| `PAYER_ACCOUNT.DUPLICATE_TRANSACTION`              | The payer account identified the transaction as a duplicate.                  |
| `PAYER_ACCOUNT.EXCEEDS_WITHDRAWAL_FREQUENCY_LIMIT` | The payer account exceeded a frequency limit.                                 |
| `PAYER_ACCOUNT.EXCEEDS_AMOUNT_LIMIT`               | The payer account exceeded an amount limit.                                   |
| `PAYER_ACCOUNT.RESTRICTED_CARD`                    | The payment instrument has a restriction that prevents the transaction.       |

## Using the domain field

The `domain` field on the status object helps you understand the systemic source of a decline - not just the specific reason code.

For example:

* A `PAYER_ACCOUNT.INVALID_SECURITY_CODE` reason points to a security-code issue.
* A `PAYER_ACCOUNT.SUSPECTED_FRAUD` reason identifies a payer-account fraud outcome.
* An `AUTH.3DS_CHALLENGE_FAILED` reason identifies an unsuccessful 3DS challenge.

Using `domain` alongside `reasonCode` gives you a clearer picture of where recovery efforts should focus. See [Transaction Statuses](/docs/concepts/transaction-statuses) for the full list of domains.
