ACH (Automated Clearing House) is the backbone of the US economy, yet it relies on a batch-processing architecture from the 1970s. For developers accustomed to synchronous REST APIs, ACH is jarringly asynchronous. A successful "200 OK" response from an ACH API only means "Request Received," not "Money Moved."
Successfully building on ACH requires a system that can handle long-running state transitions and distinct failure modes that occur days after the initial transaction. It involves generating or parsing NACHA files (fixed-width text files) and interacting with an ODFI (Originating Depository Financial Institution).
The T+2 Settlement Cycle and "Provisional Credit"
The lifecycle of an ACH Debit is a multi-day saga: Day 0 (Origination): You send the file to the Fed via your ODFI. Day 1 (Processing): The Fed sorts the file and routes it to the RDFI (Receiver's bank). Day 2 (Settlement): Funds settle between banks. Crucial Detail: If the user has Insufficient Funds (NSF), the RDFI has 48 hours from settlement to return the transaction. This means you might give a user "Provisional Credit" on Day 0, only to have the money clawed back on Day 4 via an R01 return code.
Handling Returns (The Unhappy Path)
Reconciling ACH is not just about matching successful payments; it is about matching Returns to original entries. The Return File: The Fed sends a daily file containing all rejected transactions. Matching Logic: The system must parse the return code (e.g., R01 - Insufficient Funds, R03 - No Account), identify the original trace_number, and trigger a reversal in the Internal Ledger. Automated Dunning: Upon receiving an R01, the system should automatically lock the user's account, reverse the balance, and trigger a "Payment Failed" email, without human intervention.