Linking an external account with Plaid

How to link an external account using Plaid and Bond's APIs.

Introduction

Bond platform's API allows you to link a verified external bank account of a customer or business to a Bond card account. Your customer or business can then transfer funds back and forth between their Bond and external accounts. Once the link is established, the customer's external account is represented by an Account object with an account_id identifier.

To list and remove external accounts, see Managing external accounts.

Linking process overview

Brands will use Plaid Link to enable the customer or business to immediately connect their external bank account to the Bond platform.

The prerequisite steps steps required in the process are as follows:

  1. Have a Plaid account. In previous external account linking workflows, Bond managed the Plaid accounts directly; this workflow supports an independent Plaid account
  2. Enable Bond as an integration for your brand.

Bond uses processor tokens for external account linking. This requires first generating the processor token for an external account and then using it to add the account to Bond. You will need the client_id and secret from your Plaid dashboard.

Generating a processor token

The following steps will largely use Python for code examples. Examples in other languages can be found on Plaid's token flow and processor token API documentation.

Generating a processor token requires 4 steps:

  1. Create a link_token
  2. Use the link_token to launch the link flow on the frontend and receive a public_token and account_id
  3. Exchange the public_token for an access_token
  4. Create a processor_token using Plaid's account_id and the access_token

There will be references to a client variable which can be initialized like:

import plaid
from plaid.api import plaid_api


api_key = {
  'clientId': 'YOUR_CLIENT_ID',
  'secret': 'YOUR_SECRET',
  'plaidVersion' = '2020-09-14'  
}

configuration = plaid.Configuration(
  host=plaid.Environment.Sandbox, 
  api_key=api_key
)
api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)

Step 1: Generate a Plaid link_token (Plaid documentation). Example code:

from plaid.model.country_code import CountryCode
from plaid.model.depository_account_subtype import DepositoryAccountSubtype
from plaid.model.depository_account_subtypes import DepositoryAccountSubtypes
from plaid.model.depository_filter import DepositoryFilter
from plaid.model.link_token_account_filters import LinkTokenAccountFilters
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.products import Products


request = LinkTokenCreateRequest(
    products=[Products('auth')],
    client_name="Plaid Test App",
    country_codes=[CountryCode('US')],
    redirect_uri='https://domainname.com/oauth-page.html',
    language='en',
    webhook='https://sample-webhook-uri.com',
    link_customization_name='default',
    account_filters=LinkTokenAccountFilters(
        depository=DepositoryFilter(
            account_subtypes=DepositoryAccountSubtypes(
                [DepositoryAccountSubtype('checking'), DepositoryAccountSubtype('savings')]
            )
        )
    ),
    user=LinkTokenCreateRequestUser(
        client_user_id=‘YOUR_CLIENT_ID’
    ),
)

response = client.link_token_create(request). 
link_token = response['link_token']

Step 2: Use the link_token from (1) to launch the frontend Plaid flow for connecting an account. After the Plaid flow is completed, Plaid returns a public_token. More details can be found on Plaid’s website, including example callback functions. However in the most basic sense, the code may look like:

const handler = Plaid.create({
  token: data['link_token'],
  onSuccess: (public_token, metadata) => {
    // Use public_token and metadata.account_id for steps 3 and 4
  },
  onLoad: () => {
  },
  onExit: (err, metadata) => {
  },
  onEvent: (eventName, metadata) => {
  },
  //required for OAuth; if not using OAuth, set to null or omit:
  // receivedRedirectUri: 'http://localhost:3001/oauth-link',
});

handler.open();

Step 3: Exchange the public_token from (2) for a an access_token. Detailed documentation on the exchange flow can be found here. Example code:

from plaid.model.item_public_token_exchange_request import ItemPublicTokenExchangeRequest


exchange_request = ItemPublicTokenExchangeRequest(public_token=public_token)
exchange_token_response = client.item_public_token_exchange(exchange_request)
access_token = exchange_token_response['access_token']

Step 4: Use the access_token from (3) to send a final request to Plaid and receive processor_token. More information can be found here. Example code:

from plaid.model.processor_token_create_request import ProcessorTokenCreateRequest


create_request = ProcessorTokenCreateRequest(
    access_token=access_token,  
    account_id=account_id,  # metadata.account_id from step 2
    processor='bond’
)
create_response = client.processor_token_create(create_request)
processor_token = create_response['processor_token']

Sending the processor token to Bond

Finally, you will use our API to add the linked account by hitting the POST /accounts/processor_tokens endpoint, which takes a payload with the following variables:

FieldType
processor_token
required
Processor token provided by Plaid (processor_token)
customer_id
required
The ID of the customer whose account will be linked.
curl --request POST \
  --url https://sandbox.bond.tech/api/v0.1/accounts/processor_tokens \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"processor_token": "processor-sandbox-922e5514-dba6-46e0-be38-4f691aa7888d", "customer_id": "e3dbc230-eba2-482a-95b9-791f5386e4b0"}'

The following is an example of a successful 201 response.

{
   "account_id": "5b655bc5-04c9-4e69-bc4a-7c6c57b4febc",
   "date_created": "2023-08-07T19:45:22.596051+00:00",
   "date_updated": "2023-08-07T19:45:22.596058+00:00",
   "customer_id": "e3dbc230-eba2-482a-95b9-791f5386e4b0",
   "status": "active",
   "verification_status": "instantly_verified",
   "type": "external",
   "link_type": "plaid",
   "linked_account_id": "5b655bc5-04c9-4e69-bc4a-7c6c57b4febc"
}

Note: If a 422 error code is returned, ensure that Bond is enabled as an integration.