Building consumer banking

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

Overview

Deposit accounts are foundational building blocks that can be used to hold and manage funds for your customers. Bond's APIs support the creation of consumer deposit accounts that can be used with ACH, external ACH, and instant transfers. In this guide, we will walk through how consumer deposit accounts can be created and used to move money and manage balances.

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

  1. Create API keys
  2. Find your program ID

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

  1. [Create a customer] (https://docs.bond.tech/docs/building-deposit-accounts#step-1-create-a-customer)
  2. Run KYC
  3. Create a deposit account

After creation, 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 customer

On Bond's platform, every one of your consumers that is issued a financial product must have an associated Customer object. This customer object stores important information on the consumer, including name, address, and other sensitive information that is required for regulatory purposes.

For the purposes of this guide, we will be onboarding an imaginary consumer named Christine Smith who lives at Bond HQ. An example of the customer creation request for Christine is provided below. For more information on the request and response schemas of the customer creation API, please refer to the Create a customer API reference.

curl --request POST \
  --url https://sandbox.bond.tech/api/v0.1/customers/ \
  --header 'Identity: YOUR-IDENTITY' \
  --header 'Authorization: YOUR-AUTHORIZATION' \
  --header 'Content-Type: application/json' \
  --data '{
    "brand_person_id": "YOUR-INTERNAL-USER-ID",
    "dob":"1999-12-25",
    "last_name":"Smith",
    "first_name":"Christine",
    "addresses":[
      {
        "address_type":"PHYSICAL",
        "street":"345 California Ave.",
        "street2": "Suite 600",
        "city": "San Francisco",
        "state": "CA",
        "zip_code": "12345-1234",
        "country": "US",
        "is_primary": true
      }
    ]
  }'

Note that the brand_person_id field is provided in case you want to include a unique UUID to help associate between Bond's customer ID and your own internal user ID. For our purposes, we will pass a random UUID 6723febc-61e5-4aed-9f83-f7f1e0f1b6bc.

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

{
    "customer_id": "ee268265-1f29-4603-a958-a9b0ab7ce573",
    "bond_brand_id": "abaa2147-4533-4ec7-a9f6-bd88a988ecd1",
    "brand_person_id": "6723febc-61e5-4aed-9f83-f7f1e0f1b6bc",
    "date_created": "2022-04-19T22:02:16.062792+00:00",
    "dob": "1999-12-25",
    "first_name": "Christine",
    "middle_name": "",
    "last_name": "Smith",
    "kyc_requests_available": 3,
    "addresses": [
        {
            "address_id": "d172892e-49ef-4af5-9925-cf626371efba",
            "address_type":"PHYSICAL",
            "street":"345 California Ave.",
            "street2": "Suite 600",
            "city": "San Francisco",
            "state": "CA",
            "zip_code": "12345-1234",
            "country": "US",
            "is_primary": true
            "deliverability": "undeliverable",
            "date_created": "2022-04-19T22:02:16.065774+00:00"
        }
    ],
    "business_id": null
}

In the response, we want to pay particular attention to the customer_id UUID value ee268265-1f29-4603-a958-a9b0ab7ce573 which uniquely identifies the newly created customer object associated with Christine.

Step 2: Run KYC

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

An example of a KYC initialization request for Christine is provided below. For more information on the request and response schemas for the 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/customers/ee268265-1f29-4603-a958-a9b0ab7ce573/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 customer_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 KYC initialization request looks like:

{
    "customer_id": "ee268265-1f29-4603-a958-a9b0ab7ce573",
    "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 Running KYC.

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

Step 3: Create a deposit account

After executing the appropriate follow-up steps when running the KYC, the customer object is now prepared for deposit account creation. We will be using the Create an account API endpoint, which creates a deposit account.

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

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",
  "customer_id": "ee268265-1f29-4603-a958-a9b0ab7ce573",
  "type": "deposit"
}'

A successful response to the deposit account creation 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",
    "customer_id": "ee268265-1f29-4603-a958-a9b0ab7ce573",
    "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.

At this point, we've successfully created a deposit account for Christine! Next, let's see how we can enable Christine to interact with her deposit account.

Money Movement

ACH Transfers

ACH transfers can be initiated between a Bond 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 Christine's Bond 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": "f5425ea7-ec5e-4873-b3ed-a3e862f27d2a",
    "account_id": "14920519-f4d8-4cb3-89a3-9161ed9887b4",
    "type": "ach",
    "ach_class_code": "WEB",
    "amount": "15.00",
    "ach_direction": "credit",
    "ach_network": "ach",
    "ach_description": "christine's withdrawal"
}'

Similarly, an ACH transfer that moves $20.00 from an external bank account to Christine's Bond 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": "f5425ea7-ec5e-4873-b3ed-a3e862f27d2a",
    "account_id": "14920519-f4d8-4cb3-89a3-9161ed9887b4",
    "type": "ach",
    "ach_class_code": "WEB",
    "amount": "20.00",
    "ach_direction": "debit",
    "ach_network": "ach",
    "ach_description": "christine's deposit"
}'

Note that the origination_account_id value remains Christine's deposit account ID for both transfers. In order to determine the direction of the ACH transfer, the ach_direction parameter changes between debit and credit. For more information on ACH transfers and ach_direction, please refer to ACH transfers.

External ACH Transfers

In order to initiate an ACH transfer from another financial institution, simply use the saved sponsor_bank_routing_number and the pseudo_dda as the routing number and account number.

Instant Transfers

Instant transfers can be initialized between two Bond deposit accounts using the Create a transfer API. An instant transfer that moves $25.00 from another deposit account to Christine's 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": "bfd2730a-490c-4ac2-af95-d828500a3b45",
    "account_id": "f5425ea7-ec5e-4873-b3ed-a3e862f27d2a",
    "type": "card-to-card",
    "amount": "25.00",
    "memo": "Wow, so fast!"
}'

Note that for an instant transfer, the funds always move from the origination_account_id (here that is bfd2730a-490c-4ac2-af95-d828500a3b45) to the account_id (here that is f5425ea7-ec5e-4873-b3ed-a3e862f27d2a). This is in contrast to the ACH transfers, which depends on the ach_direction parameter to determine which way the funds move between the two account IDs.

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 deposit account, we can use the Get account balance by id endpoint with the card_account_id value that we stored as a URL parameter. The balance view request for Christine's deposit account looks like:

curl --location --request GET 'https://sandbox.bond.tech/api/v0.1/balances/f5425ea7-ec5e-4873-b3ed-a3e862f27d2a' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION' \

Transfers view

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

curl --location --request GET 'https://sandbox.bond.tech/api/v0.1/transactions?account_id=f5425ea7-ec5e-4873-b3ed-a3e862f27d2a' \
--header 'Identity: YOUR-IDENTITY' \
--header 'Authorization: YOUR-AUTHORIZATION'