# ACH Return Codes: R01-R29 Reference Guide for SaaS

> ACH return codes explained: what R01, R02, R10 and other Nacha return reason codes mean, return timeframes, retry rules, and how SaaS merchants should respond.
- **Author**: Deepak Jangir
- **Published**: 2026-10-14
- **Category**: Payments, ACH
- **URL**: https://dodopayments.com/blogs/en/ach-return-codes

---

ACH return codes are standardized reason codes, defined by Nacha, that a customer's bank attaches when it sends an ACH debit back unpaid. Each code starts with "R" followed by two digits, such as R01 (insufficient funds) or R10 (customer says the debit was unauthorized), and it tells you why the payment failed and whether you are allowed to try again.

Here is why that matters for a SaaS or digital product founder. An ACH payment can look successful at checkout, then come back days later as a return. If your app already provisioned the account, shipped the license key, or granted API credits, you have given away the product and now hold a failed payment. Worse, some return codes count against network thresholds, and retrying the wrong one can break Nacha rules.

This guide is the deep reference. It covers the most common ACH return reason codes, the return timeframes for each type, which codes you can re-present and which you must never retry, the thresholds that originating banks monitor, and how to build fulfilment logic that does not get burned by late returns. If you are new to the rail itself, start with our [SaaS guide to ACH payments](https://dodopayments.com/blogs/what-is-ach-payment-saas-guide) and come back here when you need the code-by-code detail.

## What ACH Return Codes Are and How a Return Happens

An ACH debit moves through a fixed chain. Your payment provider (the Originator's side, working through an ODFI, the Originating Depository Financial Institution) sends a debit request into the ACH network. The customer's bank (the RDFI, Receiving Depository Financial Institution) receives it and either posts it or returns it with a reason code.

Unlike a card authorization, there is no real-time yes or no. The debit settles first, and the RDFI then has a window to send it back, which is why a payment that looked fine on day one can fail on day three. For a broader comparison of bank rails, see our breakdown of [EFT vs ACH vs wire transfer](https://dodopayments.com/blogs/eft-vs-ach-vs-wire-transfer).

```mermaid
flowchart LR
    A["Customer authorizes debit"] --> B["Merchant / provider submits entry (ODFI)"]
    B --> C["ACH network"]
    C --> D["Customer bank (RDFI)"]
    D -->|"Funds OK"| E["Entry posts, payment succeeds"]
    D -->|"Problem found"| F["Return with R-code"]
    F --> G["ODFI notifies provider"]
    G --> H["Merchant receives failure event"]
```

Return codes fall into two broad buckets, and the bucket decides almost everything about how you respond:

- **Administrative and funding returns** such as R01, R02, R03, R04, R09, R16 and R20. The bank found a technical or funding problem. These generally must be returned within two banking days of settlement.
- **Unauthorized returns** such as R05, R07, R10, R11 and R29. The account holder says the debit was not authorized, or not authorized in that form. For consumer accounts, the customer can generally dispute these for up to 60 calendar days after settlement.

Here is how the two buckets compare at a glance.

| Dimension | Administrative / funding returns | Unauthorized returns |
| --- | --- | --- |
| Example codes | R01, R02, R03, R04, R09, R16, R20 | R05, R07, R10, R11, R29 |
| Who triggers it | The customer's bank, usually automatically | The account holder, by contacting their bank |
| Typical return window | 2 banking days after settlement | Up to 60 calendar days for consumer accounts (R29 is 2 banking days) |
| Can you re-present? | Only R01 and R09, with limits | No, not without a new authorization |
| Closest card equivalent | A decline | A chargeback |
| Nacha threshold | 3% administrative (R02, R03, R04) | 0.5% unauthorized |

## ACH Return Reason Codes: The Full Reference Table

The table below lists the ACH return reason codes you are most likely to see as a merchant, using the standard Nacha definitions. The complete Nacha list also includes specialized codes for government payments and check conversion entries that rarely affect SaaS.

| Code | Meaning | Type | Typical window | What it means for a SaaS merchant |
| --- | --- | --- | --- | --- |
| R01 | Insufficient funds | Funding | 2 banking days | The account exists but could not cover the debit. Retry is allowed, within limits |
| R02 | Account closed | Administrative | 2 banking days | The customer closed the account. Ask for a new payment method |
| R03 | No account / unable to locate account | Administrative | 2 banking days | Account number does not match a real account. Usually a typo at checkout |
| R04 | Invalid account number structure | Administrative | 2 banking days | The number fails format checks. A data-entry or validation problem |
| R05 | Unauthorized debit to consumer account using corporate SEC code | Unauthorized | 60 calendar days | A consumer account was debited as if it were a business account |
| R06 | Returned per ODFI's request | Administrative | Per agreement | The originating bank itself asked for the entry back, often after an error |
| R07 | Authorization revoked by customer | Unauthorized | 60 calendar days | The customer withdrew permission for the debit. Do not retry |
| R08 | Payment stopped | Administrative | 2 banking days | The customer placed a stop payment on this entry. Contact them first |
| R09 | Uncollected funds | Funding | 2 banking days | Balance exists but funds are not yet available. Retry is allowed, within limits |
| R10 | Customer advises originator is not known and/or not authorized | Unauthorized | 60 calendar days | The ACH version of a fraud chargeback. Do not retry |
| R11 | Customer advises entry not in accordance with the terms of the authorization | Unauthorized | 60 calendar days | The customer authorized something, but not this amount, date, or form |
| R16 | Account frozen / entry returned per OFAC instruction | Administrative | 2 banking days | The account is frozen, sometimes for legal or sanctions reasons. Do not retry |
| R20 | Non-transaction account | Administrative | 2 banking days | The account type does not allow debits, such as some savings accounts |
| R29 | Corporate customer advises not authorized | Unauthorized | 2 banking days | The business-account version of R10. Do not retry |

Two practical notes on the table. First, "banking days" excludes weekends and federal holidays, so a two-banking-day window can stretch to four calendar days over a weekend. Second, the 60-day window for consumer unauthorized returns is measured from the settlement date, which means a customer can return a debit you considered closed weeks ago.

### The R01 return code: insufficient funds

The R01 return code is the most common ACH return for most merchants. It means the account is real and open, but the balance could not cover the debit when it was presented. Nothing about the authorization is in question.

Because R01 is a temporary condition, Nacha allows you to re-present the entry. The standard rule is up to two additional attempts within 180 days of the original settlement date, for a maximum of three total tries. Most teams time the retry to land after a likely payday, such as the 1st or 15th of the month, rather than retrying the next morning.

### The R02 return code: account closed

The R02 return code means the customer closed the bank account. Retrying is pointless because the account will never accept the debit again. Treat R02 like an expired card: notify the customer, explain the payment did not go through, and ask them to pay with a new account or a different method.

### The R10 return code: unauthorized debit

The R10 return code means the account holder told their bank they do not recognize the originator or did not authorize the debit. Functionally, it is the ACH equivalent of a fraud chargeback, and the customer usually signs a written statement with their bank to trigger it. Our explainer on [what a chargeback is](https://dodopayments.com/blogs/what-is-a-chargeback-explained) covers the card-side version of this same problem.

You must not re-present an R10. To debit that account again you need a fresh, valid authorization from the customer. In practice, many R10s on SaaS charges come from customers who simply did not recognize the company name on their bank statement, which is why descriptors matter so much (more on that below).

## ACH Return Timeframes and Nacha Return Rate Thresholds

ACH return timeframes are the single biggest operational difference from cards. A card decline arrives in seconds. An ACH return arrives days later, and an unauthorized return can arrive almost two months later.

Here is how the main ACH return timeframes break down under standard Nacha rules:

- **Two banking days after settlement** for most administrative and funding returns, including R01, R02, R03, R04, R08, R09, R16 and R20.
- **Two banking days after settlement** for R29, because corporate accounts get a shorter unauthorized window than consumers.
- **Up to 60 calendar days after settlement** for consumer unauthorized returns, including R05, R07, R10 and R11.

On top of timing, Nacha sets return rate thresholds that originating banks watch for every merchant they process for. These numbers are well established in the Nacha Operating Rules:

| Return category | Threshold | Codes included |
| --- | --- | --- |
| Unauthorized return rate | 0.5% | R05, R07, R10, R11, R29, R51 |
| Administrative return rate | 3.0% | R02, R03, R04 |
| Overall return rate | 15.0% | All return codes, excluding certain re-presentments |

Crossing the 0.5% unauthorized threshold is the serious one. It can trigger an inquiry from Nacha through the originating bank, a requirement to reduce returns within a set period, and in severe cases the loss of the ability to originate ACH debits. The administrative and overall thresholds act as warning levels that prompt a review of how you collect and validate account details.

So returns are not just a revenue problem: unrecognized charges can put the rail itself at risk, much like a high dispute rate on cards. Our guide on [chargeback vs refund](https://dodopayments.com/blogs/chargeback-vs-refund) explains how dispute ratios work there.

## How to Handle Each ACH Return Code: Retry Rules and Next Steps

The right response depends on the code, not on the amount. A simple decision rule covers most cases.

| Return code | Retry? | Recommended action |
| --- | --- | --- |
| R01, R09 | Yes, up to two re-presentments within 180 days | Retry after a likely payday, email the customer before each attempt |
| R02, R03, R04, R20 | No | Ask for a new account or payment method; fix the validation step that let bad data through |
| R08 | Not without customer contact | Find out why they stopped payment; only re-debit with new authorization |
| R16 | No | Do not retry; route to manual review |
| R05, R07, R10, R11, R29 | Never without a new authorization | Revoke access granted by that payment, contact the customer, review descriptor and consent flow |
| R06 | Depends | Check with your provider; usually tied to an error on the origination side |

A few rules apply across every code. Never re-present an unauthorized return to "see if it goes through this time", because that is exactly the behavior Nacha rules prohibit. Never change the amount or split the debit to get around an R01; a re-presentment should match the original entry. And always tell the customer what happened before you retry, since a surprise second debit is a common source of R10s.

For subscription businesses using cards, structured retry schedules are a well-known lever for recovering failed payments, which we cover in our guide to [payment retry logic](https://dodopayments.com/blogs/payment-retry-logic). ACH retries follow the same spirit with much stricter limits, so the playbook in [reducing involuntary churn from failed payments](https://dodopayments.com/blogs/involuntary-churn-failed-payments) should be adapted rather than copied.

### How to reduce ACH returns before they happen

Most returns are preventable. The causes cluster around bad account data, unrecognized charges, and surprise timing. These steps address each one:

- **Validate the account at collection.** Instant account verification through bank login, or micro-deposit verification, catches R03 and R04 errors before the first debit. Our comparison of [Plaid and Stripe](https://dodopayments.com/blogs/plaid-vs-stripe-different-tools) explains how bank-linking tools fit into this.
- **Use a clear, recognizable descriptor.** The name that appears on the customer's bank statement should match your product name. A confusing descriptor is a direct path to R10. See our guide to [statement descriptors](https://dodopayments.com/blogs/statement-descriptor) for naming practices.
- **Notify before you debit.** A short email a few days before a large debit, stating the amount and date, prevents both R01 (customer moves money in time) and R10 (customer expects the charge).
- **Capture explicit authorization.** Store the timestamp, amount, and consent language the customer accepted. If a dispute arises, that record is your evidence.
- **Make cancellation easy.** A customer who cannot find your cancel button may ask their bank to stop the debit instead, which produces an R07 or R10 rather than a clean cancellation.

## How Dodo Payments Handles ACH Returns

Dodo Payments supports [ACH Direct Debit](https://docs.dodopayments.com/features/payment-methods/ach) for customers paying in USD with a US billing address. It is worth being clear about the trade-offs up front so you can decide where it fits.

- **One-time payments only.** On Dodo, ACH and other bank debits are not available for subscriptions. Recurring plans run on cards, Google Pay, Cash App Pay (USD), and UPI Intent (INR), as described in the [subscription docs](https://docs.dodopayments.com/features/subscription). That removes most R07 "authorization revoked" scenarios, since there is no standing recurring mandate, but it also means ACH is a fit for one-off purchases, annual prepayments, or high-ticket orders rather than monthly billing.
- **Minimum and settlement.** The minimum ACH payment is $0.50, and payments settle in up to 4 business days.
- **Returns surface as `payment.failed`.** If the customer's bank returns the debit after checkout, Dodo emits a `payment.failed` webhook. Your application should grant access only when it receives `payment.succeeded`, never at checkout submission.
- **Flat pricing.** ACH Direct Debit on Dodo is a flat 1.5%, capped at $15 per transaction, and it replaces the card fee with no international or subscription surcharge.

Because Dodo acts as the Merchant of Record, it is the legal seller on each transaction and handles sales tax, VAT, and GST calculation and remittance, along with compliance and chargebacks. Your job is the fulfilment logic: wait for the success event, and handle the failure event cleanly.

Here is a minimal Express handler that verifies the webhook with the Dodo Node SDK and reacts to a returned ACH payment. It follows the signature verification pattern from the [webhooks documentation](https://docs.dodopayments.com/developer-resources/webhooks).

```ts
import DodoPayments from 'dodopayments';
import express from 'express';

const app = express();

const client = new DodoPayments({
  bearerToken: process.env['DODO_PAYMENTS_API_KEY'],
  webhookKey: process.env['DODO_PAYMENTS_WEBHOOK_KEY'],
});

// Use the raw body so the signature can be verified against the exact bytes sent
app.post('/webhooks/dodo', express.raw({ type: 'application/json' }), async (req, res) => {
  let event;
  try {
    event = client.webhooks.unwrap(req.body.toString('utf8'), {
      headers: {
        'webhook-id': req.headers['webhook-id'] as string,
        'webhook-signature': req.headers['webhook-signature'] as string,
        'webhook-timestamp': req.headers['webhook-timestamp'] as string,
      },
    });
  } catch {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Acknowledge quickly, then do the work
  res.json({ received: true });

  const payment = event.data;

  if (event.type === 'payment.succeeded') {
    // Only now grant access, ship the license key, or add credits
    await fulfillOrder(payment.payment_id, payment.customer.customer_id);
  }

  if (event.type === 'payment.failed') {
    // A bank return after checkout lands here: never fulfil, and undo anything provisional
    await revokeProvisionalAccess(payment.payment_id);
    await notifyCustomer(payment.customer.customer_id, {
      reason: payment.error_message,
      code: payment.error_code,
    });
  }
});

app.listen(3000);
```

The key design choice is that `fulfillOrder` runs only on `payment.succeeded`. Since ACH can take up to 4 business days to settle, show the customer a "payment processing" state in the meantime rather than granting access early. The [payment failure handling guide](https://docs.dodopayments.com/developer-resources/handle-payment-failures) walks through the full `payment.failed` payload, and our article on [webhooks for payment notifications](https://dodopayments.com/blogs/webhooks-payment-notifications) covers idempotency and retries on your side.

For reconciliation, match every `payment.failed` event against the order it belongs to so your revenue reports do not count returned payments as income. Our guide to [payment reconciliation for SaaS](https://dodopayments.com/blogs/payment-reconciliation-saas) covers how to set that up.

## FAQ

### How long does a customer have to return an ACH debit?

For most administrative and funding returns, such as insufficient funds or a closed account, the customer's bank generally has two banking days after settlement. For unauthorized returns on consumer accounts, such as R10 or R07, the customer can generally dispute the debit for up to 60 calendar days after settlement.

### Can I retry an ACH payment that came back with R01?

Yes. Nacha rules allow an R01 or R09 entry to be re-presented up to two additional times within 180 days of the original settlement date. Time retries around likely paydays and notify the customer before each attempt to improve the odds of success.

### What is the difference between R10 and R29?

Both mean the account holder says the debit was not authorized. R10 applies to consumer accounts and can be returned for up to 60 calendar days, while R29 applies to corporate accounts and must generally be returned within two banking days.

### Is an ACH return the same as a chargeback?

Not exactly, but unauthorized returns like R10 behave much like a card chargeback because the customer disputes the debit through their bank. Administrative returns like R01 or R02 are closer to a card decline, since they reflect a funding or account problem rather than a dispute.

### Does an ACH return cost the merchant money?

Usually, yes. Beyond losing the payment itself, many providers charge a fee for failed or returned ACH payments, and returns can lead to extra work for your support and finance teams. Check your provider's pricing page for the exact amount it charges, or see our [Stripe ACH fees breakdown](https://dodopayments.com/blogs/stripe-ach-fees) for one worked example.

## Final Thoughts

ACH return codes are a small vocabulary with large consequences. Know the difference between administrative returns, which you can often fix or retry, and unauthorized returns, which you must never retry and which count toward the 0.5% threshold. Build your fulfilment around the success event, validate accounts at collection, and use a descriptor customers recognize.

If you are still deciding whether bank debits fit your product at all, compare ACH with other pull-payment rails in our guides to [direct debit](https://dodopayments.com/blogs/what-is-direct-debit) and [SEPA Direct Debit](https://dodopayments.com/blogs/sepa-direct-debit), or read the practical setup walkthrough on [how to accept ACH payments from customers](https://dodopayments.com/blogs/accept-ach-payments-from-customers).

[Dodo Payments](https://dodopayments.com) offers one-time ACH Direct Debit alongside cards, wallets, and local payment methods, with tax handled as Merchant of Record. See the flat ACH rate and the rest of the fee structure on the [pricing page](https://dodopayments.com/pricing).
---
- [More Payments articles](https://dodopayments.com/blogs/category/payments)
- [All articles](https://dodopayments.com/blogs)