Journal

Accounting for Developers, Part III: Building a Lending Marketplace

In this final part of our Accounting for Developers series, we explore the ins and outs of building a ledger to power a lending marketplace product.

Image of Lucas Rocha
Lucas RochaProduct Manager

Updated August 14, 2025.

Introduction

In the first two parts of our Accounting for Developers series, we covered foundational accounting principles (Part I) and applied them to a Venmo-style wallet app (Part II).

Now, we’ll walk through how to design a double-entry ledger for a lending marketplace, akin to Lending Club, using a simplified version of a consumer platform we’ll call Modern Lending. These concepts apply to most lending ledger systems, including P2P platforms, embedded lenders, and credit fintech apps.

Who This Guide is For

This guide is ideal for engineers building or scaling products that feature a lending component. Whether you're supporting investor returns, loan disbursements, or repayment flows, double-entry accounting is your best tool for ensuring correctness and traceability at scale.

Double-entry:

  • Prevents funds from being created or destroyed
  • Ensures balances are always accurate
  • Provides a clear snapshot of uses and sources for each transaction, which is useful for reporting

Using double-entry constraints in database development is a best practice for fintechs and other companies that move money (read more about this in How And Why Homegrown Ledgers Break).

A Quick Refresher on Double-Entry

As a reminder, obeying double-entry accounting rules boils down to following these principles:

  • Your ledger should be composed of accounts and transactions
  • Accounts represent the balances your ledger will track; they can be classified as debit normal or credit normal
  • Transactions represent business events that have a monetary impact
    • They are composed of at least two entries
    • Entries can be on the debit side or credit side
  • The aggregate balance of all credit normal accounts and all debit normal accounts in a ledger should net to zero (credits = debits).

(For more on these concepts, revisit Part I of our series.)

Building Modern Lending, Step 1: Lending Use Case Overview

Our fictional lending platform, Modern Lending, is a peer-to-peer lending marketplace where individuals can set their risk preferences, accept interest rates, and invest directly on the platform.

Modern Lending then lends out the money to borrowers on the platform, adjusting the amount and interest rate based on their creditworthiness. Borrowers pay back their principal balance over time, and after repayments, Modern Lending returns capital to investors, plus interest.

Modern Lending recognizes (books) the spread between the interest it gets paid by borrowers and the interest it pays to investors as revenue.

Let's review the product requirements for this platform, acknowledging that users should be able to self-select as investors or borrowers during onboarding:

For investors:

  • During onboarding, they select their investing options, varying by term (when they get their money back) and interest rate (how much they get in return).
  • After onboarding, they deposit funds into Modern Lending's pooled cash account. This investment would be represented in their account as a balance.
  • At term maturity, they receive their principal back plus interest.

For borrowers:

  • During onboarding, they submit financial data (e.g., income) to determine creditworthiness.
  • They choose their loan option—varying by amount, term, and interest rate—and receive disbursement via wire, ACH, or RTP transfer.
  • They make monthly payments against their principal and interest balance, which would be represented in-app.

Additional product assumptions:

  • There are no transaction costs or fees.
  • We are building this application for scale—Modern Lending should be configured to handle thousands of investors and borrowers triggering disbursements and collections every day.
  • We would like to build our ledger flexibly to accommodate future product expansions.

This scenario creates technical requirements for a ledger that:

  • Logs transactions in real-time. For this, we will need a ledger API that embeds directly into our application code and writes into the ledger database as events happen. Modern Lending needs to parse financial transactions and translate how to write these in the ledger—we’ll call this translation service transaction handling logic.
  • Keeps balances up to date consistently and automatically. Transactions need to be parsed appropriately, aggregations need to be efficient, and balances need to be updated with minimal latency. They also need to be queryable to support transactions such as showing the user an updated balance after a transaction is completed. For this to be true, we need to map our chart of accounts to their given normality—a set of constraints that will help the ledger obey double-entry rules.
  • Accommodates a high volume of transactions and support programmatic expansion. In essence, this needs to be a central ledger that is divorced from fund movements (i.e., our underlying bank account setup) and is fully programmatic and flexible. The ledger’s functionality and underlying data models should not be tightly coupled to business logic.

Step 2: Understanding the Lending Data Flow

Before we start with the ledgering setup, it’s important for us to understand how data flows in a lending system. Modern Lending would need to implement the following services infrastructure alongside its ledger.

How Modern Lending's systems come together
How Modern Lending's systems come together

There are two kinds of data Modern Lending needs to keep track of:

  1. Historical data, or data that reliably represents the current financial state of Modern Lending based on posted transactions.
  2. Prospective data, specifically those that are defined by the business model: interest rates, loan terms, payment amounts, and the payment breakdown of interest versus principal.

Modern Lending will need to make use of an amortization schedule, a tool that calculates monthly payments based on interest rates, principal, and loan terms. Lending businesses often front-load a larger percentage of a customer’s payments towards interest versus principal. An internal service on Modern Lending’s backend can track this data and modify outputs based on new inputs (i.e., new loan terms).

The ledger database acts in tandem with the amortization schedule as the source of truth for historical information. Every time the amortization schedule service needs to provide an updated view of current balances, it cross-references the amortization schedule with the ledger database to provide accurate data.

Keeping historical information in the ledger and the amortization schedule outside of the ledger keeps Modern Lending’s data store clean and referencable over the course of the lifetime of the loan.

Notice that the ledger also needs to interact with another service divorced from the underlying ledger: payments and reconciliation logic. This service represents Modern Lending’s payment processor of choice: this can be a card processor or Modern Treasury Payments API. Transactions come in as webhooks and get parsed as ledger-compatible entries according to the rules presented below.

Step 3: Building A Chart Of Accounts for Lending

A chart of accounts is a simple depiction of the accounts Modern Lending will need, their type, and normality.

Modern Lending's Chart of Accounts
Modern Lending's Chart of Accounts

First, we have two general accounts: cash and revenue.

  • Cash tracks the overall cash position of Modern Lending. As it represents a use of funds, it is a debit normal account.
  • Revenue is a tally of how much money we recognize (book) as revenue during the regular course of business. It is a credit normal account because it represents a source of funds. For the sake of this example, Modern Lending has a single revenue stream: interest.

We also have a set of “n of” accounts. This is because each investor and each borrower will have two sets of accounts: one tracking principal and one tracking interest. While we will only need one cash and one revenue account, we need multiple sets of user accounts.

  • Principal accounts track total capital invested by investors and total capital on loan to borrowers. The investor principal accounts are credit normal because they represent sources of funds—or funds Modern Lending owes. Conversely, borrower principal accounts are debit normal because they represent uses of funds—akin to receivables.
  • Interest accounts track the net interest earned from the spread. They follow the same normality rules as the principal accounts: they are credit normal when they track interest due to investors and debit normal when they track interest owed to Modern Lending.

Step 4: Mapping Lending Transaction Logic

Let’s define the five core transaction types for lending and show how they translate into entries on a double-entry ledger. (Note: these examples are meant to be illustrative of what transaction handling logic looks like; these are not exhaustive of all transaction types Modern Lending would need to parse out.)

  1. Investor deposit. An investor adds money to their balance.
  2. Borrower disbursement. A borrower initiates a loan and receives funds.
  3. Interest calculation. Monthly interest gets added to the interest balance for both borrowers and investors. As part of this calculation, part of the interest gets recognized as booked revenue.
  4. Borrower repayment. A borrower repays monthly installments covering both interest and principal.
  5. Investor withdrawal. At the end of their term, Modern Lending sends principal plus interest owed to investors.

To illustrate this, we’ll simplify our marketplace down to one investor and one borrower, and assume the following data comes from our amortization schedule:

  • Lucy: Investor
    • Depositing $10,000
    • Expects a 4.8% return upon completion of her 1-year term ($10,480)
  • Desi: Borrower
    • Borrowing $5,000
    • Will pay 12% annual interest over the course of his 1-year loan ($5,600)
    • Therefore, Desi needs to make monthly payments of $466.67, with $416.67 ($5,000 ÷ 12) of this being directed towards principal, and $50 ($600 ÷ 12) directed towards interest.

Transaction 1. Investor Deposit

Transaction Type 1: Investor Deposit
Lucy's $10K investor deposit

As Lucy deposits money on the Modern Lending platform, we debit (increase) the cash account and credit (increase) Lucy's investor balance account.

Notice that we don’t record any kind of interest due to Lucy on the ledger at this time. Interest is ledgered in a separate transaction (see below).

Transaction 2. Borrower Disbursement

Transaction Type 2: Borrower Disbursement
Desi gets disbursed a $5K loan

When Desi is approved for a loan and receives $5,000, we credit (decrease) our cash account and debit (increase) Desi's principal due account. As above, notice we do not record interest owed.

Transaction 3. Interest Accrual (Monthly)

Transaction Type 3: Interest Calculation
Monthly interest accrual

Lucy lent $10,000 and expects a 4.8% return in a year. That means her effective interest payment at maturity equates to $480. Assuming simple interest, we should add $40 to her interest balance every month ($480 ÷ 12). This is a credit because we are increasing a credit normal account.

Desi borrowed $5,000 at 12% to be paid in a year. This means Desi's final interest balance will be $600 at maturity. Assuming simple interest again, our ledger should add $50 every month to Desi's interest balance ($600 ÷ 12). This is a debit because we are increasing a debit normal account. (Let’s assume Lucy's remaining $5,000 just sits on Modern Lending’s cash account for now).

At the end of the year, Modern Lending will have received $600 from Desi and will owe Lucy $480 in interest. The difference of $120 is recognized as revenue (1). Every month, as interest gets calculated, we add $10 to our revenue account ($120 ÷ 12).

Transaction 4. Borrower Repayment (Monthly)

Transaction Type 4: Borrower Repayment
Desi pays his monthly installment

Desi will have to pay a total of $5,600 over 12 months ($5,000 in principal, and $600 in interest), or a monthly payment of $466.67.

After the transaction clears, we debit (increase) our cash account by $466.67. In the same transaction, we credit (decrease) both principal and interest balances for Desi. Principal gets deducted by $416.67 ($5,000 ÷ 12) and interest gets deducted by $50 ($600 ÷ 12).

The ledger shows one payment made by Desi, a principal balance of $4,583.33 ($5,000 - $416.67), and an interest balance of zero. This happens because we recognized interest in the “interest calculation” section and then immediately zeroed it out as the payment was made.

The sum of credits towards Desi's interest balance represents the total paid in interest. We can contrast this with the data from Modern Lending’s amortization schedule to derive Desi's remaining principal balance.

Transaction 5. Investor Payout (Maturity)

Transaction Type 5: Investor Disbursement
Lucy gets repaid at maturity

At term, Lucy is repaid her principal of $10,000 in addition to the 4.8% return—or $480—promised to her. We credit (decrease) our cash account, and simultaneously lower her principal and interest down to zero by debiting (decreasing) $10,000 and $480, respectively.

Step 5: Bringing It All Together

Let’s review the architecture we would need to support this use case:

  1. A central ledger that represents the entire collection of accounts and transactions and stores them with double-entry constrains
  2. Two services:
    1. A Transaction Logic Service that streams transaction data (typically a payments API like Modern Treasury) and converts events into valid ledger entries for at least the following transaction types:
      1. Investor deposit
      2. Borrower disbursement
      3. Interest calculation
      4. Borrower repayment
      5. Investor disbursement
    2. An Amortization Schedule to properly calculate monthly payments and update balances
  3. A Chart of Accounts, with at least six types:
    1. One debit normal cash account
    2. One credit normal revenue from interest account
    3. One credit normal investor principal account per investor in the platform
    4. One credit normal investor interest account per investor in the platform
    5. One debit normal borrower interest account per borrower in the platform
    6. One debit normal borrower principal account per borrower in the platform.

Conclusion: Building Trust into Lending Systems

Double-entry ledgering helps you:

  • Maintain a clean and auditable system of record
  • Prevent inconsistencies between scheduled payments and actual balances
  • Enable future scalability (more loans, terms, investors, repayment flows)

Using double-entry is the best way to ensure integrity of the financial information flowing through Modern Lending’s product, but it requires a bit of setup and understanding of accounting principles. The hard part—we believe—is setting up the underlying ledger database with the right constraints and level of flexibility.

If you’re building a lending product and want to skip the complexity of building and maintaining ledger infrastructure in-house, take a look at Modern Treasury Ledgers and reach out if we can be helpful.

  1. You may be wondering why we recognize revenue as interest gets calculated, as opposed to when a borrower pays out their repayments or when an investor receives their payout. There is a difference between booked revenue (accrual) and realized revenue (cash). These two concepts are borne from accrual and cash accounting principles.

    In this case, we are using accrual accounting and booking revenue at the point in which it is earned: when interest is incurred. In a marketplace of hundreds or thousands, these transactions would be handled by a monthly cron job that calculates interest and modifies balances on the ledger at a predetermined date.

    Were we using cash accounting, we would add to the realized ledger only after a borrower makes their repayments and investors get paid back. Because your application ledger doesn’t need to comply with GAAP accounting rules, we suggest you pick the method that leads to the cleanest ledger.

Authors
Image of Lucas Rocha
Lucas RochaProduct Manager

Lucas Rocha currently is the PM on the Ledgers product, driving strategy for the company’s database for money movement. Before Modern Treasury, Lucas worked in VC at JetBlue Technology Ventures and Unshackled Ventures. He earned his MBA from Harvard Business School and his bachelor’s degree from Northeastern University.

Learn how to scale a ledger

Build a central source of truth for any service that moves money.

Download the whitepaper