Skip to content
Last updated

Recipe: ACH returns

What is an ACH return?

An ACH return occurs when the receiving bank rejects or reverses an ACH transaction. Unlike card chargebacks, ACH returns follow NACHA rules and have specific return reason codes.

Common return codes

CodeNameDescriptionTiming
R01Insufficient fundsNot enough money in the account2 business days
R02Account closedThe account has been closed2 business days
R03No account / unable to locateAccount number is invalid2 business days
R04Invalid account numberAccount number structure is wrong2 business days
R08Payment stoppedCustomer requested a stop payment2 business days
R10Customer advises not authorizedCustomer claims they did not authorize the debit60 calendar days
R29Corporate customer advises not authorizedCorporate account disputes authorization2 business days

Return timeline

Sun Sun Sun Sun Sun Sun Sun Sun SunTransaction submitted Unauthorized return (R10) Transaction submitted Standard return window Standard return window Debit (payment)Credit (payout)ACH return windows
Sun Sun Sun Sun Sun Sun Sun Sun SunTransaction submitted Unauthorized return (R10) Transaction submitted Standard return window Standard return window Debit (payment)Credit (payout)ACH return windows

Detecting returns

When an ACH transaction is returned, the transaction_state changes to failed. Check the transaction periodically or use batch status polling.

Poll the transaction

curl https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC \
  -H "APIKEY: YOUR-API-KEY"

A returned transaction looks like:

{
  "id": "TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC",
  "type": "sale",
  "amount": 250000,
  "transaction_state": "failed",
  "response_status": "declined",
  "response_message": "ACH return: R01 - Insufficient funds",
  "correlation_id": "e5f6a7b8-c9d0-1234-ef01-23456789abcd"
}

Handling returns in your application

completed / settled

failed

R01 Insufficient funds

R02/R03/R04 Bad account

R08 Stop payment

R10 Unauthorized

ACH transaction submitted

Poll transaction state

transaction_state?

Payment successful

Return code?

Retry in a few days or contact customer

Request updated bank details

Contact customer

Do not retry — investigate

completed / settled

failed

R01 Insufficient funds

R02/R03/R04 Bad account

R08 Stop payment

R10 Unauthorized

ACH transaction submitted

Poll transaction state

transaction_state?

Payment successful

Return code?

Retry in a few days or contact customer

Request updated bank details

Contact customer

Do not retry — investigate

import time, requests, os

API_KEY = os.environ["PARADISE_API_KEY"]
BASE = "https://api.dev.paradisegateway.net"

def monitor_ach_transaction(txn_id, max_checks=10, interval=3600):
    """Poll an ACH transaction until it settles or fails."""
    for _ in range(max_checks):
        resp = requests.get(
            f"{BASE}/v1/transactions/{txn_id}",
            headers={"APIKEY": API_KEY},
        )
        txn = resp.json()
        state = txn["transaction_state"]

        if state in ("completed", "settled"):
            return {"status": "success", "transaction": txn}

        if state == "failed":
            return {
                "status": "returned",
                "message": txn.get("response_message", "ACH return"),
                "transaction": txn,
            }

        time.sleep(interval)

    return {"status": "timeout", "message": "Transaction still pending"}

What to do after a return

Return codeAction
R01 (Insufficient funds)Wait a few days and retry, or contact the customer for an alternative payment method
R02/R03/R04 (Bad account)Request updated bank details; delete the invalid token
R08 (Stop payment)Contact the customer to resolve the dispute
R10 (Unauthorized)Do not retry — investigate the authorization. This may indicate fraud

Preventing returns

  • Verify bank accounts — use micro-deposit verification before processing large debits
  • Get authorization — for WEB entries, ensure you have the customer's online consent
  • Validate routing numbers — check the routing number format before tokenizing
  • Communicate clearly — tell customers when debits will occur and for how much

Next steps