At Gusto, we rely heavily on the ACH network to pay employees and to remit various payroll taxes to federal and state agencies on behalf of our clients.

In part 1 of this post, I outlined the basics of how we originate ACH debits and credits. About 95% of the time, things go exactly as planned. This post will explain the other 5% cases (called ACH returns) and how they are handled.

Here's a few of the common reasons an ACH file we originate can get returned:

1. Non-sufficient funds (or NSF) -- The bank account we're trying to debit does not have enough monies in it.
2. Invalid account number -- The routing/account number we're trying to credit or debit does not exist (a routing number identifies the Bank to the Federal Reserve, and an account number identifies the customer's account to the Bank)
3. Payment stopped -- The owner of the bank account we're trying to debit/credit told their bank that they did not authorize this transaction and wants it reversed.

In all, there are 69 different reasons an ACH file can get returned. I've posted the full list of ACH return codes.

How Returns are Handled

For the rest of this post, I'll talk specifically about returns on ACH debits (that is, us debiting money from a customer's account). If you want to know how returns on ACH credits work, you need only to switch the word "debit" with "credit" in this post.

If you recall from part 1 of this post, in order to debit a customer's account by $100.00, we need to SFTP an ACH file to our ODFI's servers. Our ODFI will send this file to the Federal Reserve that evening and and will increment our balance by$100.

It's important to note that our ODFI has incremented our balance without even knowing if Alice has the funds in our account, or if the account even exists. This is why finding a bank willing to be your ODFI is no easy task -- the bank takes on a small amount of risk by letting you originate ACH transfers through them.

When Alice's bank receives the ACH file from the Federal Reserve the following day, they generally have 24 hours after that to tell the Federal Reserve whether or not the payment should be returned. Depending on the return reason, the RDFI may or may not take the full 24 hours to response. For example, if the bank is returning the ACH file because of an invalid account number, they may return the ACH file immediately. If the bank returns the ACH file because of a NSF, the bank may wait for the entire 24 hours to see if their customer deposits money into their account before then.

The RDFI notifies the Federal Reserve that they are rejecting an ACH file by uploading an "ACH Return" file to the Federal Reserve. The contents of the return file say (1) which part of the ACH file they are rejecting (since an ACH file can contain multiple credits/debits in it) and (2) the reason for rejection (one of the Rxx) codes in the list of ACH return codes).

That evening, our ODFI will check in with the Federal Reserve to see if there are any ACH return files waiting for them. If there are, our ODFI will download the files, and then forward them to us by placing the file in the same SFTP server we originated the ACH file from. At the same time our ODFI will decrement our account by $100 to take back the money they originally credited us for. For record keeping, we'll see a debit of$100 on our bank statement with the description "ACH Return".

It's our job to to check the SFTP server every day, download and parse all the ACH response files, and update our systems when an ACH file gets returned. For example, at Gusto, if we originated an ACH debit because a company ran payroll, we'll cancel that payroll if the ACH file gets returned.

How Change Requests are Handled

If ACH returns are the developer's equivalent of an "error", ACH change requests are "warnings".

Sometimes, we will send an ACH file that isn't quite right, but is close enough for the RDFI to understand and process. In this case, the ACH transaction will go through, but the RDFI will upload an "ACH Change Request" file to the Federal Reserve, which then gets placed into our SFTP server through our ODFI. The change request file contains the correct information that we should have used in the ACH file. It's our job to check the SFTP server, parse the change request file, and update our system so that the next time we submit an ACH file to the RDFI, it contains the correct information.

For example, at Gusto, we'll automatically correct the customer's information in our system and shoot an email to our customer notifying them of the changes that their bank requested.

Here's a few of the common reasons an ACH file we originate can result in a change request:

1. Incorrect name of account holder -- We might have used "Allie" instead of "Alice" as the name of the account we tried to debit.
2. Savings/Checking selection switched -- We said we wanted to debit a checking account, when in fact the account is a savings account.
3. Incorrect account number -- We used the wrong bank account number, but we were close enough that the bank knew which account we actually meant to use (perhaps through a checksum).

It's important to note that ACH is not a real-time system. Rather, things are processed in batches at 6:30pm EST, 12:30am EST, and 3:00am EST. As a result, funds can take days to settle. For a payroll company moving more than a billion dollars annually through the ACH network, it's critical that we account for these edge cases correctly and in an automated way. If there's interest in the comments, I'll write a part 3 of this post, detailing these timelines and how we account for them properly.

Comments on Hacker News

## Appendix

Provided below are ACH return codes and change codes.

### ACH Return Codes

 R00 Manually Cancelled R01 Insufficient Funds R02 Account Closed R03 No Account/Unable to Locate Account R04 Invalid Account Number Structure R05 Unauthorized Debit to Consumer Account Using Corporate SEC Code R06 Return per ODFI's Request R07 Authorization Revoked by Customer R08 Payment Stopped R09 Uncollected Funds R10 Customer Advises Not Authorized, Improper, or Ineligible R11 Check Truncation Entry Return R12 Account Sold to Another DFI R13 Invalid ACH Routing Number R14 Representative Payee Deceased or Unable to Continue in That Capacity R15 Beneficiary or Account Holder Deceased R16 Account Frozen R17 File Record Edit Criteria R18 Improper Effective Entry Date R19 Amount Field Error R20 Non-Transaction Account R21 Invalid Company Identification R22 Invalid Individual ID Number R23 Credit Entry Refused by Receiver R24 Duplicate Entry R25 Addenda Error R26 Mandatory Field Error R27 Trace Number Error R28 Routing Number Check Digit Error R29 Corporate Customer Advises Not Authorized R30 RDFI Not Participant in Check Truncation Program R31 Permissible Return Entry R32 RDFI Non-Settlement R33 Return of XCK Entry R34 Limited Participation DFI R35 Return of Improper Debit Entry R36 Return of Improper Credit Entry R37 Source Document Presented for Payment R38 Stop Payment on Source Document R39 Improper Source Document/Source Document Presented for Payment R40 Return of ENR Entry by Federal Government Agency R41 Invalid Transaction Code R42 Routing Number/Check Digit Error R43 Invalid DFI Account Number R44 Invalid Individual ID Number R45 Invalid Individual Name/Company Name R46 Invalid Representative Payee Indicator R47 Duplicate Enrollment R50 State Law Affecting RCK Acceptance R51 Item related to RCK Entry is Ineligible or RCK Entry is Improper R52 Stop Payment on Item Related to RCK Entry R53 Item and RCK Entry Presented for Payment R61 Misrouted Return R67 Duplicate Return R68 Untimely Return R69 Field Error(s) R70 Permissible Return Entry Not Accepted/Return Not Requested by ODFI R71 Misrouted Dishonored Return R72 Untimely Dishonored Return R73 Timely Original Return R74 Corrected Return R75 Return Not a Duplicate R76 No Errors Found R80 IAT Entry Coding Error R81 Non-Participant in IAT Program R82 Invalid Foreign Receiving DFI Identification R83 Foreign Receiving DFI Unable to Settle R84 Entry Not Processed by Gateway R85 Incorrectly Coded Outbound International Payment

### ACH Change Codes

 C01 Incorrect DFI Account Number C02 Incorrect Routing Number C03 Incorrect Routing Number and Incorrect DFI Account Number C04 Incorrect Individual Name/Receiving Company Name C05 Savings/Checking Selection is Wrong C06 Incorrect DFI Account Number and Incorrect Transaction Code C07 Incorrect Routing Number, Incorrect DFI Account Number, and Incorrect Transaction Code C08 Incorrect Receiving DFI Identification C09 Incorrect Individual Identification Number C13 Addenda Format Error C14 Incorrect SEC Code for Outbound International Payment C61 Misrouted Notification of Change C62 Incorrect Trace Number C63 Incorrect Company Identification Number C64 Incorrect Individual Identification Number/Identification Number C65 Incorrectly Formatted Corrected Data C66 Incorrect Discretionary Data C67 Routing Number Not From Original Entry Detail Record C68 DFI Account Number Not From Original Entry Detail Record C69 Incorrect Transaction Code