NACHA ACH CCD+/PPD+ Formatter/Parser
Parses and formats NACHA ACH standard CCD+/PPD+ bank transaction files.
Install Options
Install CLI
npm install -g @ach/ach
Install Library
npm install @ach/ach --save
Table of Contents
Use CLI
- Provide input to stdin and get output from stdout.
- Both input and output formats default to 'ACH' when not provided.
- Provide one or more transform scripts use in between parsing and formatting
# these are all the same
# ach is both the CLI name and the default format
ach from ach to ach and edit with some.js
ach from ach to ach edit with some.js # no 'and'
ach from ach to ach edit some.js # no 'with'
ach from ach to ach some.js # no 'edit'
ach to ach some.js # no 'from ach'
ach from ach some.js # or, no 'to ach'
ach some.js # only the edit script
# short options
ach -i ach -o ach -e some.js
# long options
ach --input ach --output ach --edit some.js
# can input or output an ach file object in JSON
# read an ACH file and output it as JSON
ach to json
# read a JSON file and output it as ACH
ach from json
# read a file as ACH, send it thru another transform, and output as ACH
ach edit some-transform.js
# provide the content with OS specific commands to pipe it in and out
cat file.ach | ach to json > file.json
cat file.json | ach from json > file.ach
Note: when more formats are added all this will look better :)
Use API
ach
has three main functions to start with
- create() - used to generate an ACH file object with a series of calls
- wrap() - wraps an already built ACH file object to be used with create()'s API
- from() - used to start specifying a stream pipeline to parse/format
API: create()
ach = require('@ach/ach')
# this shows chained functions, but, you can hold the returns in a variable to reuse
achFile = ach.create
from: # the company generating the ACH file
name: 'Your Company'
# company tax ID. If the "predetermined char" isn't in front then
# a space is prepended
fein: '123456789'
for: # the bank the ACH file is being sent to
name: 'Our Bank' # they receive the file
routing: '123456789' # the routing number for the bank, with check digit
.ccd # a batch using CCD format
effectiveDate: '991231' # format: YYMMDD
description: 'Payment' # or, Payroll, or whatever
# optional values
note: 'the "discretionary data"'
date: 'Mar 30'
.credit # send money to another company
name: 'Target Company' # company receiving the money
account: # their bank account info
num: '135792468'
type: 'C' # C - checking (default), S - Savings
routing: '987654321' # their bank's routing number
amount: 12345 # amount in cents
# optional. CCD/PPD allows a single 'addenda' with an 80 character block
addenda: 'some addenda 80 chars long'
.credit # send money to another company
name: 'Another Company' # company receiving the money
account: # their bank account info
num: '159260'
type: 'C' # C - checking (default), S - Savings
routing: '987654321' # their bank's routing number
amount: 13579 # amount in cents
.debit # take that money from your company
name: 'Your Company' # your company sending the money
account: # your bank account info
num: '135792468'
type: 'C' # C - checking (default), S - Savings
routing: '987654321' # their bank's routing number
amount: 25924 # amount in cents
# optional. CCD/PPD allows a single 80 character 'addenda'
addenda: 'some addenda 80 chars long'
# same with a PPD batch.
# .ppd # a batch using PPD format
# effectiveDate: '991231' # format: YYMMDD
# description: 'Payroll'
# # optional values
# note: 'Some Employee'
# date: 'Mar 30'
# then you can send it to a stream or get it as a string.
# 1. stream
ach.from(achFile).to process.stdout
ach.from(achFile).to someFileStream
# 2. string
ach.from(achFile).to (string) -> console.log 'ACH File:\n', string
API: wrap()
ach = require '@ach/ach'
achObject = getSomeAchObjectSomehow()
ach.wrap achObject
# then use the same API functions provided by ach.create()
.ccd {}
.credit {}
.debit {}
# the `achObject` has all changes made by function calls
Using from().edit().to()
The goal is to setup a pipeline of stream transforms which parse an input stream, optionally edit the parsed object, then format the object back into a string and output it.
There are variations to use an object as the source as well as provide the result as a string or object.
These are used by the ach CLI.
An example pipeline:
- a file reader as the 'source' stream
- 'ach' format stream parser (transform) which converts the file to an ACH object
- optionally, some editing transform provided by user which receives the object, edits it, and passes it on
- 'ach' format stream formatter (writer) which converts the object to a string
- the final writer, maybe a file writer
API: from()
Valid arguments:
- a string representing the input format
- a string as the source of content
- a Readable stream as the source of content
- an object with two optional properties
The object (#4) can have:
- format - the name of the input format. currently only 'ach' and 'json' are available
- source - the input source may be:
- stream - any Readable object, or process.stdin (the default)
- string - string content must be in a format compatible with a known parser
- object - an ACH object to send into the pipeline
API: edit()
Valid argument for edit()
is an array. Array elements must be:
- string - a path, relative to the current working directory, to a JavaScript or CoffeeScript file
- a Transform class
- an instance of a Transform
- an object with implementation functions for Transform constructor
API: to()
Valid arguments:
- a string representing the output format
- a writable stream
- an object with two optional properties
The object (#3) can have:
- format - the name of the output format. currently only 'ach' and 'json' are available
- target - the output target may be:
- stream - a Writable object, or process.stdout (the default)
- function - a listener to receive either the object or string. If a format is specified then the listener receives a string in that format. Without a specified format it receives the ACH object.
API Examples
# specify everything, the longest style:
input = source: process.stdin, format: 'ach'
output = target: process.stdout, format: 'ach'
ach.from(input).to output
# Note: the above are all defaults and can be left out.
# the `source` and `target` properties can be: streams, strings, an ACH object
# specify only a format by specifying it as a string
ach.from('json').to()
ach.from().to 'json'
# specify the source content as a string:
someString = getAchObjectAsString()
ach.from(someString).to 'json'
# Note: it knows to do this because someString isn't a valid format
# input from a file reader
inputFile = fs.createReadStream 'some-file.ach', encoding:'utf8'
ach.from(inputFile).to(whatever)
# basic trio
ach.from('ach').edit(updateFileHeader).to 'json'
Future Plans
Additional Output Formats
- 'english' - a human readable format
- JSON
- YAML
- XML
Additional Bank Formats
There are many more formats in the NACHA ACH standards.
- CTX - This is very similar to CCD/PPD. It allows many addendas using EDI X12 820 format.
- IAT - International
- ... there's more