Plaid ACH Integration

Prime Trust integrates with Plaid for the creation of ACH funds transfer methods. Plaid provides Plaid Link, a drop-in client-side integration for the Plaid API that handles input validation, error handling, and multi-factor authentication.

End users use Link to select the bank they have an account with, log in with their bank's credentials, and choose one of their accounts to use as a Prime Trust funds transfer method.

Integrators using the Plaid feature will no longer need to pass the Prime Trust API bank-account-number, routing-number, or bank_account_type. Instead, they will obtain a plaid_public_token and plaid_account_id and pass these to the Prime Trust API. These fields are safer to handle than raw account numbers, as they cannot be used unless in conjunction with secret keys held by Prime Trust.

Integration flow

  1. Customer loads Plaid Link, selects their bank, logs in, and selects an account.
  2. API integrator collects the returned plaid_access_token and account_id.
  3. API integrator exchanges Plaid access_token and account_id for a Plaid processor_token.
  4. API integrator creates a funds transfer method via API with the following changes:
    • a linked contact-id is always required
    • a plaid-processor-token is required
    • bank-account-number, routing-number, and bank-account-type are not allowed to be passed

Setup a Plaid account

You'll need to setup your Plaid Link account. Instructions for setup are here.

Once you setup you Plaid account, you'll access the Plaid Dashboard, go to the Integrations section, and click to enable Prime Trust.

Create a link token

Plaid provides a one-time use link_token to authenticate with Link during Link initialization. Note that the link_token replaces the legacy public_key authentication method. See the section below for legacy integration. Future Plaid development and features will be based on the link_token infrastructure.

You will use a client-side handler to create a link_token and a server-side handler to exchange the Link public_token for a Plaid access_token and a Prime Trust processor_token.

Instructions and sample code for creating and using a link_token are here.

  1. Use Plaid's /link/token/create request endpoint to obtain a link_token using your client_id and secret available from the Plaid Dashboard.
curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"client_id": "CLIENT_ID",
"secret": "SECRET",
"client_name": "My App",
"user": { "client_user_id": "UNIQUE_USER_ID" },
"products": ["auth"],
"country_codes": ["US"],
"language": "en",
"webhook": ""

Integrate with Link

Launch Link using client-side JavaScript.

<button id="linkButton">Open Link - Institution Select</button>
<script src=""></script>
(async function(){
var linkHandler = Plaid.create({
// Make a request to your server to fetch a new link_token.
token: (await $.post('/create_link_token')).link_token,
onSuccess: function(public_token, metadata) {
// The onSuccess function is called when the user has successfully
// authenticated and selected an account to use.
// When called, you will send the public_token and the selected account ID,
// metadata.accounts, to your backend app server.
public_token: public_token,
accounts: metadata.accounts
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
// metadata contains information about the institution
// that the user selected and the most recent API request IDs.
// Storing this information can be helpful for support.
// Trigger the authentication view
document.getElementById('linkButton').onclick = function() {
// Link will automatically detect the institution ID
// associated with the public token and present the
// credential view to your user.;

Server-side handler

The Link module returns a public_token and an accounts array, which is a property on the metadata object, via the onSuccess callback. Exchange this public_token for a Plaid access_token using the /item/public_token/exchange API endpoint.

Send the access_token and account_id property of the account to Plaid via the /processor/token/create endpoint in order to create a processor_token.

# Exchange token
curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"client_id": "[Plaid Client ID]",
"secret": "[Plaid secret]",
"public_token": "[Public token]"
# Create a processor token for a specific account id.
curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"client_id": "PLAID_CLIENT_ID",
"secret": "PLAID_SECRET",
"access_token": "ACCESS_TOKEN",
"account_id": "ACCOUNT_ID",
"processor": "prime_trust"


"processor_token": "processor-sandbox-0asd1-a92nc",
"request_id": "m8MDnv9okwxFNBV"

Create an ACH Funds Transfer Method

Using the returned Plaid values, create an ACH Funds Transfer Method with a linked Contact:

"data": {
"type": "funds-transfer-method",
"attributes": {
"contact-id": "EXISTING_CONTACT_ID",
"plaid-processor-token": "PLAID_PROCESSOR_TOKEN",
"funds-transfer-type": "ach",
"ach-check-type": "personal",
"bank-account-name": "John James Doe",
"ip-address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334"

When using the Plaid attributes, bank_account_number, routing_number, and bank_account_type cannot be used. The returned Funds Transfer Method should have the account number, routing number, and account type automatically filled in based on the information from Plaid. This Funds Transfer Method can then be used to create a Contribution as normal.

Account Policies for Plaid


When set to true for an account, any attempt to create a new ACH Funds Transfer Method without a plaid_public_token will be rejected. Any attempt to create a Contribution using a Funds Transfer Method that was not created using a plaid_public_token will also be rejected.


When combined with require_plaid_authentication_on_ach, ACH Contributions using a Plaid Funds Transfer Method, the customer bank account must have at least the Contribution amount plus this percentage of the amount in available funds.


  • when minimum_percentage_balance_for_ach_contribution is 10.0 and Contribution amount is $100, the bank account must have at least $110 in their available balance
  • when minimum_percentage_balance_for_ach_contribution is 50.0 and Contribution amount is $900, the bank account must have at least $1,350 in their available balance

Note: sandbox testing in Plaid is limited to what is available to the "user_good" login (password "pass_good")

Legacy integration using public key

You can read about how to migrate from using a public_key to a link_token here. Integrators are encouraged to use the link_token method to use Plaid Link.

The fastest way to get started is to download the Plaid quickstart examples. From your terminal:

git clone
cd quickstart/node
npm install

Inside the quickstart folder, open the node/views/index.ejs file in a text editor. Edit line 247 and insert new lines to match the following and save:

onSuccess: function(public_token, metadata) {
console.log('plaid_public_token', public_token);
console.log('plaid_account_id', metadata.account_id);
$.post('/get_access_token', {

Start the quickstart project:

APP_PORT=8000 \
PLAID_ENV=sandbox \
node index.js

In your browser, visit http://localhost:8000. Open the Chrome/browser inspector and navigate to the "Console" tab. Go through the Plaid widget to login and select a bank account. The only bank credentials working in sandbox are:

  • Username: user_good
  • Password: pass_good

After a successful login, the Chrome/browser inspector console should show the plaid_public_token and plaid_account_id.

After going through the Plaid quickstart flow, you will take the access_token that was output, and retrieve the plaid_account_id. This will be done by using the following endpoint:

"client_id": "YOUR_CLIENT_ID",
"secret": "YOUR_SECRET_KEY",
"access_token": "ENTER_ACCESS_TOKEN_HERE"

After retrieving the plaid_account_id, you will make one more call before creating the funds transfer method. You must take both the access_token and plaid_account_id, and exchange them for a processor_token:

"client_id": "YOUR_CLIENT_ID",
"account_id": "{{Plaid_Account-ID}}",
"secret": "YOUR_SECRET_KEY",
"access_token": "ENTER_ACCESS_TOKEN_HERE",
"processor": "prime_trust"
Last updated on