Building commercial banking

A step-by-step guide to creating and using commercial deposit accounts

Overview

Commercial deposit accounts can be used to hold and manage funds for your business customers. Bond's APIs support the creation of commercial deposit accounts that can be used with ACH, external ACH, and instant transfers. In this guide, we will walk through how commercial deposit accounts can be created and used to move money and manage balances when your brand works with business customers.

Before creating a deposit account, the following prerequisites are recommended:

  1. Create API keys
  2. Find your program ID

In order to create a commercial deposit account, the following steps are required:

  1. [Create a business] (https://docs.bond.tech/docs/building-commercial-banking#step-1-create-a-business)
  2. Run KYC on Beneficial Owners
  3. Running KYB
  4. Create a deposit account

After creation, the deposit accounts can be used for money movement:

Deposit accounts also come with standard bookkeeping functionality, including:

Creating a Deposit Account

Prerequisite: Create API keys

In order to interact with the API endpoints on Bond's platform, a pair of Identity and Authorization API keys need to be supplied in the request headers. More information on creating API keys can be found on the following page: Getting your API key.

Prerequisite: Find your program ID

A program ID is a UUID value that represents a relationship between you and a bank, and is often associated one-to-one with a financial product. In this guide, our program ID will be affiliated with consumer debit accounts. You can find your program ID in Bond Portal under the Developers tab. For more information on what a program ID represents, please see Card program ID.

Step 1: Create a business

  • On Bond's platform, every one of your business customers that is issued a financial product must have an associated Business object. This business object stores important information including legal business name, type, address, beneficial owners, and employer identification number.

For the purposes of this guide, we will be onboarding an imaginary business named Acme Inc. based in San Francisco. To do this, we will need to create a business resource for Acme Inc.

An example of the business creation request for Acme Inc is provided below. For more information on the request and response schemas of the business creation API, please refer to the Create a business API reference.

curl --request POST \
  --url https://sandbox.bond.tech/api/v0.1/businesses/ \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{
  "ein": "12-1234567",
  "phone": "+14085557788",
  "email": "[email protected]",
  "website": "https://www.acme.tech",
  "legal_business_name": "Acme Inc.",
  "dba_business_name": "Acme Inc.",
  "business_type": "corporation",
  "addresses": [
    {
      "address_type": "MAILING",
      "street": "345 California Ave.",
      "street2": "Suite 600",
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "12345-1234",
      "country": "US",
      "is_primary": true
    },
    {
      "address_type": "PHYSICAL",
      "street": "123 California Ave.",
      "street2": "Suite 100",
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "12345-1234",
      "country": "US",
      "is_primary": false
    }
  ],
  "beneficial_owners": [
    {
      "first_name": "James",
      "last_name": "Bond",
      "dob": "1970-12-12",
      "addresses": [
        {
          "address_type": "MAILING",
          "street": "345 California Ave.",
          "street2": "Suite 600",
          "city": "San Francisco",
          "state": "CA",
          "zip_code": "12345-1234",
          "country": "US",
          "is_primary": true
        }
      ]
    }
  ]
}'

After sending the business creation request, we receive a successful response.

{
    "date_created": "2022-08-25T16:35:23.770199+00:00",
    "addresses": [
        {
            "date_created": "2022-08-25T16:35:23.775334+00:00",
            "address_id": "87c90c92-701f-423c-ab19-33c6043f9d2f",
            "address_type": "MAILING",
            "street": "345 California Ave.",
            "street2": "Suite 600",
            "city": "San Francisco",
            "state": "CA",
            "zip_code": "12345-1234",
            "country": "US",
            "is_primary": true,
            "deliverability": null
        },
        {
            "date_created": "2022-08-25T16:35:23.776317+00:00",
            "address_id": "f3d10c09-74c5-4a78-ba92-65a53f6757e4",
            "address_type": "PHYSICAL",
            "street": "123 California Ave.",
            "street2": "Suite 100",
            "city": "San Francisco",
            "state": "CA",
            "zip_code": "12345-1234",
            "country": "US",
            "is_primary": false,
            "deliverability": null
        }
    ],
    "beneficial_owners": [
        {
            "date_created": "2022-08-25T16:35:23.772728+00:00",
            "addresses": [
                {
                    "date_created": "2022-08-25T16:35:23.777525+00:00",
                    "address_id": "2339bd4c-a71e-4ddd-b0a0-58978b473ccb",
                    "address_type": "MAILING",
                    "street": "345 California Ave.",
                    "street2": "Suite 600",
                    "city": "San Francisco",
                    "state": "CA",
                    "zip_code": "12345-1234",
                    "country": "US",
                    "is_primary": true,
                    "deliverability": null
                }
            ],
            "beneficial_owner_id": "6578bd28-35dc-4b10-b1f5-3e9c655df7e6",
            "first_name": "James",
            "middle_name": null,
            "last_name": "Bond",
            "dob": "1970-12-12",
            "ssn": null,
            "phone": null,
            "email": null
        }
    ],
    "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
    "ein": "12-1234567",
    "legal_business_name": "Acme Inc.",
    "dba_business_name": "Acme Inc.",
    "business_type": "corporation",
    "date_established": null,
    "phone": "+14085557788",
    "email": "[email protected]",
    "website": "https://www.acme.tech"
}

In the response, we want to pay particular attention to the business_id UUID value b57ecb2f-659d-4bfe-a61d-ef56000226a6, which uniquely identifies the newly created business object.

Step 2: Run KYC on Beneficial Owners

After supplying Bond with initial information on your beneficial owners during business creation, the next step is to conduct KYC/AML checks in order to ensure that the beneficial owners are not flagged by any OFAC checks or other fraud prevention measures.

An example of a KYC initialization request for James Bond, the beneficial owner of Acme Inc., is provided below. For more information on the request and response schemas for the Beneficial Owner KYC initialization API, please refer to the Start KYC (Know-Your-Customer) API reference.

curl --request POST \
  --url https://sandbox.bond.tech/api/v0.1/businesses/b57ecb2f-659d-4bfe-a61d-ef56000226a6/beneficial_owners/6578bd28-35dc-4b10-b1f5-3e9c655df7e6/verification-kyc \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{
    "program_id": "YOUR-PROGRAM-ID",
    "ssn": "123-45-6789",
    "phone": "1234567890",
    "phone_country_code": "1",
    "email": "[email protected]",
    "ip": "127.0.0.1"
}'

Note that we have included the beneficial_owner_id value from the previous step in the URL of this KYC initialization request as a path parameter, and the program_id value in our request body.

A successful response to the Beneficial Owner KYC initialization request looks like:

{
    "customer_id": "6578bd28-35dc-4b10-b1f5-3e9c655df7e6",
    "kyc_status": "submitted"
}

The submitted state indicates that Bond's platform has successfully received the KYC request. After processing the KYC request, the status of the KYC will automatically update. The new state can be requested either via the Retrieve KYC Status endpoint or via a Webhooks subscription. More details on the relevant actions corresponding to each KYC status can be found at Verifying Beneficial Owners.

After the KYC status of the beneficial owner reaches passed, we are ready to progress to the next step.

Step 3: Running KYB

🚧

Requirement

Before running KYB, make sure that the business resource contains ein and phone values and that these are correct.

See Retrieving a business to view the ein and phone status, and Updating a business to modify them if necessary.

In order to create a deposit account, you will first have to validate the business customer in Bond through the Know-Your-Business (KYB) process. To start KYB, use the POST /businesses/{business_id}/verification-kyb operation with no further parameters.

The request to initiate a KYB process for our business ID b57ecb2f-659d-4bfe-a61d-ef56000226a6 is shown below:

curl --request POST \
  --url https://sandbox.bond.tech/api/v0.1/businesses/b57ecb2f-659d-4bfe-a61d-ef56000226a6/verification-kyb \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Identity: YOUR-IDENTITY'

When you initiate the KYB process, the KYB service responds with an initiated message similar to the one shown below:

{
    "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
    "kyb_status": "initiated"
}

The results of the KYB are sent via a webhook. You can also retrieve the KYB status using the Retrieve KYB Status call:

curl --request GET \
  --url https://sandbox.bond.tech/api/v0.1/businesses/b57ecb2f-659d-4bfe-a61d-ef56000226a6/verification-kyb \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Identity: YOUR-IDENTITY'

A successful response indicating that our business has passed KYB looks like the following:

{
   "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
   "kyb_status": "approved",
}

If you're using a webhook subscription to monitor KYB status, the webhook payload indicating the approved state is show below:

{
  "event": "kyb.verification.approved",
  "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
  "occurred_at": "2022-07-15T17:06:41.122010+00:00"
}

If the business fails the KYB check and they can't pass a manual check, you cannot issue them a deposit account.

For a complete specification and interactive examples, see Running KYB in the Bond API Reference.

Step 4: Create a deposit account

After the beneficial owners have passed KYC and the business has passed KYB, the business resource is now prepared for deposit account creation.

We will be using the Create an account API endpoint, which creates a deposit account.

For more information on the request and response schemas for the deposit account creation API, please refer to the Create an account API reference. An example of a commercial deposit account creation request, which we specify by passing in the business_id body parameter, is provided below.

curl --request POST 'https://api.bond.tech/api/v0.1/accounts' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \
--header 'Content-Type: application/json' \
--data-raw '{
  "program_id": "YOUR-PROGRAM-ID",
  "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
  "type": "deposit"
}'

A successful response to this request looks like:

{
    "account_id": "a90708df-72a5-4cc3-a497-e1ad27ccae46",
    "date_updated": "2022-04-22T17:07:03.034183+00:00",
    "date_created": "2022-04-22T17:07:03.034177+00:00",
    "program_id": "YOUR-PROGRAM-ID",
    "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
    "type": "deposit",
    "status": "active",
    "routing_number": "084101234",
    "account_number": "2834461234567890",
    "description": "deposit account",
    "balance": {
        "previous_statement_balance": 0,
        "available_balance": 0,
        "current_balance": 0,
        "currency": "USD"
    },
    "cards": []
}

The relevant values that we want to store are:

  • account_id: used for checking balance, getting transactions, and initiating both ACH and instant transfers
  • routing_number/account_number: used for initiating External ACH transfers.

Money Movement

ACH Transfers

ACH transfers can be initiated between a Bond commercial deposit account and an externally linked bank account using the Create a transfer API. For more information on how to link an external bank account, please refer to the Guide to linking external accounts.

An ACH transfer that moves $15.00 from our commercial deposit account to an external bank account looks like:

curl --location --request POST 'https://sandbox.bond.tech/api/v0.1/transfers' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \
--header 'Content-Type: application/json' \
--data-raw '{
    "origination_account_id": "a90708df-72a5-4cc3-a497-e1ad27ccae46",
    "account_id": "14920519-f4d8-4cb3-89a3-9161ed9887b4",
    "description": "simple transfer",
    "amount": 1500,
    "ach": {
          "class_code": "WEB",
          "same_day": true
     }
}'

Similarly, an ACH transfer that moves $20.00 from an external bank account to the commercial deposit account looks like:

curl --location --request POST 'https://sandbox.bond.tech/api/v0.1/transfers' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \
--header 'Content-Type: application/json' \
--data-raw '{
    "origination_account_id": "14920519-f4d8-4cb3-89a3-9161ed9887b4",
    "account_id": "a90708df-72a5-4cc3-a497-e1ad27ccae46",
    "description": "withdrawal",
    "amount": 2000,
    "ach": {
          "class_code": "WEB",
          "same_day": true
     }
}'

In order to initiate an ACH transfer from another financial institution, simply use the saved routing_number and the account_number in the relevant processes from the other party.

For more information on transfers, please refer to Creating a transfer.

Instant Transfers

To create a $300.00 internal transfer between our commercial deposit account and another of your deposit accounts, the request would look like:

curl --request POST 'https://api.bond.tech/api/v0.1/transfers' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \
--header 'Content-Type: application/json' \
--data-raw '{
  "origination_account_id": "a90708df-72a5-4cc3-a497-e1ad27ccae46",
  "destination_account_id": "225641a5-f6e4-4ae1-b5e0-326e6b98842e",
  "description": "team repayment",
  "amount": 30000
}'

Recurring Transfers

Recurring transfers that are initiated on a regular basis can be easily implemented by calling the APIs associated with ACH transfers or instant transfers on a repeating schedule.

Bookkeeping

Balance view

To view the balance associated with the commercial deposit account, we can use the Get account by id endpoint with the account_id value that we stored as a URL parameter. A sample balance view request for our commercial deposit account looks like:

curl --location --request GET 'https://sandbox.bond.tech/api/v0.1/accounts/a90708df-72a5-4cc3-a497-e1ad27ccae46' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \

A successful response will contain a balance object with balance information for the account:

{
  "account_id": "a90708df-72a5-4cc3-a497-e1ad27ccae46",
  "date_updated": "2020-08-16T19:39:34Z",
  "date_created": "2020-08-15T19:39:34Z",
  "program_id": "YOUR-PROGRAM-ID",
  "business_id": "b57ecb2f-659d-4bfe-a61d-ef56000226a6",
  "type": "deposit",
  "status": "active",
  "description": "commercial deposit account #1",
  "routing_number": "547897762",
  "account_number": "574771265",
  "balance": {
    "current_balance": 1000000,
    "available_balance": 1000000,
    "previous_statement_balance": 987100,
    "locked_balance": 0,
    "currency": "USD"
  },
  "cards": [
    "7c45101a-82de-49e5-b01d-50151b54312d"
  ],
  "deposit": {}
}

Transfers view

To view the transfers associated with the commercial deposit account, we can use the Get transactions endpoint with the account_id value that we stored as a query parameter. The transfers view request for the account looks like:

curl --location --request GET 'https://sandbox.bond.tech/api/v0.1/transactions?account_id=a90708df-72a5-4cc3-a497-e1ad27ccae46' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION'

You may also use additional query parameters such as payment_type, start_date, and end_date to further filter your list of transfers, as well as page and count for paginated results.