
In simple terms, double-entry accounting 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 and accuracy into your product using double-entry with Blnk.
Source and destination
Every transaction is made of three main parts:
- How much was sent.
- Who sent it.
- Who received it.
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/destination is not in my system
This is a very common use case.
For example: Ada deposited $200 from her bank account to her in-game wallet. 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.
```
--CODE language-javascript--
source: "@Outside",
destination: "ada-balance"
```
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.”
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.
```
--CODE language-javascript--
q: "*",
query_by: "destination",
filter_by: "source:=outside-balance"
```
Catching/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 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.
- 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.
- 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.
- 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:
- When cash is spent
- When interest is accrued
- 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.
```
--CODE language-bash--
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.
```
--CODE language-bash--
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.
```
--CODE language-bash--
source: "@LoanSettlement"
destination: "user-balance"
```
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.
- Refunds are new money movements, not edits.
- Reconciliation becomes easier and doable.
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 to try out double-entry for your product.
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Ledger architecture refers to how you group your balances to work for your application
Ordered list
- Item 1
- Item 2
- Item 3
Unordered list
- Item A
- Item B
- Item C
Bold text
Emphasis
Superscript
Subscript
