"Astoundingly" complicated???? ACH/NACHA isn't any more complicated than any other API. If anything it's easier than most if you're used to string processing, because the file format is just 80 character rows with 9 different types of rows starting with that numerical digit. The schema is well defined. In many cases a "transaction" is executed by simply FTPing an .ach file. What did you find so complicated?
* ACH-formatted transactions are supposed to be 80 character rows, but ACH emitters play loose and fast with that. 81 (CR/LF) and 82 (CR+LF) character entries are common enough in the wild that financial communities regularly complain about them. ACH transactions are supposed to be concatenative, so it wouldn't surprise me to learn that most real-world ACH handling code needs to handle 80, 81, and 82-character records in the same stream.
* The envelope and hierarchy of ACH is extremely simple. The internal state machine isn't: there are plenty of overlapping entry classes[1], obscure return codes, common misuse of said codes, and rider entries (like addenda information). The records for international settlements are shockingly complex; no ODFIs or RDFIs seem to follow the rules about not clawing back money after various contest periods expire.
[1]: When do I use CIE entries versus PPD? Do I use WEB for a recurring utility payment that was initiated online?
In addition to the sibling comment: as already mentioned, the machinery to handle ACH (or any bank transactions, really) is very complex:
- the formats (there are more than one for interbank communications) are never properly followed by any bank, and many add their own undocumented proprietary extensions to them
- they are usually processed in batches, and the entirety of bank systems are built assuming that everything is processed in batches at specific times of day
- entries in batches may and will arrive out-of-order. For example, a request to cancel a transaction may and at one point will arrive before the request to authorize a transaction.
- a lot of other systems are built into the entire transaction process and assuming everything is processed in batches: fraud detection, dunning chains [1], account cancellations, reminders, fees etc. etc.
- There are systems where bank holidays are built into the system. If bank holiday is on a Friday, and you request/send payment, it will not be processed by the bank on the other side until Monday evening and the transaction will not be completed until Tuesday morning.
And that's just scraping the top of the iceberg. You can't just magically replace this. But you can try to build on top/work around that.
> entries in batches may and will arrive out-of-order.
This is on purpose by some banks. They will sort the incoming queue and process withdraws before deposits to increase the number of NSF fees they collect.
...and as someone that interfaces with clearing firms via SFTP, I can tell you that it's a nightmare. FTP was great for downloading ratio-ed mp3s in the year 1998. It's a terrible way to handle things in 2020. It perplexes me how much of my industry is held together by cron-jobs and SFTP processes.