ACH Processing

The OpenTransact API is able to connect to financial instutions that enable ACH processing, sometimes referred to as ACH Origination. This guide will walk you through integrating with the OpenTransact API for the purposes of connectiong to one of the integrated partners that supports processing ACH payments.

Integration Basics

1: Create a Profile for the Entity you want to transact with

Whenever you want to transact with a Person or Organization, you will need to create a Profile for them within the OpenTransact API.

See the API Docs for Create Profile for more information on the required attributes and options for this request.

# cURL is most likely already installed on your machine
curl --request POST \
  --url https://api.opentransact.com/v1/profiles \
  --header 'Authorization: Basic {AUTH_TOKEN}' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
	"data": {
		"type": "profiles",
		"attributes": {
			"owner": {
				"type": "people",
				"first-name": "First",
				"last-name": "User"
			},
			"metadata": {
			}
		},
		"relationships": {
			"application": {
				"data": {
					"id": "{APPLICATION_ID}",
					"type": "applications"
				}
			}
		}
	}
}'

2: Add an Address to the Profile (optional for ACH)

Once the profile is created you may want to add an address to the profile. Addresses are not required by default for ACH processing, but may be required by verification services, or the risk management requirements for your processing partner. Take the ID from the profile you created in the previous step and use it in the request below where you see {PROFILE_ID}.

See the API Docs for Create Address for more information on the required attributes and options for this request.

# cURL is most likely already installed on your machine
curl --request POST \
  --url https://api.opentransact.com/v1/addresses \
  --header 'Authorization: Basic {AUTH_TOKEN}' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
            "data": {
              "type": "addresses",
              "attributes": {
                "street1": "111 PEACHTREE PLACE",
                "locality": "Atlanta",
                "region": "GA",
                "country": "US",
                "zipcode": "30345"
              },
              "relationships": {
                "owner": {
                  "data": {
                    "type": "profiles",
                    "id": "{PROFILE_ID}"
                  }
                }
              }
            }
          }

3: Add an Account to the Profile

The final bit of information required to make ACH transactions is adding an Account to the Profile. For ACH transactions youll need to send parameters for an Account of type BankAccount.

See the API Docs for Create Account for more information on the required attributes and options for this request.

Optionally, integrate our Javascript SDK, and Create a Client Token to let your users directly submit Account information to the OpenTransact API without sensitive data hitting your servers.

cURL

# Create an Account using cURL
curl --request POST \
  --url https://api.opentransact.com/v1/accounts \
  --header 'Authorization: Basic {AUTH_TOKEN}' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
	"data": {
		"type": "accounts",
		"attributes": {
			"nickname": "Personal Checking Account",
			"details": {
				"type": "bank-accounts",
				"account-number": "300000991",
				"routing-number": "021000021",
				"account-holder-type": "personal",
				"account-category": "checking"
			}
		},
		"relationships": {
			"owner": {
				"data": {
					"type": "profiles",
					"id": "{PROFILE_ID}"
				}
			}
		}
	}
}'

4: Ensure the Account becomes active.

If your Application on OpenTransact is configured with a rule for activating Accounts, it will be run after the Account is created. This may involve checking a third party service or database to ensure the Account is valid. Once complete, the Account will be updated and either be in the active or invalid state. You can only create transactions with an Account in the active state.

Fetch the Account to check the status. See the API Docs for Show Account for more information.

# Fetch the Account to check the status
curl --request GET \
  --url https://api.opentransact.com/v1/accounts/{ACCOUNT_ID} \
  --header 'Authorization: Basic {AUTH_TOKEN}' \
  --header 'Content-Type: application/vnd.api+json'

5: Create a Transaction.

Once you have an active Account of type BankAccount on your profile you can now create ACH transactions with that Account. If you are sending money to the recipient you will want to set the transaction-type attribute to credit. If you want to receive funds from the account, you will set it to debit.

Use the Account ID and Profile ID from the previous steps where you see {ACCOUNT_ID} and {PROFILE_ID} in the request below.

See the API Docs for Create Transaction for more information on the required attributes and options for this request.

# Create a Transaction using cURL
curl --request POST \
  --url https://api.opentransact.com/v1/transactions \
  --header 'Authorization: Basic {AUTH_TOKEN}' \
  --header 'Content-Type: application/vnd.api+json' \
  --data '{
	"data": {
		"type": "transactions",
		"attributes": {
			"transaction-type": "debit",
			"amount": 12,
			"precision": 2,
			"currency": "USD",
			"memo": "First Transaction"
		},
		"relationships": {
			"account": {
				"data": {
					"id": "{ACCOUNT_ID}",
					"type": "accounts"
				}
			},
			"profile": {
				"data": {
					"id": "{PROFILE_ID}",
					"type": "profiles"
				}
			}
		}
	}
}'

6: Monitor the Activity Stream for updates to the transaction status.

Based on the payment provider you have chosen to connect or the bank where you are processing ACH transactions, the Transactions you create will be submitted for processing. When successful, they will move into the processed state and when unsuccesful, they will move into the processing_failed state.

See the API Docs for List Activities for more information.

# Fetch the Account to check the status
curl --request GET \
  --url 'https://api.opentransact.com/v1/activities?filter%5Bapplication-id%5D={APPLICATION_ID}' \
  --header 'Authorization: Basic {AUTH_TOKEN}'

7: Monitor the Activity Stream for Returns and NOCs.

Using the same or similar API call to Step 6, monitor the Activity stream for ACH Returns and ACH Notifications of Change. ACH transactions are never truly final. While the state of the Transaction will move to processed, this just means that the bank has received it and will process it. The transaction can still fail for a multitude of reasons, which you can read about in the list of ACH Return Codes. Additionally, when there are minor errors in the data submitted, banks may process the transaction if able, and then respond with a Notificaiton of Change (NOC), which will contain info for correcting the minor errors. For this reason you must continuously monitor the Activity stream for AchReturn and AchNotificationOfChange objects related to the Transactions you have processed. When an AchReturn occurs, the Transaction will in essence have been reversed by the bank/processor, when a NOC occurs, you must alter the information you have on file to correct the error. If you are vaulting account data in OpenTransact, rules can be configured to automatically resolve NOC errors.

See the API Docs for List Activities for more information.

Testing in Sandbox

ACH Test scenarios:

Successful Account Number

All transactions that don’t match one of the failure criteria below will trigger the system to return a successful result.

Bad Routing Number

Confirm that your application can handle a user entering a bad routing number. You can mitigate this issue by using our Banks endpoint to confirm user entry prior to creating an account.

Non USD transaction

All transactions on the ACH network are denominated in the US dollar. Confirm your application’s behavior either prevents non-USD payments entirely from being entered as debits or credits against bank accounts, or handle the specific error when it may occur.

Incorrect Precision

ACH transaction amounts must be denominated in dollar and cents only, so only a precision of 2 is supported for transactions you wish to process on the ACH network. Confirm the application’s behavior either prevents entry of transactions with a precision other than 2 or handles the error appropriately where it occurs.

Return Generating Account Numbers

ACH Transactions may be returned in the future due to a variety of reasons. You can simulate ACH returns via the MockACHGateway by entering transactions against accounts with the following info:

Routing Number: 021000021 Account Number: any valid account number starting with 4000 and ending in the 2 digit return code you wish to trigger.

Ex: 021000021 400087802 will generate a R02 Account Closed return.

Returns will be generated after the processing of a matching transaction.

Notification of Change Generating Account Numbers

ACH Transactions may trigger what is called a notification of change due to a variety of reasons. You can simulate ACH notification of change by entering transactions against accounts with the following info:

Routing Number: 021000021 Account Number: any valid account number starting with 5000 and ending in the 2 digit NOC code you wish to trigger.

Ex: 021000021 500087802 will generate a C02 Incorrect transit/routing number notification of change.

Notification of Changes will be generated after the processing of a matching transaction.

Application Test Checklist

Before deploying an integrated application to production, it's crucial to thoroughly test and prepare for various ACH processing scenarios. Comprehensive testing ensures that applications can handle real-world situations effectively and securely. While the checklist below outlines specific test cases, it's important to consider a wide range of scenarios that may occur during ACH transactions. By rigorously testing these scenarios, the reliability of integrated applicatios can be enhanced, user experience can be improved, and compliance can be maintained according to ACH network requirements. Let's review some key areas to focus on:

  • Ensure your application can enter successful transactions
  • Ensure your application can handle entering an account with a bad routing number, confirming your system prevents it or handles the error
  • Ensure your application can prevent entering non USD transactions against bank accounts, or handles error correctly
  • Ensure your application can prevent entering of transactions with a precision other than 2, or handles error correctly
  • Ensure your application can handle a transaction which is returned
  • Ensure your application can handle a transaction which triggers a notification of change

ACH Return Codes

CodeReasonDescription
R01INSUFFICIENT FUNDSThe available and/or cash reserve balance is not sufficient to cover the dollar value of the debit entry.
R02ACCOUNT CLOSEDA previously active account has been closed by action of the customer or the RDFI.
R03NO ACCOUNT / UNABLE TO LOCATE ACCOUNTThe account number structure is valid and it passes the check digit validation, but the account number does not correspond to the individual identified in the entry, or the account number designated is not an open account.
R04INVALID ACCOUNT NUMBERThe account number structure is not valid. The entry may fail the check digit validation or may contain an incorrect number of digits.
R05RESERVED
R06RETURNED PER ODFI's REQUESTThe ODFI has requested that the RDFI return the ACH entry. If the RDFI agrees to return the entry, the ODFI must indemnify the RDFI according to Article Five(Return, Adjustment, Correction, and Acknowledgement of Entries and Entry Information) of these Rules.
R07AUTHORIZATION REVOKED BY CUSTOMERThe RDFI's customer (the Receiver) has revoked the authorization previously provided to the Originator for this particular transaction.
R08PAYMENT STOPPED or STOP PAYMENT ON ITEMThe Receiver of a recurring debit transaction has the right to stop payment on any specific ACH debit. The RDFI determines that a stop payment order has been placed on the item to which the PPD debit entry constituting notice of presentment or the PPD Accounts Receivable Truncated Check Debit Entry relates.
R09UNCOLLECTED FUNDSSufficient book or ledger balance exists to satisfy the dollar value of the transaction, but the dollar value of transactions in the process of collection (i.e., uncollected checks) brings the available and/or cash reserve balance below the dollar value of the debit entry.
R10CUSTOMER ADVISES NOT AUTHORIZEDThe RDFI has been notified by its customer, the Receiver, that the Originator of a given transaction has not been authorized to debit his account.
R11CHECK TRUNCATION ENTRY RETURNTo be used when returning a check truncation entry. This reason for return should be used only if no other return reason code is applicable.
R12BRANCH SOLD TO ANOTHER DFIA financial institution may continue to receive entries destined for an account at a branch that has been sold to another financial institution. Because the RDFI no longer maintains the account and is unable to post the entry, it should return the entry to the ODFI.
R13RDFI NOT QUALIFIED TO PARTICIPATE
R14REPRESENTATIVE PAYEE DECEASED or UNABLE TO CONTINUE IN THAT CAPACITYThe representative payee is a person or institution authorized to accept entries on behalf of one or more other persons, such as legally incapacitated adults or minor children. The representative payee is either deceased or unable to continue in that capacity. The beneficiary is not deceased.
R15BENEFICIARY or ACCOUNT HOLDER DECEASED1. The beneficiary is the person entitled to the benefits and is deceased. The beneficiary may or may not be the account holder; 2. The account holder (acting in a non-representative payee capacity) is an owner of the account and is deceased.
R16ACCOUNT FROZENThe funds in the account are unavailable due to specific action taken by the RDFI or by legal action.
R17FILE RECORD EDIT CRITERIASome fields that are not edited by the ACH Operator are edited by the RDFI. If the entry cannot be processed by the RDFI, the field(s) causing the processing error must be identified in the addenda record information field of the return.
R18IMPROPER EFFECTIVE ENTRY DATE
R19AMOUNT FIELD ERROR
R20NON-TRANSACTION ACCOUNTThe ACH entry destined for a non-transaction account, as defined in Regulation D, would include either an account against which transactions are prohibited or limited or a pass-through where the entry is for a credit union or thrift organization and Regulation E descriptive requirements cannot be met.
R21INVALID COMPANY IDENTIFICATIONThe identification number used in the Company Identification Field is not valid. This Return Reason Code will normally be used on CIE transactions.
R22INVALID INDIVIDUAL ID NUMBERIn CIE and MTE entries, the Individual ID Number is used by the Receiver to identify the account. The Receiver has indicated to the RDFI that the number with which the Originator was identified is not correct.
R23CREDIT ENTRY REFUSED BY RECEIVERThe Receiver may return a credit entry because one of the following conditions exists: 1. a minimum amount required by the Receiver has not been remitted; 2. the exact amount required has not been remitted; 3. the account is subject to litigation and the Receiver will not accept the transaction; 4. acceptance of the transaction results in an overpayment; 5. the Originator is not known by the Receiver; 6. the Receiver has not authorized this credit entry to this account.
R24DUPLICATE ENTRYThe RDFI has received what appears to be a duplicate entry; i.e., the trace number, date, dollar amount and/or other data matches another transaction. This code should be used with extreme care. The RDFI should be aware that if a file has been duplicated, the Originator may have already generated a reversal transaction to handle the situation.
R25ADDENDA ERROR
R26MANDATORY FIELD ERROR
R27TRACE NUMBER ERROR
R28ROUTING NUMBER CHECK DIGIT ERROR
R29CORPORATE CUSTOMER ADVISES NOT AUTHORIZEDThe RDFI has been notified by the Receiver (non-consumer) that the Originator of a given transaction has not been authorized to debit the Receiver's account.
R30RDFI NOT PARTICIPANT IN CHECK TRUNCATION PROGRAM
R31PERMISSIBLE RETURN ENTRY (CCD and CTX only)The RDFI has been notified by the ODFI that the ODFI agrees to accept a CCD or CTX return entry in accordance with Article Seven, section 7.3 (ODFI Agrees to Accept CCD or CTX Return).
R32RDFI NON-SETTLEMENT
R33RETURN OF XCK ENTRYThe RDFI determines at its sole discretion to return an XCK entry. This return reason code may only be used to return XCK entries. An XCK entry may be returned up to sixty days after its Settlement Date.
R34LIMITED PARTICIPATION DFI
R35RETURN OF IMPROPER DEBIT ENTRY
R36RETURN OF IMPROPER CREDIT ENTRY
R40RETURN OF ENR ENTRY BY FEDERAL GOVERNMENT AGENCY (ENR only)The Federal Government Agency determines at its sole discretion to return an ENR entry. This return reason code may be used only to return ENR entries.
R41INVALID TRANSACTION CODE (ENR only)Either the Transaction Code included in Field 3 of the Addenda Record does not conform to the ACH Record Format Specifications contained in Appendix Two (ACH Record Format Specifications) or it is not appropriate with regard to an automated enrollment entry.
R42ROUTING NUMBER / CHECK DIGIT ERROR (ENR only)The Routing Number and the Check Digit included in Field 3 of the Addenda Record is either not a valid number or it does not conform to the Modulus 10 formula.
R43INVALID DFI ACCOUNT NUMBER (ENR only)The consumer's or company's account number included in Field 3 of the Addenda Record must include at least one alphameric character.
R44INVALID INDIVIDUAL ID NUMBER / IDENTIFICATION NUMBER (ENR only)The Individual ID Number/Identification Number provided in Field 3 of the Addenda Record does not match a corresponding ID number in the Federal Government Agency's records.
R45INVALID INDIVIDUAL NAME / COMPANY NAME (ENR only)The name of the consumer or company provided in Field 3 of the Addenda Record either does not match a corresponding name in the Federal Government Agency's records or fails to include at least one alphameric character.
R46INVALID REPRESENTATIVE PAYEE INDICATOR (ENR only)The Representative Payee Indicator Code included in Field 3 of the Addenda Record has been omitted or it is not consistent with the Federal Government Agency's records.
R47DUPLICATE ENROLLMENT (ENR only)The entry is a duplicate of an automated enrollment entry previously initiated by a participant in the ENR automated enrollment program.
R50STATE LAW AFFECTING RCK ACCEPTANCE (To be Used for the Return of RCK Entries)The RDFI is located in a state that has not adopted Revised Article 4 of the Uniform Commercial Code (1990 Official Text) and has not revised its customer agreements to allow for electronic presentment. The RDFI is located within a state that requires all canceled checks to a specific type of account to be returned to the Receiver within the periodic statement.
R51ITEM INELIGIBLE, NOTICE NOT PROVIDED, SIGNATURE NOT GENUINE, or ITEM ALTERED (adjustment entries) (To be Used for the Return of RCK Entries)An entry may be considered to be ineligible if the item to which the RCK entry relates is not an item within the meaning of Revised Article 4 of the Uniform Commercial Code (1990 Official Text); the item is not a negotiable demand draft drawn on or payable through or at a Participating DFI, other than a Federal Reserve Bank or Federal Home Loan Bank; the item is in an amount of $2,500 or more; the item does not indicate on the face of the document that it was returned due to "Not Sufficient Funds, "NSF", Uncollected Funds," or comparable language; the item is dated more than 180 days from the date the entry is being transmitted to the RDFI (i.e., the item to which the RCK entry relates is stale dated); the item is drawn on a non-Consumer Account; the item has been previously presented more than two times in its physical form, or more than one time in its physical form and more than one time as an RCK entry.
R52STOP PAYMENT ON ITEM (adjustment entries) (To be Used for the Return of RCK Entries)The RDFI determines that a stop payment order has been placed on the item to which the RCK entry relates. An RDFI using this Return Reason Code must transmit the return entry by its ACH Operator's deposit deadline for the return entry to be made available to the ODFI no later than the opening of business on the banking day following the sixtieth calendar day following the Settlement Date of the RCK entry to which the item relates.
R61MISROUTED RETURN (To be Used by the ODFI for Automated Dishonored Return Entries)The financial institution preparing the return entry (the RDFI of the original entry) has placed the incorrect Routing Number in the Receiving DFI Identification field (positions 04-12, including Check Digit, of the Entry Detail Record).
R62INCORRECT TRACE NUMBER (To be Used by the ODFI for Automated Dishonored Return Entries)The Trace Number found in positions 07-21 in the Addenda Record of the return entry is different from the trace number of the original entry.
R63INCORRECT DOLLAR AMOUNT (To be Used by the ODFI for Automated Dishonored Return Entries)The dollar amount in the Entry Detail Record of the return entry is different from the dollar amount of the original entry.
R64INCORRECT INDIVIDUAL IDENTIFICATION (To be Used by the ODFI for Automated Dishonored Return Entries)The Individual Identification Number reflected in the Entry Detail Record of the return entry is different from the Individual Identification Number/Identification Number used in the original entry.
R65INCORRECT TRANSACTION CODE (To be Used by the ODFI for Automated Dishonored Return Entries)The Transaction Code in the Entry Detail Record of the return entry is not the return equivalent of the Transaction Code in the original entry. (See list of Transaction Codes in Appendix Two (ACH Record Format Specifications). All entries must be returned as received: e.g., credit as credit, debit as debit, demand as demand, savings as savings.)
R66INCORRECT COMPANY IDENTIFICATION (To be Used by the ODFI for Automated Dishonored Return Entries)The Company Identification number used in the Company/Batch Header Record of the return entry is different from the Company Identification number used in the original entry.
R67DUPLICATE RETURN (To be Used by the ODFI for Automated Dishonored Return Entries)The ODFI has received more than one return for the same entry.
R68UNTIMELY RETURN (To be Used by the ODFI for Automated Dishonored Return Entries)The return entry has not been sent within the timeframe established by these rules.
R69MULTIPLE ERRORS (To be Used by the ODFI for Automated Dishonored Return Entries)Two or more of the following fields — Original Entry Trace Number, Amount, Individual Identification Number/Identification Number, Company Identification, and/or Transaction Code — are incorrect.
R70PERMISSIBLE RETURN ENTRY NOT ACCEPTED (To be Used by the ODFI for Automated Dishonored Return Entries)The ODFI has received a CCD or CTX return entry identified by the RDFI as being returned with the permission of the ODFI, but the ODFI has not agreed to accept the entry. This code may be used only to dishonor a return containing an R31 return reason code.
R80CROSS-BORDER PAYMENT CODING ERROR (To be Used for the Return of CBR and PBR Entries)The cross-border entry is being returned due to one or more of the following conditions: • invalid Foreign Exchange Indicator; • invalid ISO Originating Currency Code; • invalid ISO Destination Currency Code; • invalid ISO Destination Country Code; • invalid Transaction Type Code.
R81NON-PARTICIPANT IN CROSS-BORDER PROGRAM (To be Used for the Return of CBR and PBR Entries)The cross-border entry is being returned because the Originating Gateway Operator does not have an agreement with the ODFI to process cross-border entries.
R82INVALID FOREIGN RECEIVING DFI INDENTIFICATION (To be Used for the Return of CBR and PBR Entries)The reference used to identify the Foreign Receiving DFI of an outbound cross-border entry is invalid.
R83FOREIGN RECEIVING DFI UNABLE TO SETTLE (To be Used for the Return of CBR and PBR Entries)The cross-border entry is being returned due to settlement problems in the foreign payment system.

Was this page helpful?