Introduction

Plaid and Stripe have partnered to offer frictionless money transfers without the need to ever handle an account or routing number. Use Plaid Link to instantly authenticate your customer's account and automatically generate a Stripe bank account token so that you can accept ACH payments via their ACH API.
This guide is designed for those who already have a ACH-enabled account at both Stripe and Plaid. If that's not you, head over to the Stripe ACH docs to get started. You'll be able to sign up for a Plaid account from there.
Getting Started
You'll first want to familiarize yourself with Plaid Link, a drop-in integration for the Plaid API that handles input validation, error handling, and multi-factor authentication.
Your customers will use Link to authenticate with their financial institution
and select the depository account they wish to use for ACH transactions. From
there, you'll receive a Plaid access_token
, allowing you to leverage real-time
balance checks and transaction data, and a Stripe bank_account_token
, which
allows you to move money via Stripe's ACH API without ever handling an account
or routing number.
Instructions
Step 1: Set up your Plaid and Stripe accounts
You'll need accounts at both Plaid and Stripe in order to use the Plaid Link + Stripe integration. You'll also need to connect your Plaid and Stripe accounts so that Plaid can facilitate the creation of bank account tokens on your behalf.
First, sign up for a Stripe account if you do not already have one and then verify that it is enabled for ACH access. To verify that your Stripe account is ACH enabled, head to the ACH Guide when you are logged in to your Stripe account. If you see:
your account is not enabled. Click 'Accept Terms of Service' to enable your Stripe account for ACH. If you do not see the 'Accept Terms of Service' button, your Stripe account is already enabled for ACH access and you do not need to take any action.
Next, verify that your Plaid account is enabled for the integration. If you do not have a Plaid account, create one. Your account will be automatically enabled for integration access.
To verify that your Plaid account is enabled for the integration, go to the Integrations section of the account dashboard. If you see:
your Plaid account is enabled for the integration but you have not connected your Stripe account.
Click the 'Connect With Stripe' button to connect your Plaid and Stripe accounts. This step is required so that Plaid can facilitate the creation of Stripe bank account tokens on your behalf.
Once your Stripe account is connected, you'll see:
Your Plaid account is now set up for the integration!
Step 2: Get your public_key
Your public_key
is available from the Plaid Dashboard:
You have three different API keys
public_key
a non-sensitive, public identifier that is used to initialize Plaid Link
secret
client_id
private identifiers that are required for accessing any financial data
these should never be shared in client-side code
Your public_key
is a less privileged version of your client_id
and
secret
. It simply associates accounts you create using Plaid Link with
your client_id
. All Plaid API requests must be made using your private
client_id
and secret
.
Step 3: Integrate with Plaid Link
Integrating with Link is easy. All it takes is a few lines of client-side
JavaScript and a small server-side handler to exchange the Link public_token
for
a Plaid access_token
and a Stripe bank account token.
You can either trigger the "Institution Select" view, a general purpose view that lists all Plaid-supported institutions, or trigger a particular institution's login form. See below:
<button id="linkButton">Open Link - Institution Select</button>
<button id="bofaButton">Open Link - Bank of America</button>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js">
</script>
<script>
var linkHandler = Plaid.create({
selectAccount: true,
env: 'sandbox',
clientName: 'Client Name',
key: '[YOUR PUBLIC_KEY]',
product: ['auth'],
onLoad: function() {
// The Link module finished loading.
},
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.account_id, to your backend app server.
//
// sendDataToBackendServer({
// public_token: public_token,
// account_id: metadata.account_id
// });
console.log('Public Token: ' + public_token);
console.log('Customer-selected account ID: ' + metadata.account_id);
},
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 standard Institution Select view
document.getElementById('linkButton').onclick = function() {
linkHandler.open();
};
</script>
See the parameter reference for complete documentation on possible configurations.
Plaid.create
accepts one argument, a configuration Object
, and returns an
Object
with one function, open
, and one property, institutions
.
The exposed institutions
property is an Array
of Object
s in the form:
[
{
name: 'Bank of America',
institution_id: 'ins_1',
auth: true,
transactions: true,
},
...
]
The institutions
property will be populated with all supported institutions
for a given product. That is, the list of institutions will be different for
auth
and transactions
.
Step 4: Write server-side handler
The Link module handles the entire onboarding flow securely and quickly, but does
not actually retrieve account data for a user. Instead, the Link module returns
a public_token
and an account_id
—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. You will also send
the account_id
selected by the user to Plaid. Plaid
will automatically create and return a Stripe bank account token for this
account, which can be then be used to move money via Stripe's ACH API. The
bank account token will be linked to the Stripe account you linked in your Plaid Dashboard.
You can create Stripe bank account tokens in all three API environments:
- Sandbox (https://sandbox.plaid.com): test simulated users with Stripe's "test mode" API
- Development (https://development.plaid.com): test live users
- Production (https://production.plaid.com): production environment for when you're ready to go live
// Change sandbox
to development
to test with live users and change
// to production when you're ready to go live!
var plaid = require('plaid');
var plaidClient = new plaid.Client('[Plaid client ID]',
'[Plaid secret]',
'[Plaid public key]'
plaid.environments.sandbox);
plaidClient.exchangePublicToken('[Plaid Link public_token]', function(err, res) {
var accessToken = res.access_token;
// Generate a bank account token
plaidClient.createStripeToken(accessToken, '[Account ID]', function(err, res) {
var bankAccountToken = res.stripe_bank_account_token;
});
});
# Exchange token
curl -X POST https://sandbox.plaid.com/item/public_token/exchange \
-H 'Content-Type: application/json'
-d '{
"client_id": "[Plaid Client ID]",
"secret": "[Plaid secret]",
"public_token": "[Public token]"
}'
# Create bank account token
curl -X POST https://sandbox.plaid.com/processor/stripe/bank_account_token/create \
-H 'Content-Type: application/json'
-d '{
"client_id": "[Plaid Client ID]",
"secret": "[Plaid secret]",
"access_token": "[Access token]",
"account_id": "[Account ID]"
}'
# Change sandbox
to development
to test with live users and change
# to production
when you're ready to go live!
client = Plaid::Client.new(env: :sandbox,
client_id: ENV['PLAID_CLIENT_ID'],
secret: ENV['PLAID_SECRET'],
public_key: ENV['PLAID_PUBLIC_KEY'])
exchange_token_response = client.item.public_token.exchange('[Plaid Link public_token]')
access_token = exchange_response['access_token']
stripe_response = client.processor.stripeBankAccountTokenCreate(access_token, '[Account ID'])
bank_account_token = stripe_response['stripe_bank_account_token']
// Use builder to create a client
PlaidClient plaidClient = PlaidClient.newBuilder()
.clientIdAndSecret("[Plaid client ID]", "[Plaid secret]")
.publicKey("[Plaid public key]")
.sandboxBaseUrl() // Use the Sandbox. Can also be developmentBaseUrl()
or productionBaseUrl()
.build();
// Required request parameters are always Request object constructor arguments
Response<ItemPublicTokenExchangeResponse> exchangeResponse = plaidClient.service()
.itemPublicTokenExchange(new ItemPublicTokenExchangeRequest("[Plaid Link public_token]")).execute();
if (exchangeResponse.isSuccessful()) {
String accessToken = exchangeResponse.body().getAccessToken();
Response<ItemStripeTokenCreateResponse> stripeResponse =
client().service().itemStripeTokenCreate(new ItemStripeTokenCreateRequest(accessToken, "[Account ID]")).execute();
if (stripeResponse.isSuccessful()) {
String bankAccountToken = stripeResponse.body().getStripeBankAccountToken();
}
}
# Change sandbox
to development
to test with live users and change
# to production
when you're ready to go live!
client = Client('[Plaid client ID]',
'[Plaid secret]',
'[Plaid public key]'],
'sandbox')
exchange_token_response = client.Item.public_token.exchange('[Plaid Link public_token]')
access_token = exchange_token_response['access_token']
stripe_response = client.Processor.stripeBankAccountTokenCreate(access_token, '[Account ID]'])
bank_account_token = stripe_response['stripe_bank_account_token']
For a valid request, the API will return a JSON response similar to:
{
"stripe_bank_account_token": "btok_5oEetfLzPklE1fwJZ7SG",
"request_id": "[Unique request ID]"
}
For possible error codes, see the full listing of Plaid error codes.
Note: The account_id
parameter is required if you wish to receive a Stripe
bank account token.
Step 5: Test with sandbox credentials
Link's sandbox mode is compatible with Plaid's Sandbox API environment and Stripe's
"test mode" API. To test the integration in sandbox mode, simply use the Plaid
sandbox credentials along with your public_key
.
Use Stripe's ACH API in test mode to create test transfers using the bank account tokens you retrieve from Plaid's Sandbox API environment.
Step 6: Get ready for production
Your account is immediately enabled for our Sandbox and Development environments (https://sandbox.plaid.com and https://development.plaid.com), which allows you to test with Sandbox API credentials and up to 100 live users. To move to Production, please request access from the Dashboard.
Support and questions
Find answers to many common integration questions and concerns—such as pricing, sandbox and test mode usage, and more—at our Help Center and docs.
If you're still stuck, open a support ticket with information describing the issue that you're experiencing and we'll get back to you as soon as we can.