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

# Reason Codes

> Reason codes returned with check and return webhook events, and submitted on Check Cancel and Check Stop requests.

A reason code explains **why** an outcome occurred. It is distinct from a status code, which tells you **what** happened. The two travel together in the same webhook payload:

```json theme={null}
{
  "data": {
    "event": {
      "status": "1114",
      "client_message": "Payment Returned by Issuer",
      "reason_code": "02",
      "reason_description": "R03-No Account"
    }
  }
}
```

Here `1114` is the status — the payment was returned. `02` is the reason — the receiving bank reported no account. Use the [Status Codes](/docs/hub/errors) reference for the first value and this page for the second.

<Info>
  **Ingo reason codes are normalized.** Where a return originates with the ACH network, a card network, or an issuer, Ingo maps that provider's response into the single Ingo reason code set below before delivering it to you. Integrate against the Ingo code — the accompanying `reason_description` names the underlying network reason for operational triage, but the code is the stable contract.
</Info>

***

## Reading the value

<AccordionGroup>
  <Accordion title="Codes are two-character, zero-padded strings">
    In webhook payloads, `reason_code` is always a **two-character string**, zero-padded below 10. A no-account return arrives as `"02"` — never as `2` or `"2"`.

    ```javascript theme={null}
    // Correct
    if (event.reason_code === '02') { /* ... */ }

    // Wrong — will never match
    if (Number(event.reason_code) === 2) { /* fragile */ }
    if (event.reason_code === '2')       { /* never true */ }
    ```

    Compare against the padded literal, and store the field as a string. Parsing to an integer discards the padding that makes the value canonical and will break any round-trip back onto the wire.

    <Note>
      On the **request** side, `POST /gateway/checkcancel` and `POST /gateway/checkstop` accept `reason_code` as an **integer** (`73`, not `"73"`). Because every send-side code is already two digits, no padding question arises — but the type differs from the webhook representation, so do not share a single serializer across both directions.
    </Note>
  </Accordion>

  <Accordion title="reason_description is display text, not a matching key">
    Most events that carry `reason_code` also carry `reason_description` — up to 250 characters, emitted verbatim from the platform's reason code table.

    Treat it as display and log text only. It is **not** normalized prose: some entries carry legacy spellings and internal formatting (for example `Chargeback-RC30_ServicesNotProvided`, or `R20-non transaction account`). Descriptions on this page have been cleaned for readability, so they will not always match the emitted string character-for-character.

    Branch your logic on `reason_code`. Never string-match `reason_description`.
  </Accordion>

  <Accordion title="Where reason codes appear">
    | Surface | Event or endpoint                                             | Codes in scope                         |
    | ------- | ------------------------------------------------------------- | -------------------------------------- |
    | Webhook | `gateway.transaction.recipient.payment.status.returned`       | ACH, card, and biller return reasons   |
    | Webhook | `gateway.transaction.recipient.status.payment.check.returned` | Positive pay check returns (`79`–`87`) |
    | Webhook | `gateway.transaction.recipient.payment.status.check.canceled` | Check cancel reasons (`73`–`76`)       |
    | Webhook | `gateway.transaction.recipient.payment.status.check.stopped`  | Check stop reasons (`77`–`78`)         |
    | Request | `POST /gateway/checkcancel`                                   | Check cancel reasons (`73`–`76`)       |
    | Request | `POST /gateway/checkstop`                                     | Check stop reasons (`77`–`78`)         |

    The check and return events above are delivered on the IngoPay, Embedded Account Capture, and Notify webhook channels. See [Webhooks](/docs/hub/webhooks) for delivery, retry, and payload envelope details.

    Codes `73`–`78` are the only reason codes you **send**. Every other code on this page is one you **receive**.
  </Accordion>

  <Accordion title="Unassigned and reserved values">
    `10` is not assigned. Codes `11`–`15` are reserved for a legacy partner integration and are not emitted on any client-facing contract.

    Treat any unrecognized `reason_code` as an unclassified failure rather than rejecting the event — the set can grow, and new codes are added without a contract version change.
  </Accordion>
</AccordionGroup>

***

## Reason code reference

<AccordionGroup>
  <Accordion title="ACH Return Reasons">
    Returned when an ACH credit or debit cannot be posted by the receiving depository financial institution. The NACHA column shows the network return code that maps to each Ingo reason code.

    | Code | NACHA | Description                                                                  |
    | ---- | ----- | ---------------------------------------------------------------------------- |
    | `01` | R04   | Invalid account number                                                       |
    | `02` | R03   | No account                                                                   |
    | `03` | R06   | Return requested by sender                                                   |
    | `05` | R02   | Customer account closed                                                      |
    | `38` | R01   | Insufficient funds                                                           |
    | `39` | R05   | Unauthorized debit to consumer account using corporate SEC code              |
    | `40` | R07   | Authorization revoked by customer                                            |
    | `41` | R08   | Payment stopped                                                              |
    | `42` | R09   | Uncollected funds                                                            |
    | `43` | R10   | Customer advises not authorized, improper, or ineligible                     |
    | `44` | R11   | Customer advises entry not in accordance with the terms of the authorization |
    | `45` | R12   | Account sold to another DFI                                                  |
    | `46` | R13   | Invalid ACH routing number                                                   |
    | `47` | R14   | Representative payee deceased or unable to continue in that capacity         |
    | `48` | R15   | Beneficiary or account holder (other than representative payee) deceased     |
    | `49` | R16   | Account frozen / entry returned per OFAC                                     |
    | `50` | R17   | File record edit criteria                                                    |
    | `51` | R18   | Improper effective entry date                                                |
    | `52` | R19   | Amount field error                                                           |
    | `53` | R20   | Non-transaction account                                                      |
    | `54` | R21   | Invalid company identification                                               |
    | `55` | R22   | Invalid individual ID number                                                 |
    | `56` | R23   | Credit entry refused by receiver                                             |
    | `57` | R24   | Duplicate entry                                                              |
    | `58` | R25   | Addenda error                                                                |
    | `59` | R26   | Mandatory field error                                                        |
    | `60` | R27   | Trace number error                                                           |
    | `61` | R28   | Routing number check digit error                                             |
    | `62` | R29   | Corporate customer advises not authorized                                    |
    | `63` | R30   | RDFI not participant in check truncation program                             |
    | `64` | R31   | Permissible return entry (CCD and CTX only)                                  |
    | `65` | R32   | RDFI non-settlement                                                          |
    | `66` | R33   | Return of XCK entry                                                          |
    | `67` | R34   | Limited participation DFI                                                    |
    | `68` | R35   | Return of improper debit entry                                               |
    | `69` | R36   | Return of improper credit entry                                              |
    | `70` | R37   | Source document presented for payment                                        |
    | `71` | R38   | Stop payment on source document                                              |
    | `72` | R39   | Improper source document / source document presented for payment             |

    <Warning>
      **`44` carries an obsolete `reason_description`.** An R11 return is delivered as `reason_code` `44` with `reason_description` set to `Check truncation entry return` — R11's pre-2015 NACHA meaning. R11's current meaning is the one shown in the table above. Match on the code `44`; do not rely on the description to tell you what the return was.
    </Warning>

    <Note>
      **Reinitiation eligibility.** Not every ACH return reason permits a reinitiation attempt. Status codes `1315` and `1317` on the [Status Codes](/docs/hub/errors) page are returned when a reinitiation is rejected because of the return reason on the original — or on a prior reinitiation — transaction.
    </Note>
  </Accordion>

  <Accordion title="Card Decline & Account Reasons">
    Returned when a card disbursement is declined or reversed for a reason other than a formal chargeback.

    | Code | Description             |
    | ---- | ----------------------- |
    | `00` | Declined                |
    | `06` | Invalid expiration date |
    | `07` | Declined                |
    | `08` | Reported lost or stolen |
    | `09` | Chargeback              |

    <Warning>
      Do not retry `08` (reported lost or stolen) automatically. Prompt the recipient to supply a different destination account.
    </Warning>

    <Note>
      `00` and `07` are both `Declined` and are not distinguishable from the payload alone. Treat them identically.
    </Note>
  </Accordion>

  <Accordion title="Card Chargeback Reasons">
    Returned when a card disbursement is reversed through the network chargeback process. The RC column shows the network chargeback reason code that maps to each Ingo reason code.

    | Code | RC   | Description                                                                        |
    | ---- | ---- | ---------------------------------------------------------------------------------- |
    | `16` | RC30 | Services not provided                                                              |
    | `17` | RC41 | Canceled recurring transaction                                                     |
    | `18` | RC53 | Not as described                                                                   |
    | `19` | RC57 | Fraudulent multiple transactions                                                   |
    | `20` | RC62 | Counterfeit transaction                                                            |
    | `21` | RC70 | Card recovery bulletin or exception file                                           |
    | `22` | RC71 | Declined authorization                                                             |
    | `23` | RC72 | No authorization                                                                   |
    | `24` | RC73 | Expired card                                                                       |
    | `25` | RC74 | Late presentment                                                                   |
    | `26` | RC75 | Transaction not recognized                                                         |
    | `27` | RC76 | Incorrect currency, transaction code, or domestic transaction processing violation |
    | `28` | RC77 | Non-matching account number                                                        |
    | `29` | RC78 | Service code violation                                                             |
    | `30` | RC80 | Incorrect transaction amount or account number                                     |
    | `31` | RC81 | Fraudulent transaction — card present                                              |
    | `32` | RC82 | Duplicate processing                                                               |
    | `33` | RC83 | Fraudulent transaction — card not present                                          |
    | `34` | RC85 | Credit not processed                                                               |
    | `35` | RC86 | Paid by other means                                                                |
    | `36` | RC90 | Non-receipt of cash or load transaction value                                      |
    | `37` | RC93 | Merchant fraud performance                                                         |

    Chargebacks are terminal for the original transaction. Reconcile the reversal against your ledger; do not resubmit the same disbursement.
  </Accordion>

  <Accordion title="Biller Reasons">
    | Code | Description               |
    | ---- | ------------------------- |
    | `04` | Payment refused by biller |
  </Accordion>

  <Accordion title="Check Cancel (73–76) — sent on request">
    Submitted in the `reason_code` field of `POST /gateway/checkcancel` as an integer. The code must match the check's current transaction status, or the request is rejected with status `722`.

    | Code | Description       | Eligible Status |
    | ---- | ----------------- | --------------- |
    | `73` | Check not printed | Routed only     |
    | `74` | Undelivered check | Issued only     |
    | `75` | Client request    | Issued only     |
    | `76` | Internal request  | Issued only     |

    These codes are echoed back as strings on the `payment.status.check.canceled` webhook event.
  </Accordion>

  <Accordion title="Check Stop (77–78) — sent on request">
    Submitted in the `reason_code` field of `POST /gateway/checkstop` as an integer. The check must be in an issued status.

    | Code | Description      |
    | ---- | ---------------- |
    | `77` | Client request   |
    | `78` | Internal request |

    A successful stop response confirms only that the request was submitted. Confirmation that the check was actually stopped arrives on the `payment.status.check.stopped` webhook event, which echoes the reason code as a string.
  </Accordion>

  <Accordion title="Positive Pay Check Returns (79–87)">
    Returned on the `status.payment.check.returned` webhook event when a presented check fails a positive pay exception check.

    | Code | Description             |
    | ---- | ----------------------- |
    | `79` | Duplicate presentment   |
    | `80` | Amount not equal        |
    | `81` | Maximum amount exceeded |
    | `82` | Stale date              |
    | `83` | Payment canceled        |
    | `84` | Payee name conflict     |
    | `85` | Payee format conflict   |
    | `86` | Extra payee listed      |
    | `87` | Paid, no issue          |
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Status Codes" icon="hashtag" href="/docs/hub/errors">
    Response and event status codes across all Ingo Payments products.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/docs/hub/webhooks">
    Delivery, retry behavior, and payload envelope structure.
  </Card>

  <Card title="Retry Logic" icon="rotate" href="/docs/hub/retry-logic">
    Which outcomes warrant a retry, and how to retry safely.
  </Card>

  <Card title="Reporting" icon="table" href="/docs/hub/reporting">
    Reason codes as they appear in transaction and status files.
  </Card>
</CardGroup>
