<!-- Source: https://blnkfinance.com/blog/double-entry-for-developers -->

[Blog](https://blnkfinance.com/blog) [Guides](https://blnkfinance.com/blog/guides)

7 min read

# Double-Entry Accounting for Developers: How to Model Money Movement in Blnk

How double-entry works in a product ledger. Model deposits, debt, interest, refunds, and reconciliation as source and destination posts.

![Double-entry accounting for developers: how to model money movement in Blnk](https://cdn.sanity.io/images/06pses5q/production/99e6e1da36c8c2eccf3c71cf1d143c8806d946d1-1920x1080.webp?w=1600&fit=max&auto=format)

In simple terms, [double-entry accounting](https://blnkfinance.com/glossary/double-entry) is the money version of the law of conservation of energy.

Just as energy cannot be created or destroyed and can only change form, money in a double-entry system cannot appear or disappear. Every movement of money must have two sides: a source and a destination.

When building financial products, this means money is never just “created” inside the system. It is always transferred from somewhere to somewhere else, and both sides must be recorded.

In this article, we’ll learn how to [implement correctness](https://docs.blnkfinance.com/guides/double-entry) and accuracy into your product using double-entry with Blnk.

## Double-entry vs single-entry: what's the difference?

Most developers start with single-entry accounting without realising it. You have a balance, you add to it or subtract from it, and you move on.

The problem is that a single-entry system only records what happened to one side. If John deposits $200, you record "+$200 to John's balance." But where did that $200 come from? The ledger doesn't say.

|  | Single-entry | Double-entry |
| --- | --- | --- |
| Records | One side of the transaction | Both sides, source and destination |
| Auditability | Hard to trace where money came from | Every transaction is fully traceable |
| Error detection | Silent drift, balances go wrong slowly | Errors surface immediately |
| Reconciliation | Manual, painful | Systematic, every entry has a counterpart |
| Blnk support | ✗ Not supported | ✓ enforced by design |

Double-entry requires every transaction to have two parts: a source balance it leaves and a destination balance it enters. Blnk enforces this on every single transaction request. If you don't provide both, the transaction won't record.

## [Source and destination](https://blnkfinance.com/glossary/source-and-destination)

Every transaction is made of three main parts:

1.  How much was sent (`amount`) .
2.  Who sent it (`source`).
3.  Who received it (`destination`).

Blnk enforces this with the source and destination parameters in our transaction request object. When a transaction is created within Blnk, you can always guarantee that this transaction wasn’t generated from thin air.

This matters a lot, because it gives you more control and confidence when the time comes to audit or investigate a problem.

## What happens when the source or destination is outside my system

This is a very common use case.

For example: Ada deposited $200 from her bank account to her in-game wallet. The $200 came from outside Blnk. Her bank isn't a balance in your ledger. How do you represent that?

To model this with double-entry, you frame the fund flow as money came from “outside” to Ada’s wallet.

This means that the source is “outside,” and the destination is Ada.

<!-- 200 OK -->
```
source: "@Outside",
destination: "ada-balance"
```

`@Outside` (or whatever name you choose) is an internal balance that represents external inflows. Now when you look at the transaction record in Blnk, you can immediately tell that this was a deposit. The logic now becomes “every transaction where ‘outside’ is the source must be a deposit.”

For outflows, when money leaves your system, you reverse it:

<!-- 200 OK -->
```
"source": "ada-wallet-balance",
"destination": "@World"
```

Imagine this for thousands of balances in your system. With this logic, all you now need to retrieve deposits for a particular balance is to filter all balances where the source is outside and the destination is the specified balance.

<!-- 200 OK -->
```
q: "*",
query_by: "destination",
filter_by: "source:=outside-balance"
```

## Catching and preventing errors with double-entry

Double-entry in Blnk is represented with a single record. The debit and credit sides are defined by the source and destination balances respectively.

This means that:

1.  **1:1 money movement:** Every transaction maps a single source to a single destination. If the amount is $20, that exact $20 is deducted from the source and added to the destination. You record the amount once, removing the risk of creating money by accident.
2.  **No half-recorded transactions:** A common cause of missing money is recording one side and forgetting to record the other side. Blnk helps you prevent that out of the box. Your transaction will not be recorded if both sides are not provided.
3.  **Deterministic balances:** Because every transaction has two sides, balances will always be the result of easily traceable transactions. If a balance looks wrong, you know the issue must come from a specific transaction rather than silent drift over time.
4.  **Clear error surfaces:** With double entry, balance errors always come down to two things: wrong amount and wrong counterparty. This drastically narrows down the search space when something goes wrong and you need to dig deep into your ledger.

## Example: building a credit card flow on double-entry

Jasmine was tasked with building a new ledger for her team’s new credit card product. As a core requirement, the product would accrue owed cash spent by the user plus interest accrued on the outstanding loan.

To implement it with Blnk’s double entry, she needs to start with 1 question:

> How many times will money move?

For Jasmine, money moves three times:

1.  When cash is spent
2.  When interest is accrued
3.  When the credit is repaid

### When cash spent is being accrued.

When a user spends money on credit, their balance goes negative. A negative balance means the user owes that amount to the business.

This setup makes debt visible immediately. Any negative balance clearly represents an outstanding customer obligation.

```
source: "user-balance",
destination: "@Outside"
```

In plain terms, value leaves the user’s balance and moves to the outside world. The ledger records this as debt, not lost money.

### When interest is being accrued

Accrued interest represents the cost of borrowing over time. Each interest charge increases how much the user owes, which means their negative balance grows.

```
source: "user-balance",
destination: "@Interest"
```

Because interest is clearly separated in its own money movement, you can also choose to separate the principal from the interest and see how the debt was built up.

### When the credit card is paid off

Paying off the credit card means settling the debt and bringing the user balance back to zero.

To do this, the payment flows into the user’s balance, offsetting the negative amount created by spending and interest.

```
source: "@LoanSettlement"
destination: "user-balance"
```

## Use-case tutorials built on double-entry

Every use case below is a direct implementation of the double-entry model above. Start with the one closest to what you're building:

-   [How to Build Recurring Payments and Savings Goals with Blnk](https://blnkfinance.com/blog/how-to-implement-recurring-payments-with-blnk)
-   [How to Build Loan Disbursement, Interest, and Repayments with Blnk](https://blnkfinance.com/blog/how-to-build-loan-disbursement-interest-and-repayments-with-blnk)
-   [How to Build a Bulk Payroll System Using the Blnk Ledger](https://blnkfinance.com/blog/how-to-build-a-bulk-payroll-system-using-the-blnk-ledger)
-   [How to Build a Reward System for an eCommerce Platform with Blnk](https://blnkfinance.com/blog/how-to-build-a-reward-system-for-an-e-commerce-platform-using-blnk)
-   [How to Build a SaaS Referral System with Blnk](https://blnkfinance.com/blog/how-to-build-a-saas-referral-system-with-blnk)
-   [How to Build Escrow Payments for Online Marketplaces](https://blnkfinance.com/blog/developer-guide-to-building-a-marketplace-with-open-source-ledger-blnk)
-   [How to Generate Customer Statements From Your Ledger With Blnk](https://blnkfinance.com/blog/how-to-generate-customer-statements-from-your-ledger-with-blnk-postgres)

## FAQ

-   **What's the difference between source and destination in Blnk?**Source is the balance money leaves. Destination is the balance money enters. Both are required on every transaction. If either is missing, Blnk rejects the transaction.
-   **Can a balance go negative in Blnk?**Yes, with `[allow_overdraft](https://blnkfinance.com/glossary/overdraft): true`. This is intentional and common for internal balances like `@World` that represent external inflows, or for credit product balances where a negative balance represents money owed.
-   **How do I record a fee on a transaction?**Create a separate transaction from the user's balance to your internal fee balance such as `@RevenueFees`. Fees are not edits to the original transaction. They are their own money movement with their own audit trail.
-   **What happens if I send the same transaction twice?**Blnk uses the `reference` field to detect duplicates. If the same reference is sent twice, Blnk processes it once and discards the duplicate. Always use a unique, [stable reference](https://blnkfinance.com/glossary/reference) per transaction.
-   **How does double-entry make reconciliation easier?**Because every transaction has two sides, you can always reconstruct the full history of any balance by tracing its transactions. Reconciliation becomes a matching exercise rather than a forensic investigation.

## In summary

Double-entry is not just a feature. It is a standard, a correctness guarantee for your money.

It requires you to define your flows explicitly even if it means a bit of extra work upfront. This decision will save you a ton of time, money, and energy when your customers grow, volumes increases, and edge case start to appear.

**With Blnk in place, it becomes easier to build higher-level workflows:**

-   **Fees & revenue** are just additional destinations. [See how to model fees and multiple destinations](https://docs.blnkfinance.com/transactions/multiple-destinations)
-   **Refunds** are new money movements, not edits. [See how refunds work in Blnk](https://docs.blnkfinance.com/transactions/refunds)
-   **Reconciliation** becomes easier and doable. [See how reconciliation works in Blnk](https://docs.blnkfinance.com/cloud/reconciliation/overview)

Instead of worrying about if your balances are correct, you can ask “which transactions got us here?” Double-entry turns money into a system that you can always trust, audit, and verify.

Get started with [Blnk Core](https://docs.blnkfinance.com/home/install) to try out double-entry for your product.  

On this page

1.  [Double-entry vs single-entry: what's the difference?](#double-entry-vs-single-entry-what-s-the-difference)
2.  [Source and destination](#source-and-destination)
3.  [What happens when the source or destination is outside my system](#what-happens-when-the-source-or-destination-is-outside-my-system)
4.  [Catching and preventing errors with double-entry](#catching-and-preventing-errors-with-double-entry)
5.  [Example: building a credit card flow on double-entry](#example-building-a-credit-card-flow-on-double-entry)
6.  [When cash spent is being accrued.](#when-cash-spent-is-being-accrued)
7.  [When interest is being accrued](#when-interest-is-being-accrued)
8.  [When the credit card is paid off](#when-the-credit-card-is-paid-off)
9.  [Use-case tutorials built on double-entry](#use-case-tutorials-built-on-double-entry)
10.  [FAQ](#faq)
11.  [In summary](#in-summary)

Author

-   Praise Philemon Co-founder & Head of Revenue

Updated on

August 17, 2026

## Related articles

-   [
    
    ![Managing ledger integrity in the age of AI agents](https://cdn.sanity.io/images/06pses5q/production/0b63efb27b89fbc596e1ca371e19517b9d395c42-1200x675.png?rect=94,0,1013,675&w=1500&h=1000&fit=crop&auto=format)
    
    Guides
    
    ### Managing ledger integrity in the age of AI agents
    
    August 21, 2026
    
    ](https://blnkfinance.com/blog/managing-ledger-integrity-in-the-age-of-ai-agents)
-   [
    
    ![How to handle idempotency in your financial app using the Blnk Ledger](https://cdn.sanity.io/images/06pses5q/production/e5d0161c36664e7a15399131195ba09b533e2255-1792x1008.png?rect=140,0,1512,1008&w=1500&h=1000&fit=crop&auto=format)
    
    Guides
    
    ### How to handle idempotency in your financial app using the Blnk Ledger
    
    May 4, 2026
    
    ](https://blnkfinance.com/blog/how-to-handle-idempotency-in-your-financial-app-using-the-blnk-ledger)
-   [
    
    ![Complete guide: best practices for building financial apps with Blnk Ledger](https://cdn.sanity.io/images/06pses5q/production/48df165ccc6f3f9a8f9c165fd0124eb3a60782ca-1920x1080.webp?rect=150,0,1620,1080&w=1500&h=1000&fit=crop&auto=format)
    
    Guides
    
    ### Complete guide: best practices for building financial apps with Blnk Ledger
    
    February 3, 2026
    
    ](https://blnkfinance.com/blog/building-with-blnk-ledger-best-practices-guide)
