Introducing OpenACH, the world's first free, open-source, secure web-based ACH origination and payment processing platform... Payment processing made simple.


One of the great benefits of using OpenACH is how easily it can be integrated with websites, e-commerce systems, invoicing systems, etc. The API can be used to create and maintain payment profiles, bank accounts, and payment schedules. Payment profiles can easily be linked to your customer records using an 'external id', making it very easy to find your customers later, even if you don't want to have to track the IDs that OpenACH creates for them. The basic flow through the API is as follows:

  1. Connect/Authenticate

  2. Load one or more records

  3. Optionally save one or more records

  4. Disconnect/Logout

API Client, Requests and Responses

The OpenACH API operates on a client/request/response model. First, a client is created which connects to a specific OpenACH host, authenticating with an auth-token and key. Once connected, a request is made of the server, and the server returns a response to the client.


A client is created to connect to the OpenACH host, using a pre-arranged auth-token and key. Each auth-token and key are configured to allow access to payment profiles, bank accounts and payment schedules belonging to a single origination account.

// Load the OpenACH SDK
require_once( 'OpenACHSdk.php' );

// Create a new client
$client = new OAClient();

// Connect to the server
$response = $client->connect(
'a546730e-6a09-11e1-83b4-f23c91dfda4e', // Auth token
'a5467336-6a09-11e1-83b4-f23c91dfda4e' // Auth key

// Alternatively, a connection can be made to a specific endpoint URL and port number
$response = $client->connect(
'a546730e-6a09-11e1-83b4-f23c91dfda4e', // Auth token
'a5467336-6a09-11e1-83b4-f23c91dfda4e', // Auth key
'https://your.openach.server/', // Endpoint URL
'443' // Port Number

// The response will tell us whether or not we were successful
if ( ! $response->success )
// If unsuccessful
echo $response->error;
'Connected with a session id of ' . $response->session_id; // This is the PHPSESSID cookie

Load One or More Records

After connecting, you can send one or more requests to load records. OpenACH API allows you to build requests to work with four distinct types of records: Payment Profiles, External Accounts (e.g. Bank Accounts), Payment Schedules, and Payment Types.

Payment Profiles

Each payment profile represents a customer, and includes first and last name, email address, password, security questions/answers and status. A payment profile can have multiple external accounts (e.g. bank accounts) and payment schedules.

External Accounts

External accounts are simply customer bank accounts. It may seem odd at first to refer to them as "external accounts" instead of "bank accounts", but understand that OpenACH deals with all sorts of different bank accounts. These particular bank accounts are external in the fact that they belong to people other than the originator, and more than likely reside at other banks than the originator's bank account(s). We chose not to rename them simply for the API in order to avoid confusion for developers who work with both internal and SDK aspects of OpenACH. When you are using the API, just remember that "external account" simply means "bank account".

Any given payment profile may have multiple external accounts, and a single external account may be associated with many payment schedules. External accounts are defined by bank name, bank country, routing/SWIFT number, account number, account holder name, account type, and a billing address (required only for international transactions).

Payment Schedules

At the heart of OpenACH are payment schedules. Each individual payment schedule is associated with a single external account which is used to process the payment(s). Payment schedules can be created as one-time payments, or recurring payments with intervals of daily, weekly, biweekly, monthly, bimonthly, biannually, annually, or biennially. Each payment schedule is assigned an amount, payment type, currency code, next date, frequency, an end date, and status. OpenACH automatically calculates the remaining occurrences for each payment schedule based on this information. Each payment schedule is linked to a payment type.

Payment Types

To process payments, each origination account in OpenACH is configured with one or more payment types which define the transaction as either a credit (depositing funds INTO an external account), or a debit (withdrawing funds FROM an external account). They can only be modified from within the OpenACH web interface and are available through the API simply for reference when setting up new payment schedules.

Using Requests to Load Records

The SDK uses several different classes of requests to load data from OpenACH. Most of these requests require that you provide it a record id to search on, or a specific record id to load.

Request class
Requires input field
Responds with
OAGetExternalAccountRequest external_account_id A single external account
OAGetExternalAccountsRequest payment_profile_id All external accounts for the payment profile
OAGetPaymentProfileRequest payment_profile_id A single payment profile
OAGetPaymentProfileByExtIdRequest payment_profile_external_id A single payment profile
OAGetPaymentScheduleRequest payment_schedule_id A single payment schedule
OAGetPaymentSchedulesRequest payment_profile_id All payment schedules for the payment profile
OAGetPaymentTypesRequest All payment types

After a client is created, a request is built and sent through the client.

// ... SDK already loaded, new client created, and connected to the server

// Create a new Payment Profile request

$paymentProfileReq = new OAGetPaymentProfileByExtIdRequest();

// Set the external id that we're looking for
$paymentProfileReq->payment_profile_external_id = '327';

// Use the client to send the request to OpenACH
$paymentProfile = $client->sendRequest( $paymentProfileReq );

// We can check the response status
if ( ! $paymentProfile->success )

// Create a new external account request
$externalAccountsReq = new OAGetExternalAccountsRequest();

// Set the payment_profile_id to the profile we just loaded
$externalAccountsReq->payment_profile_id = $paymentProfile->payment_profile_id;

// Create a new payment schedules request (we will reuse this several times)
$paymentSchedulesReq = new OAGetPaymentSchedulesRequest();

$externalAccounts = $client->sendRequest( $externalAccountsReq );

// We could check for success, but a convenient feature of the response objects are that
// they implement array iterators, allowing us to spin through the results as if it were an array
// If there are no results or there was an error, the 'array' will simply be empty
foreach ( $externalAccounts as $externalAccount )
$paymentSchedulesReq->external_account_id = $externalAccount->external_account_id;
$paymentSchedules = $client->sendRequest( $paymentSchedulesReq );
    foreach (
$paymentSchedules as $paymentSchedule )
// display the payment schedule info, or whatever else you would like to do with the data...

Optionally save one or more records

After loading records, you may wish to update some information and save them, or even create new records from scratch. The SDK contains a set of request classes to facilitate saving records. In your workflow, you may create new records and/or update existing records. Regardless of which, the SDK provides a single save request that is capable of handling both situations. The only real difference is that when creating a new record, you will leave the record id blank so a new one can be assigned as it is created. When updating an existing record, the record id is provided so OpenACH knows what record to update.

Request class
Requires input fields
Responds with
OASaveExternalAccountRequest external_account_id*
A single external account
OASavePaymentProfileRequest payment_profile_id*
A single payment profile
OASavePaymentScheduleRequest payment_schedule_id*
A single payment schedule


When your session is complete, you can disconnect/logout from the OpenACH session. Doing so will both remove your current session id and auth details from the client, as well as close your session on the server. If you plan on reusing the same session id across multiple requests on your website/webapp, you can store the session id and bypass the connect/authenticate step for subsequent connections. Note however that for security purposes, you should not persist the session id for long periods of time, as the authentication will allow you to better control security from within OpenACH.

// ... SDK already loaded, new client created, and connected to the server

// Option 1: Save the session Id for later and destroy the client without disconnecting

$sessionId = $client->sessionId;
$client = null;

// Create a new client reusing an existing session id
$client = new OAClient();
$client->sessionId = $sessionId;
// ... continue using the client as before

// Option 2: Disconnect from the session completely (if not reusing the session id)


Using OpenACH Endpoints Directly

The OpenACH SDK relies on a REST/JSON web service framework. As such, the web service endpoints can be accessed directly by any language capable of REST/JSON calls. This also allows developers to port the OpenACH SDK into the programming language of their choice. The endpoints are available on every OpenACH installation. In the list below, the host name should be replaced as necessary, depending on which OpenACH server you intend to access. Parameters can be passed as either GET or POST, though we recommend using POST for reasons of security (GET requests are often logged by web servers, whereas POST are not.)

Requires input field(s)
Responds with user_api_token, user_api_key success, (error), session_id (none) success external_account_id (success, error) OR external_account object payment_profile_id (success, error) OR Array of external_account objects payment_profile_id (success, error) OR payment_profile object payment_profile_external_id (success, error) OR payment_profile object payment_schedule_id (success, error) OR payment_schedule object payment_profile_id (success, error) OR Array of payment_schedule objects (none) (success, error) OR Array of payment_type objects