Accounting for Developers

A developer-focused crash course in basic accounting principles and best practices for building products that move money.

Image of Accounting for Developers eBook
Published

August 17, 2022

Reading Time

18 minutes

Topics
Explore With AI
OpenAIClaudeGemini
Copied
Introduction

Why Developers Should Care About Accounting

If you're building or maintaining software that moves or stores money, you're in the business of accounting—whether you know it or not.

As a payment operations startup, accounting principles are core to our work. While some of the largest fintechs and marketplaces implement accounting principles at scale, they seem an arcane topic for new startups. This HackerNews thread, for example, is rather representative of the state of confusion around the topic.

Over the years, many guides such as this have tried to explain accounting to developers (for example, these two great pieces from Martin Blais and Martin Kleppmans). But in our experience, a concepts-first approach to explaining accounting comes in handy when you are designing systems that move or touch money.

This guide introduces double-entry accounting from a software engineering perspective. We cover core principles and apply them to systems like digital wallets and lending platforms. The goal is not to make you an accountant but to help you build more reliable and auditable financial software.

We'll explore:

  • Why double-entry is essential in payments infrastructure
  • How to structure accounts, transactions, and entries
  • How to build a Venmo-style wallet
  • How to build a lending system ledger
Chapter 1

Does Accounting Really Matter In Software Development?

Double-entry accounting is the most reliable way to track money. It ensures every financial event is recorded accurately, with a clear source and destination for funds.

As a payments infrastructure company, we often get to see the architecture of some of the most successful software companies. Top companies rely on double-entry principles. Some build their applications from the start with accounting concepts in mind, but in most cases, companies need to retrofit them after painful incidents involving missing funds, broken payout flows, or inconsistent balances.

When software fails to track money properly, it does so in a number of common patterns. The most common failure mode is software accidentally creating or destroying records of funds. This leads to all sorts of inconsistencies. Every developer we know has horror stories about explaining to their finance team why a customer is owed money or what caused a payout to have an unexpected amount:

  • Internal records differing from bank statements
  • Reconciliation engines mismatching
  • Balances that don't make sense given a set of transactions

For more evidence that double-entry systems are a good standard for scalable applications, see the stories of Uber, Square, and Airbnb.

The core principle of double-entry accounting is that every transaction should record both where the money came from and what the money was used for.

Chapter 2

Accounts: The Building Blocks Of An Accounting System

Let's break down the building blocks of an accounting system.

Let's use a simple Venmo transfer as an example. Van is sending $50 to Tai:

Van sends $50 to Tai, shown as entries against Van's and Tai's accounts

The entries in this transaction tell which accounts were affected. If each user's balance is set up as an account, a transaction can simultaneously write an entry against each account. This ensures the total money in the system doesn't change, it just moves. Now, let's expand this model with more accounts and a handful of additional events:

Expanded Venmo ledger showing multiple events across Venmo and bank account balances
Here I have a ledger—a log of events with monetary impact. We often see developers mutating balances directly rather than computing a balance from a log of transactions. This is suboptimal.

While mutating a balance directly is more efficient and simpler to implement, it's more accurate to store immutable transactions and always compute balances from those transactions. Mutating balances directly creates a system that is prone to errors, as it becomes non-trivial to detect and reconcile inaccuracies.

Notice how each transaction has multiple entries. Each entry belongs to a transaction and an account. By comparing entries side by side, you can see where the money came from and what it was used for.

Double-entry ensures that, as transactions are logged, sources and uses of funds are clearly shown, and balances can be reconstructed as of any date:

One transaction with two entries: one the source of funds, the other the use of funds

This core idea—one transaction, at least two entries, one representing the source and the other representing the use of funds—is one of the foundational ideas of double-entry accounting. We'll expand more on this later.

Understanding Debit Vs. Credit Normal Accounts

As mentioned before, each account has a type. The two types we will cover here are debit normal and credit normal.

By definition:

  • Accounts that represent funds you own, or uses of money, are debit normal accounts.
    • Debit normal accounts increase with a debit entry and decrease with a credit entry.
    • Examples of uses of funds are assets (e.g., cash) and expenses.
    • Note: The term "use" here is broadly defined: letting cash sit in a bank account is a use of funds, as well as selling on credit to someone else (you are effectively 'using' the money you'd get on a sale by extending them credit).
    • Accounts that represent funds you owe, or sources of money, are credit normal accounts.
    • Credit normal accounts increase with a credit entry and decrease with a debit entry.
    • Examples of sources of funds are liabilities, equity, or revenue; this can mean investors' capital, accumulated profits, or income.
    • Note: "Source" is broadly defined here, too: if you are buying on credit, for instance, that is a "source" of money for you in the sense that it prevents you from spending money right now.

Let's illustrate that with a simple table with two columns, the right side listing credit normal accounts and the left side listing debit normal accounts. We will place accounts that track uses of funds on the debit normal side and accounts that track sources of funds on the credit normal side.

Two columns: debit normal accounts (assets and expenses, uses of money) versus credit normal accounts (liabilities and revenue, sources of money)
Table of account categories with mnemonic, examples, and account type
Buying inventory? That's a use (debit). Taking out a loan? That's a source (credit).

What are Debits and Credits in Accounting?

Some of the guides we mentioned at the beginning of this post advise developers to "save the confusion and flush out debits and credits from your mind." We do recognize that debits and credits can be challenging to grasp, but we think fully mastering these concepts is important when creating transaction handling rules.

Part of the confusion is that "debits" and "credits" are often used as verbs: to debit or to credit an account, which trip up developers. Debits and credits can also refer to entries. Here's the simplest way to think about them:

  • Debit entry: Adds to a debit normal account or subtracts from a credit normal account
  • Credit entry: Adds to a credit normal account or subtracts from a debit normal account

In software terms, it's like flags for how a value should affect a given account based on its type.

Matrix of account type by debit and credit showing plus or minus effect

Let's continue to model out a few transactions to drive this point home. Let's use a fictitious startup called Modern Bagelry—an eCommerce store for premium bagels.

In this example, we will use four accounts: Cash and Inventory (both debit normal accounts) as well as Equity and Loans (both credit normal accounts). Let's say this ledger starts on a day T, and we are measuring time in days.

Modern Bagelry transactions over time, with debits, credits, and explanations

How to Ensure Your Ledger is Balanced

The power of double-entry comes from ensuring the sum of all credit normal balances always equals the sum of all debit normal balances.

Let's say we are aggregating the balances for each account in the example above right after each transaction takes place:

Ending balances for Modern Bagelry after each transaction; debit normal totals equal credit normal totals at $1.47M

A system of accounts will balance as long as the balance on debit normal accounts equals the balance on credit normal accounts.

  • The ending balances of debit normal accounts, Cash ($1.22M) and Inventory ($250k), sum to $1.47M.
  • The ending balances of credit normal accounts, Equity ($1M) and Loans ($470k), also sum to $1.47M.
  • Total Debits = Total Credits.

Our Ledger is balanced. Not matching would mean the system created or lost money out of nothing.

Summary: Accounting Principles Developers Should Know

Let's recap the principles we reviewed so far:

  • A ledger is a timestamped log of events that have a monetary impact.
  • An account is a discrete pool of value that represents a balance you want to track.
    • Accounts are classified as debit normal or credit normal.
  • A transaction is an event recorded in the ledger.
    • Transactions must have two or more entries.
  • Entries belong to a ledger transaction and also belong to an account.
    • Entries change balances based on account type and entry direction.
    • Debits—or entries on the debit side—increase the balance of debit normal accounts, while credits decrease it.
    • Credits—or entries on the credit side—increase the balance of credit normal accounts, while debits decrease it.
  • The system is correct if the sum of balances of all credit normal accounts matches the sum of balances of all debit normal accounts. This means all money is properly accounted for.

How can you apply this with software? To implement double-entry accounting in code, you'll need:

  • Ledger Object: Represents the entire system of accounts and transactions
  • Account Object:
    • Has a normality: debit or credit
    • Represents a balance bucket
  • Transaction Object:
    • Contains two or more entries
    • Must be balanced: debits = credits
  • Entry Object:
    • Belongs to one transaction and one account
    • Includes amount and direction (debit or credit)
Chapter 3

Putting Principles Into Practice: Building A Venmo Clone

Now, we will walk through how to design the ledger for a Venmo-style digital wallet app. You'll see how to apply the double-entry accounting principles as we model user transfers, deposits, and withdrawals. We will also share how to structure this using a relational database.

If you're curious about the API calls and system design considerations of designing a digital wallet app, you can also check out our guide on how to build a digital wallet.

Designing a Ledger, Step 1: Define Product Requirements for the Wallet App

Let's begin with what users should be able to do if the app works correctly:

  • View their wallet account balance
  • Add funds to their balance via card or bank payments
  • Send money to (and receive money from) other users in the app
  • Withdraw their balance into a bank account via ACH or instant payment
  • Pay a small fee when they make a withdrawal from the app, to be deducted from their wallet balance

From a product perspective, we also want to:

  • Distinguish user-specific balances and expose them to said users consistently and accurately
  • Ensure the sum of all user balances equals the cash in our bank account
  • Properly calculate and collect revenue from fees
  • Account for a 3% card transaction processing fee for each deposit, paid by us

Step 2: Designing the Chart of Accounts

With these requirements in mind, let's map our chart of accounts (COA). The COA is a simple depiction of the accounts we will need, their type, and normality:

Wallet chart of accounts: Cash, User Wallet, Credit Card Fees, and Revenue with their account types

To review:

  • Cash represents funds we actually hold in our bank account. Because it represents an asset or use of funds, it's a debit normal account.
  • User's Wallet Balance represents funds we hold on behalf of our users. Because users should be able to withdraw them at any time, they are funds we "owe"—or liabilities. Those funds are technically now available for our "use," meaning they are sources of funds, and thus credit normal accounts.
    • We need one User Balance account for each customer that creates an account with us.
  • Card Processing Fees represent expenses or uses of funds; therefore, this is a debit normal account. This account's balance will increase every time we pay off fees.
  • Revenue from fees we collect in each transaction are sources of funds, so they are credit normal accounts.

Step 3: Modeling Key Transactions

We should consider the typical events that will affect the ledger. For the sake of this example, we will model three core transaction types:

  • Transfers: User A sends money from their balance to User B.
  • Deposits: User A adds cash into their account balance. At the time of transfer, we need to account for the credit card processing fee. (Let's assume, for the sake of this example, that credit card fees are paid by us.)
  • Withdrawals: User B withdraws from their account balance. We charge a fee when users withdraw from the app, deducted from their balance. At the time of transfer, we need to account for our own service fee as revenue.
Example 1, a transfer: Art's Wallet debited $100 and Brittany's Wallet credited $100
This example shows Art transferring $100 to Brittany. In this case, the transaction amount is debited (deducted) from Art's Wallet (who's initiating the transfer) and credited (added) to Brittany's Wallet (who's the receiver).

Note that this logic can be used for any in-app transfer—we just have to designate which wallet is initiating and which is receiving in each case. As marked in our COA above, User Wallets are credit normal accounts. If Brittany was sending money to Art, then Brittany's balance would be debited (decrease), and Art's balance would be credited (increase).

Example 2, a deposit: Art's Wallet credited $300, Cash debited $294, Card Processing Expenses debited $6

In this model, three accounts are involved: Art's Wallet, Cash, and Card Processing Expenses (recall that for the sake of this example, our app is paying for card fees).

  • Art deposits $300 in his wallet balance using a credit card.
  • To counterbalance the $300 credit (increase) on Art's Wallet, we need two debit entries:
  • One on the card processing fees account (increases by $6, or 2% of the transaction)
  • One on the cash account. Given we are recording this expense as paid off to our credit card vendor, our cash balance increases by $294 ($300-$6).

Without double-entry, we would need a way for the system to recognize all of the deposit transactions and properly account for card fees. By recording all of the money movement in a single event (in this case, a deposit) with multiple entries, we make sure our system is consistent. As debits equal credits, money in equals money out.

Example 3, a withdrawal: Brittany's Wallet debited $502.50, Cash credited $500, Revenue From Fees credited $2.50

A withdrawal is similar to a deposit, except that in this case, we are charging an extra fee from the user and recognizing it as revenue from fees. This transaction will decrease Brittany's Wallet and Cash but will increase Revenue.

Brittany withdraws $500 from her wallet balance (Brittany knows that she will pay a fee).

  • Let's assume that the fee is 0.5% of the withdrawal amount, or $2.50.
  • Her user wallet gets deducted for $500 + $2.50, or $502.50.
  • We need to wire Brittany her money, so we add a credit entry to deduct our Cash account; however, we owe $2.50 less to Brittany, a small amount we can recognize as Revenue.

There are many different ways to model this. We could have chosen to have Brittany receive $497.50 ($500-$2.50), for example. In this case, we would add/credit the $2.50 we kept to revenue from fees similarly, but our cash would only decrease/credit by $497.50. The ledger would still balance. Thinking in terms of credit and debit normality gives you the flexibility to log transactions in the best way for your business.

Step 4: Database Modeling and Application Logic

Let's review the logical elements we would need to create to service this use case:

  • One ledger object that represents the entire collection of accounts and transactions. All of our accounts and transactions should belong to a single ledger.
  • At least four types of account objects:
    • User Wallets (one per user, credit normal)
    • Cash (single account, debit normal)
    • Revenue from Fees (single account, credit normal)
    • Card Processing Expenses (single account, debit normal)
  • At least three modeled transactions
    • User Transfer
    • Deposit
    • Withdrawal
  1. In dev terms:
    • Accounts table fields: id, user_id, account_type, normality
    • Transactions table fields: id, timestamp, description
    • Entries table fields: id, transaction_id, account_id, amount, direction
    • For entries, enforce: sum of debit amounts == sum of credit amounts, per transaction
    • For each transaction type, create logic that writes 2+ entries with totals that net to zero (determine entry direction based on account type)
  2. By setting up the ledger as a double-entry system, we ensure that our Wallet App:
    • Scales without drift or inconsistency
    • Produces accurate balances and reconciliation data
    • Extends to new features with minimal refactoring (as new product requirements come up or functionalities are rolled out, we can update our COA and the transaction models to represent them in the ledger appropriately)
Chapter 4

Applying The Concepts: Building a Lending Marketplace

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 supports 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.

Lending data flow between the front end, payments and reconciliation logic, the ledger database, and the amortization schedule

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

  • Historical data, or data that reliably represents the current financial state of Modern Lending based on posted transactions.
  • 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 referenceable 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.

Lending chart of accounts: cash, revenue, investor principal, investor interest due, borrower principal, and borrower interest 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.)

  • Investor deposit. An investor adds money to their balance.
  • Borrower disbursement. A borrower initiates a loan and receives funds.
  • 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.
  • Borrower repayment. A borrower repays monthly installments covering both interest and principal.
  • 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:

Transaction 1. Investor Deposit

Transaction 1, investor deposit: Cash debited $10,000 and Lucy's Investor Principal Balance credited $10,000

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 2, borrower disbursement: Cash and Desi's principal balance, $5,000

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 3, monthly interest accrual: Lucy's investor interest credited $40, Desi's borrower interest debited $50, revenue booked $10

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 revenue1. Every month, as interest gets calculated, we add $10 to our revenue account ($120 ÷ 12).

Transaction 4. Borrower Repayment (Monthly)

Transaction 4, borrower repayment: Cash debited $466.67, Desi's principal balance $416.67, Desi's interest due balance $50

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 at maturity: Cash $10,480, Lucy's investor principal $10,000, Lucy's investor interest $480

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 -$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 constraints
  2. Two services:
    • 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:
      • Investor deposit
      • Borrower disbursement
      • Interest calculation
      • Borrower repayment
      • Investor disbursement
    • An Amortization Schedule to properly calculate monthly payments and update balances
  3. A Chart of Accounts, with at least six types:
    • One debit normal cash account
    • One credit normal revenue from interest account
    • One credit normal investor principal account per investor in the platform
    • One credit normal investor interest account per investor in the platform
    • One debit normal borrower interest account per borrower in the platform
    • One debit normal borrower principal account per borrower in the platform
Conclusion

Summary: 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.

Sources

Footnotes

  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.

Subscribe to our newsletter

Get the latest articles, guides, and insights delivered to your inbox.