Linking an external account without the Bond SDK

How to link an external account using Bond API endpoints directly.

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 card account and external account. Once the link is established, the customer's external account is represented by an Account object with an account_id identifier and type attribute that has the value external or migrate_account.

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

Linking process overview

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

The steps required in the process are as follows:

  1. Create a Bond account corresponding to the external account
  2. Use the provided link_token with the Plaid SDK for the customer
  3. Exchange Plaid's public_token for an access_token
  4. Link the Bond external account to a Bond card accounts

The Bond endpoints that make requests to the Plaid APIs require the access_token to identify the customer's linked external account within Plaid. Bond controls the access_token management when needed by other endpoints.

TokenOrigin and use
link_tokenTemporary token returned by Plaid to establish the link between the client frontend and the Bond platform backend.
public_tokenTemporary token returned by Plaid after the customer supplies their bank details and is exchanged for an access_token.
access_tokenPermanent token used to access the customer's external bank account via Plaid. This token uniquely represents the customer's login for their bank account.

Linking process

Creating an external account

The first step is to create a Bond account that represents the customer or business's external account in the Bond platform. This is done by making a request to the POST /accounts endpoint with the following body parameters:

FieldType
type
required
Account type to be created, external or migrate_account. Must be external for Plaid Link.
link_type
required
The service name that the external account belongs to, plaid.
customer_id
required
The ID of the customer whose account will be linked.
business_id
required
The ID of the business whose account will be linked.

This endpoint creates the Bond account and returns both the account_id of the Bond account and a link_token which can be used by the Plaid Link SDK to initialize the bank linking process.

The following example demonstrates a request to create an account. Note that you must provide either a customer_id or business_id in the request body:

curl --request POST \
     --url https://sandbox.bond.tech/api/v0/accounts \
     --header 'Authorization: YOUR-AUTHORIZATION' \
     --header 'Content-Type: application/json' \
     --header 'Identity: YOUR-IDENTITY' \
     --data '{"type": "external", "link_type": "plaid", "customer_id": "6f0e7dcb-6073-42df-bf02-ce71bd5fac3a"}'
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://sandbox.bond.tech/api/v0/accounts")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["Identity"] = 'YOUR-IDENTITY'
request["Authorization"] = 'YOUR-AUTHORIZATION'
request.body = "{\"type\":\"external\",\"link_type\":\"plaid\"}"

response = http.request(request)
puts response.read_body
const options = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Identity: 'YOUR-IDENTITY',
    Authorization: 'YOUR-AUTHORIZATION'
  },
  body: JSON.stringify({type: 'external', link_type: 'plaid'})
};

fetch('https://sandbox.bond.tech/api/v0/accounts', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
import requests

url = "https://sandbox.bond.tech/api/v0/accounts"

payload = {
    "type": "external",
    "link_type": "plaid"
}
headers = {
    "Content-Type": "application/json",
    "Identity": "YOUR-IDENTITY",
    "Authorization": "YOUR-AUTHORIZATION"
}

response = requests.request("POST", url, json=payload, headers=headers)

print(response.text)
var client = new RestClient("https://sandbox.bond.tech/api/v0/accounts");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Identity", "YOUR-IDENTITY");
request.AddHeader("Authorization", "YOUR-AUTHORIZATION");
request.AddParameter("application/json", "{\"type\":\"external\",\"link_type\":\"plaid\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"type\":\"external\",\"link_type\":\"plaid\"}");
Request request = new Request.Builder()
  .url("https://sandbox.bond.tech/api/v0/accounts")
  .post(body)
  .addHeader("Content-Type", "application/json")
  .addHeader("Identity", "YOUR-IDENTITY")
  .addHeader("Authorization", "YOUR-AUTHORIZATION")
  .build();

Response response = client.newCall(request).execute();

The following is an example of a successful 201 response.

{
    "account_id": "01f56a45-9b8c-4ccb-a4da-c122eef559a5",
    "date_created": "2022-12-15T14:29:02.941021+00:00",
    "date_updated": "2022-12-15T14:29:02.941027+00:00",
    "customer_id": "6f0e7dcb-6073-42df-bf02-ce71bd5fac3a",
    "status": null,
    "verification_status": null,
    "type": "external",
    "link_type": "bond",
    "link_token": "link-sandbox-329252b7-f0a6-4b3c-9746-190d43efadd1",
    "expiration": "2022-12-15T18:29:03Z"
}

The link_token is then provided to the Plaid Link SDK which initiates a prompt for the customer to begin the process to link their external bank account.

Exchanging tokens

After Plaid has verified the customer's bank information, the Plaid Link SDK will then return a public_token. This is a temporary token that is exchanged for an access_token by calling the POST /accounts/{account_id} endpoint, which takes a payload with the following variables:

FieldType
public_token
required
Public token provided by Plaid Link (public_token)
external_account_id
required
Account ID provided by Plaid Link (metadata.account_id)
'linked_account_id'
required
Bond's account UUID (36 characters) for the linked account.
status
required
Verification status of the external Plaid account.(metadata.account.verification_status)

Possible values are instantly_verified (Instant Auth), pending_automatic_verification (Automated Micro-Deposits), and pending_manual_verification (Same-Day Micro-Deposits).
curl --request POST \
  --url https://sandbox.bond.tech/api/v0/accounts/023zd49b-7432-229a-d396-134097b6c3f9/external_accounts/plaid \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"public_token": "public-sandbox-98ed91d9-7794-49e2-a397-279734e597ae", "external_account_id":"1gxb4pgQ8VcV7xanAxp1sxAAjNERA4iQ6w1Vm", "linked_account_id": "282b4dc8-9632-4b6d-8778-9dbce4c40fe0", "status": "instantly_verified"}'

The following is an example of a successful 200 response.

{
    "access_token": "access-sandbox-035d67aa-5d6b-4014-98af-e09b7335ea31",
    "status": "active",
    "account_type": "checking",
    "account_category": "depository"
}

Linking the external account to the card account

After creating an account that has been linked to the customer's external account, you need to create a link to the customer's card account (or a deposit account, in API v0.1), so that they can move funds between the accounts. Since we are moving funds from an external account to a customer card account, this is done by updating the customer's card account with a reference to the external account using the PATCH /api/v0/accounts/{card_account_id} endpoint, which takes a payload with the following variables:

FieldType
add_external_accounts
required
List of Bond account IDs corresponding to Bond accounts each having type="external".

An example of a request is shown below.

curl --request PATCH \
  --url https://sandbox.bond.tech/api/v0/accounts/0f02ad0f9-1945-4cbc-b1b7-0e96b0189842 \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"add_external_accounts": ["023zd49b-7432-229a-d396-134097b6c3f9"]}'

An example of a successful response is shown below.

    {
        "account_id": "f02ad0f9-1945-4cbc-b1b7-0e96b0189842",
        "type": "card",
        "status": "active",
        "card_id": "01419e9c-e368-4291-9d5d-d274d84bad31",
        "linked_accounts": [
          {
            "account_id":"023zd49b-7432-229a-d396-134097b6c3f9",
            "type": "external",
            "link_type": "plaid",
            "status": "active",
            "verification_status": "instantly_verified"
          }
        ]
    }

Microdeposits

When a customer requests to link their account, Plaid Link may direct them to use manual micro-deposit verification. This flow involves the following steps:

  1. Generating a new Plaid Link token
  2. Reinitializing the Plaid Link SDK for the customer
  3. Updating the Bond account status to reflect the Plaid Link results

Generating a new Plaid Link token

A new Plaid Link token can be generated by making a request to the PATCH /accounts/{account_id} endpoint.

An example of a PATCH /accounts/{account_id} call for this purpose is shown below.

curl --request PATCH \
  --url https://sandbox.bond.tech/api/v0/accounts/023zd49b-7432-229a-d396-134097b6c3f9 \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"new_link_token": true}'

An example of a successful response is shown below.

{
    "account_id": "023zd49b-7432-229a-d396-134097b6c3f9",
    "type": "external",
    "link_type": "plaid",
    "status": "active",
    "verification_status": "instantly_verified",
    "link_token": "link-sandbox-0c77a4df-c9c3-4e54-a0a0-5d2c053ae9c0",
    "expiration": "2021-01-27T23:29:06Z"
}

Updating the Bond account status

After the micro-deposits are verified through Plaid Link, another request can be made to the PATCH /api/v0/accounts/{account_id} endpoint to supply the final verification_status. An example of a PATCH /api/v0/accounts/{account_id} call for this purpose is shown below:

curl --request PATCH \
  --url https://sandbox.bond.tech/api/v0/accounts/023zd49b-7432-229a-d396-134097b6c3f9 \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"new_link_token": false, "verification_status": "manually_verified"}'

Note that verification_status correspond to the metadata.account.verification_status value from the Plaid Link result.

Link an account without verification

If your customer wants to send funds from their card account to an external account that they do not own, you need to create a Bond account with type being "migrate_account". You need to provide bank information in the request.

📘

By default only card-to-account ACH transfers are available for "migrate_accounts". If a Brand wants to allow account-to-card ACH transfers as well, by managing Bank account verification themselves, they will need to reach out to support.

The POST /api/v0/accounts/migrate_account/plaid operation can be used to create a Bond account for this purpose.

This operation takes a payload with the following variables:

FieldType
account_number
required
Account number of the external account
routing_number
required
Routing number of the external account
bank_account_type
required
Account type of the external account (checking or savings)
bank_name
required
Name of the bank associated with the external account being linked

An example of a request is shown below.

curl --request POST \
  --url https://sandbox.bond.tech/api/v0/accounts/migrate_account/plaid \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{"account_number": "1111222233331111", "routing_number": "021000021", "bank_account_type": "checking", "bank_name": "Chase Bank"}'

An example of a successful request is shown below.

{
    "linked_account_id": "49abaa9b-d835-4d0e-a088-ccb0ef371e6b",
    "access_token": null,
    "status": "active",
    "verification_status": "unverifiable",
    "account_type": "savings",
    "account_category": "depository"
}

In order to be used for ACH transfers, after a successful migration, this external account needs to be linked to a card account as explained above.