Add Payment Initiation to your app

Learn how to add Payment Initiation capabilities to your application

In this guide, we'll start from scratch and walk through how to use Payment Initiation to make a payment. The steps are a bit different from setting up to use most Plaid products. For a high level overview of the process before diving in to the code, see Intro to Payment Initiation.

Get Plaid API keys

If you don't already have one, you'll need to create a Plaid developer account. After creating your account, you can find your API keys under the Team Settings menu on the Plaid developer dashboard.

Request Payment Initiation access

You'll need to request access to Payment Initiation before using it in any Plaid development environment, including Sandbox. To get access to Payment Initiation, submit a product access request Support ticket.

Install Plaid libraries

You can use our official libraries to connect to the Plaid API from your application:

1
2
# Install via npm
npm install --save plaid

Create a recipient

Before beginning the payment initiation process, you will need to know how much money is being sent and the name and account information of the recipient. With this information in hand, you can then call /payment_initiation/recipient/create to create a payment recipient and recieve a recipient_id.

1
2
3
4
5
6
7
8
// Using BACS, without IBAN or address
const response = await client
.createPaymentRecipient(name, null, null, bacs)
.catch((err) => {
// handle error
});
const recipientID = response.recipient_id;

Create a payment

Now that you have the recipient_id, you can provide it and the payment amount to /payment_initiation/payment/create, which will return a payment_id.

1
2
3
4
5
6
7
8
const response = await client
.createPayment(recipientID, reference, amount)
.catch((err) => {
// handle error
});
const paymentID = response.payment_id;
const status = response.status;

Launch the Payment Initiation flow in Link

Plaid Link is a drop-in module that provides a secure, elegant authentication flow for each institution that Plaid supports. Link makes it secure and easy for users to connect their bank accounts to Plaid. Note that these instructions cover Link on the web. For instructions on using Link within mobile apps, see the Link documentation. If you want to customize Link's look and feel, you can do so from the Dashboard.

Before initializing Link, you will need to create a new link_token on the server side of your application. A link_token is a short-lived, one-time use token that is used to authenticate your app with Link. You can create one using the /link/token/create endpoint. Then, on the client side of your application, you'll need to initialize Link with the link_token that you just created. This will bring up the Payment Initiation flow in Link that will allow your end user to confirm the payment.

When calling /link/token/create for use with Payment Initiation, you will provide the payment_id in order to create a token that will initialize Link for the Payment Initiation flow, and you will specify payment_initiation as the product. While it is normally possible to initialize Link with multiple products, payment_initiation cannot be specified along with any other products and must be the only product in Link's product array if it is being used. If your user already has an Item, you can optionally provide its access_token to /link/token/create in order to force that Item to be used as the funding source of the payment.

In the code samples below, you will need to replace PLAID_CLIENT_ID and PLAID_SECRET with your own keys, which you can obtain from the Dashboard.

Create a link_token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Using Express
const express = require('express');
const app = express();
app.use(express.json());
const plaid = require('plaid');
const client = new plaid.Client({
clientID: process.env.PLAID_CLIENT_ID,
secret: process.env.PLAID_SECRET,
env: plaid.environments.sandbox,
});
app.post('/create_link_token', async (request, response) => {
try {
// Get the client_user_id by searching for the current user
const user = await User.find(...);
const clientUserId = user.id;
// Create the link_token with all of your configurations
const tokenResponse = await client.createLinkToken({
user: {
client_user_id: clientUserId,
},
client_name: 'Plaid Test App',
products: ['payment_initiation'],
country_codes: ['GB'],
language: 'en',
webhook: 'https://webhook.sample.com',
payment_initiation: {
payment_id: paymentId,
},
});
response.on({ link_token: tokenResponse.link_token });
} catch (e) {
// Display error on client
return response.send({ error: e.message });
}
});
Install Link dependency
1
2
3
4
<head>
<title>Connect a bank</title>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
</head>
Configure the client-side Link handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const linkHandler = Plaid.create({
token: (await $.post('/create_link_token')).link_token,
onSuccess: (public_token, metadata) => {
// Send the public_token to your app server.
$.post('/exchange_public_token', {
public_token: public_token,
});
},
onExit: (err, metadata) => {
// Optionally capture when your user exited the Link flow.
// Storing this information can be helpful for support.
},
onEvent: (eventName, metadata) => {
// Optionally capture Link flow events, streamed through
// this callback as your users connect an Item to Plaid.
},
});
linkHandler.open();

Verify payment status

Because Link has access to all of the details of the payment at the time of initialization, it will display a screen with the payment details already populated. All your end user has to do is log in to their financial institution through a Link-initiated OAuth flow, select a funding account, and confirm the payment details.

Once the payment is confirmed, you can track its status with the /payment_initiation/payment/get endpoint. A status of PAYMENT_STATUS_INITIATED means that the payment was successfully completed. Plaid will also fire the PAYMENT_STATUS_UPDATE webhook to alert you when there are any changes to the status of an initiated payment. Payments will generally complete immediately if the recipient account is in the UK, or in one business day if it is elsewhere in Europe.

1
2
3
4
5
6
7
8
9
10
11
12
const response = await client.getPayment(paymentID).catch((err) => {
// handle error
});
const paymentID = response.payment_id;
const paymentToken = response.payment_token;
const reference = response.reference;
const amount = response.amount;
const status = response.status;
const lastStatusUpdate = response.last_status_update;
const paymentTokenExpirationTime = response.payment_token_expiration_time;
const recipientID = response.recipient_id;