Verifying Bank Account Information (via Plaid)

📘

You might not need this page...

If you're using the Invite a Company workflow to have your vendors and customers enter their own banking information, you will not need to perform any of the steps in this article. This document provides guidance on ways to validate banking information if you wish to collect it in your own application.

Verifying Bank Information

If you wish to collect bank account numbers and routing numbers within your own application, you will probably want to validate that those accounts are valid. You don't want to pay the wrong people, and you don't want to pay fees for failed transactions.

There are two ways to integrate validation of banking information into a collection workflow - using Plaid, and using a micro-deposit.

Using Plaid

Plaid is the most recognized solution provider for bank account validation in the world. They provide a simple Link interface that you can embed directly into your application. This is by far the easiest way to verify banking information, however, not every bank's accounts are compatible with Plaid, so you may also need to support micro-deposits as a fallback method. In addition to account validation, you can also use Plaid to do things like validate account balances.

First, you'll need a Plaid developer account. Once you've created an account, you will embed the Plaid Link interface in your application.

748

Plaid Link's user interface

When the user completes Link, you will receive a public_token back from it. Pass this public token to Plaid's item token exchange endpoint to receive an access_token. This is an identifier for the bank account that was confirmed with Plaid, however, Routable can't do anything with that value as it is internal to Plaid. We'll need to exchange it for the actual bank account details.

Take your newly-minted access_token and pass it to the Plaid Auth endpoint. This will return a response containing, among other data, the routing and account numbers for the bank account(s) validated in Plaid.

{
  "accounts": [
    {
      "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
      "balances": {
        "available": 100,
        "current": 110,
        "limit": null,
        "iso_currency_code": "USD",
        "unofficial_currency_code": null
      },
      "mask": "9606",
      "name": "Plaid Checking",
      "official_name": "Plaid Gold Checking",
      "subtype": "checking",
      "type": "depository"
    }
  ],
  "numbers": {
    "ach": [
      {
        "account": "9900009606",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "routing": "011401533",
        "wire_routing": "021000021"
      }
    ],
    "eft": [
      {
        "account": "111122223333",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "institution": "021",
        "branch": "01140"
      }
    ],
    "international": [
      {
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "bic": "NWBKGB21",
        "iban": "GB29NWBK60161331926819"
      }
    ],
    "bacs": [
      {
        "account": "31926819",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "sort_code": "601613"
      }
    ]
  },
  "item": {
    "available_products": [
      "balance",
      "identity",
      "payment_initiation",
      "transactions"
    ],
    "billed_products": [
      "assets",
      "auth"
    ],
    "consent_expiration_time": null,
    "error": null,
    "institution_id": "ins_117650",
    "item_id": "DWVAAPWq4RHGlEaNyGKRTAnPLaEmo8Cvq7na6",
    "update_type": "background",
    "webhook": "https://www.genericwebhookurl.com/webhook"
  },
  "request_id": "m8MDnv9okwxFNBV"
}

A sample response from Plaid's /auth/get endpoint. Note the numbers object containing the banking information.

If any of the steps above fail, the user has provided invalid banking information. If you receive an account and routing in the numbers object within Plaid's /auth/get response, the bank information is valid and can be submitted confidently to Routable.

Finally, use the Create a Payment Method endpoint of Routable's API, and provide the account and routing values from the Plaid response. You'll also need the account type, which you can find in the subtype property under accounts in the response.

That's it! You've got a validated account set up for your vendor!

Using a Micro-deposit

Some bank accounts, often those from smaller regional banks, cannot be validated with Plaid. For these accounts, you may wish to implement micro-deposits to validate a bank account. This involves sending a very small payment to the account with a random amount, and then having the account owner confirm the amounts you sent. You can think of it like sending a confirmation code for two-factor authentication, but through a bank account.

To do this, you will first need to create a form to collect the account_number, routing_number and account_type from your vendor in your application. We'll submit this to Routable's Create a Payment Method endpoint.

Next, you'll send a tiny Payable to that account. Choose a random amount between 1 cent and 10 cents USD. Record the amount that was sent to the account along with the Routable Payment Method ID that you got when you created the account. You won't be charged a fee from Routable to send this payment.

If both the Create a Payment Method and the Create a Payable calls succeed, then the bank account information is valid, but we still haven't validated that your user is in fact the owner of that account. To do this, we need one more step.

Create a form to allow the user to select their pending payment method and enter the amount of the Payable you sent. If it matches what you sent, then the user has been able to see it in their bank account, and you have confirmed that the user has access to that account and can now trust the account to send and receive payments from that company.