How ACH works: A developer perspective - Part 2

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.

A normal ACH transaction

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)

RDFI returns an ACH file

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".

ODFI returns an ACH file

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.

ACH change request

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