Building Statements

A step-by-step guide to creating compliant statements

Overview

Bond provides APIs that allows you to create compliant statements for your end users with ease. In this guide, you'll learn how to use Bond's APIs and statement templates to build and customize statements for your users.

To create statements for your users, you will need to:

  1. Gather the data needed for your statements
  2. Get the appropriate statement disclosures from Bond's Operations and Compliance team
  3. Build a template
  4. Substitute values into the template

Once these steps have been completed, you'll have compliant statements ready to distribute to your end users.

Get statement data

To construct a statement, you will need the statement data for the billing month, as well as customer information to print on the statement. For this, you'll need to make the following API calls:

We'll reference the response to this API call as statement_response. The statement_response will depend on the account type (deposit or credit), as shown below:

{
  "statement_id": "c11fc6d8-9865-45b7-b3de-583257abe33e",
  "account_id": "654dc482-96f9-4012-b2e3-fb73a5a17c97",
  "statement_month": "2022-02",
  "type": "deposit",
  "statement_start_date": "2022-01-21",
  "statement_end_date": "2022-02-20",
  "fees": 0,
  "transactions": [
    {
      "transaction_id": "cea15fcb-48dd-4c3d-a0d5-564ea360c6c9",
      "transaction_date": "2022-02-13",
      "settled_date": "2022-02-13",
      "amount": 1458,
      "transaction_description": "atm fee",
      "transaction_type": "Fee"
    }
  ],
  "deposit": {
    "beginning_balance": 1000057,
    "withdrawals": 20057,
    "deposits": 325000,
    "ending_balance": 1305000
  }
}
{
  "statement_id": "38677cf1-6f3f-4c5b-96dc-77d0bc724eda",
  "account_id": "654dc482-96f9-4012-b2e3-fb73a5a17c97",
  "statement_month": "2022-02",
  "type": "credit",
  "statement_start_date": "2022-01-21",
  "statement_end_date": "2022-02-20",
  "fees": 0,
  "transactions": [
    {
      "transaction_id": "c6671a52-f942-4a3b-99ce-d98496c1f6d3",
      "transaction_date": "2022-02-13",
      "settled_date": "2022-02-13",
      "amount": 1458,
      "transaction_description": "Amazon LLC",
      "transaction_type": "Purchase"
    }
  ],
  "credit": {
    "payment_due_date": "2022-03-15",
    "previous_balance": 78515,
    "new_balance": 850,
    "available_credit": 150,
    "credit_limit": 1000,
    "minimum_payment_due": 35,
    "interest_charged": 0,
    "purchases": 850,
    "payments_and_credits": 247
  }
}

We'll reference the response to this API call as customer_response. A sample customer_response is shown below:

{
  "customer_id": "8559dec0-2edb-4c3c-a3c5-32de10174c34",
  "brand_person_id": "7b18da9e-0217-4ecb-8454-8c0ab8bedc14",
  "bond_brand_id": "e2b37ab8-5e6e-4538-bbe0-35121b481845",
  "date_created": "2020-10-26T21:48:57.287919",
  "dob": "1997-12-25",
  "first_name": "James",
  "middle_name": "Herbert",
  "last_name": "Bond",
  "ssn": "XXX-XX-6789",
  "phone": "650-123-4567",
  "email": "[email protected]",
  "kyc_requests_available": 3,
  "addresses": [
    {
      "address_id": "9e8241d2-ac5e-41c6-8b38-b3fe44387266",
      "address_type": "PHYSICAL",
      "street": "345 California St.",
      "street2": "Suite 600",
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "94104-2657",
      "country": "US",
      "is_primary": true,
      "deliverability": "deliverable",
      "date_created": "2020-10-26T21:48:57.287919"
    },
    {
      "address_id": "242c459e-6bd5-4158-89ee-550f0bdd133d",
      "address_type": "MAILING",
      "street": "111 Lake Tahoe Rd.",
      "street2": "",
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "12345",
      "country": "US",
      "is_primary": false,
      "deliverability": "undeliverable",
      "date_created": "2020-10-26T21:48:57.287919"
    }
  ]
}

We'll reference the response to this API call as account_response. The account_response will depend on the account type, as shown below:

{
  "account_id": "057c6074-a02d-4a5a-bad9-bbc64b047df7",
  "date_updated": "2020-08-16T19:39:34Z",
  "date_created": "2020-08-15T19:39:34Z",
  "program_id": "e242686d-3bb7-4543-8438-0aa682e14696",
  "customer_id": "1114ae62-5fe1-4b21-b4fb-f2b158d8e21e",
  "type": "deposit",
  "status": "active",
  "description": "string",
  "routing_number": "547897762",
  "account_number": "574771265",
  "balance": {
    "current_balance": 1000,
    "available_balance": 950,
    "previous_statement_balance": 17312,
    "currency": "USD"
  },
  "cards": [
    "7c45101a-82de-49e5-b01d-50151b54312d"
  ],
  "deposit": {}
}
{
  "account_id": "057c6074-a02d-4a5a-bad9-bbc64b047df7",
  "date_updated": "2020-08-16T19:39:34Z",
  "date_created": "2020-08-15T19:39:34Z",
  "customer_id": "1114ae62-5fe1-4b21-b4fb-f2b158d8e21e",
  "type": "credit",
  "status": "active",
  "balance": {
    "current_balance": 45412,
    "available_balance": 48312,
    "previous_statement_balance": 17312,
    "currency": "USD"
  },
  "program_id": "232e9951-e03a-47b2-9c9a-64ec0c02b69f",
  "description": "",
  "routing_number": "547897762",
  "account_number": "574771265",
  "cards": [
    "5145b38c-2d63-46be-bb68-3815d50ae4a6"
  ],
  "credit": {
    "credit_limit": 1000,
    "security_deposit_account_id": "3abc7efb-5827-48bb-8931-be6fe08f905c",
    "statement": {
      "close_date": "2020-08-05",
      "balance": 187575
    },
    "apr": {
      "purchase": 11.99,
      "cash_advance": 19.99,
      "penalty": 2.99,
      "balance_transfer": 14.99
    },
    "payment": {
      "due_date": "2020-08-05",
      "minimum_payment_percent": 9.99,
      "minimun_payment": 35
    }
  }
}
{
  "account_id": "057c6074-a02d-4a5a-bad9-bbc64b047df7",
  "date_updated": "2020-08-16T19:39:34Z",
  "date_created": "2020-08-15T19:39:34Z",
  "customer_id": "1114ae62-5fe1-4b21-b4fb-f2b158d8e21e",
  "type": "credit",
  "status": "active",
  "balance": {
    "current_balance": 45412,
    "available_balance": 48312,
    "previous_statement_balance": 17312,
    "currency": "USD"
  },
  "program_id": "232e9951-e03a-47b2-9c9a-64ec0c02b69f",
  "description": "",
  "routing_number": "547897762",
  "account_number": "574771265",
  "cards": [
    "5145b38c-2d63-46be-bb68-3815d50ae4a6"
  ],
  "credit": {
    "credit_limit": 1000,
    "security_deposit_account_id": "3abc7efb-5827-48bb-8931-be6fe08f905c",
    "statement": {
      "close_date": "2020-08-05",
      "balance": 187575
    },
    "apr": {
      "purchase": 11.99,
      "cash_advance": 19.99,
      "penalty": 2.99,
      "balance_transfer": 14.99
    },
    "payment": {
      "due_date": "2020-08-05",
      "minimum_payment_percent": 9.99,
      "minimun_payment": 35
    }
  }
}

Note: if you are making bulk API calls to our services at the end of a month to create statements for all your users, you will need to limit your request frequency in order to avoid being rate-limited by our APIs.

Bond's global rate limit across all your API calls is 1000 API calls per minute, so you should aim to stay very well below that as you're executing bulk API requests to pull data for statements.

Get disclosures

Statements for consumer programs are required to contain certain disclosures to inform your users of specific rights. Depending on your program, your disclosures may be different. Contact your Bond operations point-of-contact to get the relevant disclosures for your program.

Build a template

By providing you with the data you need to create your statements, Bond allows you to customize and style your statements to match the branding of your product.

However, we encourage you to start with the example HTML templates below, so that you can ensure that it fits the basic structure that is expected from compliant statements.

Here is a sample credit account statement template:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Monthly Account Statement</title>
  </head>
  <body>
    <h1>Monthly Account Statement</h1>
    <h2>Account Summary</h2>
    <p>$customer_name</p>
    <p>$customer_address</p>
    <h4>Summary of Account Activity</h4>
    <p>Previous balance: $previous_balance</p>
    <p>Payments and Credits: $payments_and_credits</p>
    <p>Purchases: $purchases</p>
    <p>Fees: $fees</p>
    <p>New balance as of $end_date: $new_balance</p>
    <h4>Credit Limit</h4>
    <p>Credit Limit: $credit_limit</p>
    <p>Available Credit: $available_credit</p>
    <p>Statement Start Date: $start_date</p>
    <p>Statement Closing Date: $end_date</p>
    <h4>Payment Information</h4>
    <p>New balance as of $end_date: $new_balance</p>
    <p>Payment Due: $payment_due</p>
    <p>Payment Due Date: $payment_due_date</p>
    <p><b>Late Payment Warning</b>: If we do not receive your payment by the date listed above, you may have to pay a late fee of up to $late_fee</p>
    <h4>Questions?</h4>
    <p>Call Customer Service: $customer_service_number</p>
    <p>Lost or Stolen Credit Card: $lost_stolen_number</p>
    <hr> 
    <p>$bank_address</p>
    <p>Account Number: $account_number</p>
    <p>New Balance: $new_balance</p>
    <p>Minimum Payment Due: $new_balance</p>
    <p>Payment Due Date: $payment_due_date</p>
    <p>AMOUNT ENCLOSED: </p>
    <div style='border: 1px solid #000; padding: 20px'></div>
    <p>Please send billing inquiries and correspondence to: $billing_inquiry_address </p>
    <h4>Your rights</h4>
    INSERT YOUR RIGHTS SECTION
    <hr> 
    <p>Billing period: $start_date - $end_date</p>
    <table>
      <tr>
        <th>Transactions</th>
      </tr>
      <tr>
        <th>Transaction Date</th>
        <th>Posted Date</th> 
        <th>Description</th>
        <th>Amount</th>
      </tr>
      $transaction_rows
    </table>
  </body>
</html>

And here is a sample deposit account statement template:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Monthly Account Statement</title>
  </head>
  <body>
    <h1>Monthly Account Statement</h1>
    <h2>Account Summary</h2>
    <p>$customer_name</p>
    <p>$customer_address</p>
    <h4>Summary of Account Activity</h4>
    <p>Previous balance: $previous_balance</p>
    <p>Payments and Credits: $payments_and_credits</p>
    <p>Fees: $fees</p>
    <p>New balance as of $end_date: $new_balance</p>
    <h4>Questions?</h4>
    <p>Call Customer Service: $customer_service_number</p>
    <hr> 
    <p>Please send billing inquiries and correspondence to: $billing_inquiry_address </p>
    <h4>Your rights</h4>
    INSERT YOUR RIGHTS SECTION
    <hr> 
    <p>Statement period: $start_date - $end_date</p>
    <table>
      <tr>
        <th>Transactions</th>
      </tr>
      <tr>
        <th>Transaction Date</th>
        <th>Posted Date</th> 
        <th>Description</th>
        <th>Amount</th>
      </tr>
      $transaction_rows
    </table>
  </body>
</html>

Substitute values into your template

Once you've selected a statement template, you can substitute values into the template using the data you retrieved earlier.

In addition to the data you retrieved earlier in statement_response, customer_response, and account_response, there are also the following static values common across all statements:

  • customer_service_number: The general customer service number end-users should use for your program
  • lost_stolen_number: The number end-users should use for for lost/stolen cards

Below is a sample script that substitutes data into the statement template and converts it into a PDF.

Note: For security purposes, the script below masks the account numbers provided in the account_response before substitution into the HTML statement template. It is important to ensure this for every statement, as /accounts API responses use full account numbers.

from string import Template

template = t = Template(template_str)
statement_str = t.substitute(
    previous_balance=statement_response['data'][0]['credit']['previous_balance'],
    payments_and_credits=statement_response['data'][0]['credit']['payments_and_credits'],
    purchases=statement_response['data'][0]['credit']['purchases'],
    fees=statement_response['data'][0]['fees'],
    start_date=statement_response['data'][0]['statement_start_date'],
    end_date=statement_response['data'][0]['statement_end_date'],
    new_balance=statement_response['data'][0]['credit']['new_balance'],
    credit_limit=statement_response['data'][0]['credit']['credit_limit'],
    available_credit=statement_response['data'][0]['credit']['available_credit'],
    payment_due=statement_response['data'][0]['credit']['new_balance'],
    payment_due_date=statement_response['data'][0]['credit']['payment_due_date'],
  	account_number=f'XXXXXXXXXXX{account_response['data'][0]['account_number'][:-4]}'
    late_fee=your_late_fee,
    customer_service_number=customer_service_number,
    lost_stolen_number=lost_stolen_number,
    bank_address=bank_address.replace('\n', '<br/>'),
    billing_inquiry_address=billing_inquiry_address,
    transaction_rows=''.join([f'''<tr>
        <td>{tx['transaction_date']}</td>
        <td>{tx['settled_date']}</td>
        <td>{tx['transaction_description']}</td>
        <td>{tx['amount']}</td>
    </tr>''' for tx in statement_response['data'][0]['transactions']])
)

import pdfkit
pdfkit.from_string(statement,'example_statement.pdf')

Distribute your statement

Once the statement PDF has been constructed, you can deliver it via email after the close date of the payment period is completed.