Banking transactions in a list

Overview

A transactions page provides a simplified accounting view of a user’s accounts mixed in with their accounting data. It can provide a bank-like interface for users to perform simple accounting tasks such as viewing, categorizing, and reviewing a single account’s worth of information.

A transaction page should allow the user to:

  • Select an account to view.
  • List the transactions to that account in chronologial order.
  • See the category of the transaction.

Optionally, you can also use this page to review transactions.

How it works

After a transaction has been posted to a financial account, it is processed by your bank integration, Plaid or Unit, for example. Your data integration imports the transaction into Teal where it goes through our transaction submission pipeline and is categorized.

A journal entry is created for the transaction, with one line entry recorded to the financial account ledger and the other to the ledger it was categorized as. The Transactions endpoints allow you to access all Transactions for a given financial account.

It’s important to understand that a Transaction in Teal is an abstraction of a the journal entry and line entry created by the transaction submission pipeline:

  • The Transaction’s description is the same as the parent journal entry’s.
  • The Transaction’s category is the ledger of the opposing line entry. Consequently, recategorizing a Transaction changes the ledger of the opposing line entry. A Transaction’s line entry can never be moved out of its financial account ledger.
  • A Transaction’s amount is the same as the line entry in the financial account ledger.
  • For a Transaction to have multiple categories, you must create multiple line entries in the journal entry.

Further, a Transactions page is similar to a ledger statement for a financial account ledger, with the key difference being that a ledger statement can include non-transaction journal entries such as adjustments.


Prerequisites

You can build a transaction page for any Instance, provided their financial accounts are mapped to ledgers and you are creating transactions, manually or via a data-integration.


Steps

1. Get financial account ledgers

To retrieve an Instance’s Transactions, we need to first get all financial account ledgers. Use the /v0/ledgers/ endpoint and filter the results to ledgers whose financial_account_type is not null.

Map the result into a <select> element to allow the user to select which account they want to see transactions from.


const TransactionsPage = () => {
    const options = {
        method: 'GET',
        headers: {
            Authorization: AUTHORIZATION_KEY,
            'teal-instance-id': TEAL_INSTANCE_ID
        }
    }

    const ledgersRequest = await fetch(
        'https://api.sandbox.teal.dev/v0/ledgers/',
        options
    );

    const ledgersData = await request.json();

    const financialAccountLedgers: Ledger[] = request.records.filter(ledger =>
        ledger.financial_account_type !== null
    );

    return (
        <main>
            <label for="ledger-select">Select a ledger</label>
            <select id="ledger-select">
                {
                    financialAccountLedgers.map(ledger => (
                        <option key={ledger.id}>{ledger.name}</option>
                    ))
                }
            </select>
        </main>
    )
}


2. Display the Transactions

Use /v0/ledgers/{ledger_id}/transactions with the selected Ledger id as the ledger_id parameter. Use the records attribute from the response to display the transaction data to the user.

const TransactionsPage = () => {

    // ...

    const [select, selectedId] = useState();

    const options = {
        method: 'GET',
        headers: {
            Authorization: AUTHORIZATION_KEY,
            'teal-instance-id': TEAL_INSTANCE_ID
        }
    }

    const transactionsRequest = await fetch(
            `https://api.sandbox.teal.dev/v0/ledgers/${selectedId}/transactions`,
            options
        );

    const transactionsData = await request.json();

    const { records }: BankTransaction[] = transactionsData

    return (
        <main>
            { /** ... */ }

            {
                records.map(transaction => {
                    return (
                        <div key={transaction.id}>
                            {transaction.description}
                        </div>
                    )
                })
            }
        </main>
    )
}

Your transaction component should, at a minimum, display the description, amount, and date of the transaction. If you want to include additional information about the category or related line entry (or entries), you can expand the request /v0/ledgers/{ledger_id}/transactions?expand=ledger,opposing_line_entries to get the required information.

If you are building a separate transaction review section, you can display only reviewed transactions by calling /v0/ledgers/{ledger_id}/transactions?review_status=reviewed instead.


3. Further enhancements and considerations

Depending on your use case, consider adding features such as date filters, tagging, or categorization reviewing.


Best practices

  • Only display one account’s Transactions at a time. This helps prevent confusion when reviewing transactions.
  • Use pagination to keep your application fast and performant or virtualized lists for an infinite scroll experience.
  • Be aware of the differences between credit accounts and debit accounts and how you represent transaction amounts of each to users. Money spent from debit accounts is negative (money is leaving the account), whereas money spent on credit accounts is positive (credit is accruing on the account).
  • Think about how you want to display accounting data such as categories or tags alongside banking data. Ensure there is a clear hierarchy of information.
  • Keep the focus of the page on displaying the account’s transaction data. If you need to perform complex accounting actions, such as splitting a journal entry, use a modal or navigate the user to a new screen.

Relevant resources

Guides

API references