This guide covers best practices for designing your chart of accounts in Formance Ledger, with a focus on handling real-world financial scenarios like debts, credit lines, and liabilities.
Allowing Negative Balances
In Formance, accounts can be configured to carry negative balances, enabling accurate modeling of real-world financial obligations such as debts, credit lines, pending payments, or unsettled invoices.
Why allow negative balances?
Allowing an account to go negative is a common way to represent liabilities or temporary obligations. For example:
- A user owes funds to a platform or another user
- A credit line that can be drawn upon
- Pending settlements awaiting clearing
- Unsettled invoices
The account balance reflects that deficit until the obligation is cleared.
Enabling overdraft
To allow an account to have a negative balance, use the allowing overdraft clause in Numscript:
send [USD/2 1000] (
source = @users:alice allowing unbounded overdraft
destination = @users:bob
)
Or with a bounded overdraft:
send [USD/2 1000] (
source = @users:alice allowing overdraft up to [USD/2 500]
destination = @users:bob
)
See Overdraft for more details on overdraft syntax.
Debt Settlement Example
When a user pays off a debt, the transaction simply reduces the negative balance on the debtor’s account. This brings the balance closer to zero (or above), effectively recording the settlement of the liability.
Scenario
- Alice owes 100toBob(Alice′sbalance:−100)
- Alice pays $50 to Bob
- Alice’s balance becomes -$50
// Initial debt creation (Bob lends to Alice)
send [USD/2 10000] (
source = @users:alice allowing unbounded overdraft
destination = @users:bob
)
// Debt repayment (Alice pays back Bob)
send [USD/2 5000] (
source = @users:alice
destination = @users:bob
)
This mirrors standard double-entry accounting, where one account’s reduction offsets another’s increase.
Best Practices for Account Naming
Avoid world as a generic source
To ensure clarity and traceability in your ledger:
Avoid introducing funds from the generic world account for business transactions.
Use specific account addresses like users:123:payment:4567 to represent the exact source or context of the transaction.
Why this matters
- Audit trail: Specific addresses maintain a transparent record of where funds originated
- Context: Stakeholders can understand the purpose of each transaction
- Debugging: Easier to trace issues when accounts have meaningful names
Good vs. bad examples
| Bad | Good |
|---|
@world → @users:alice | @users:alice:payment:order-123 → @platform:revenue |
| Generic source | Specific, contextual source |
When to use world
The world account is appropriate for:
- Initial system bootstrapping
- Minting new assets (e.g., loyalty points, tokens)
- Non-funded currency conversions (see Currency Conversion)
Structuring Account Hierarchies
Use colons (:) to create meaningful account hierarchies:
users:{user_id}:wallet:main
users:{user_id}:wallet:pending
users:{user_id}:payment:{payment_id}
merchants:{merchant_id}:earnings
merchants:{merchant_id}:settlements
platform:fees
platform:revenue
platform:taxes:{tax_type}
orders:{order_id}:authorization
orders:{order_id}:capture
orders:{order_id}:refund
Benefits of hierarchical naming
- Filtering: Query all accounts matching a pattern (e.g.,
users:123:)
- Organization: Logical grouping of related accounts
- Scalability: Easy to add new account types without restructuring
Modeling Common Financial Scenarios
# Customer accounts
customers:{id}:wallet
# Merchant accounts
merchants:{id}:earnings
merchants:{id}:settlements
# Order-specific accounts
orders:{id}:pending
orders:{id}:captured
# Platform accounts
platform:fees
platform:taxes:vat
platform:refunds:pool
# Borrower accounts (can go negative)
borrowers:{id}:principal
borrowers:{id}:interest
# Lender accounts
lenders:{id}:available
lenders:{id}:deployed
# Loan-specific accounts
loans:{id}:outstanding
loans:{id}:payments
Multi-currency Wallet
# User wallets per currency
users:{id}:wallet:USD
users:{id}:wallet:EUR
users:{id}:wallet:BTC
# Exchange accounts
exchange:liquidity:USD
exchange:liquidity:EUR
exchange:fees
Summary
| Concept | Recommendation |
|---|
| Negative balances | Use allowing overdraft for liabilities and debts |
| Account naming | Use specific, contextual addresses instead of world |
| Hierarchy | Use colons to create logical groupings |
| Debt settlement | Reduce negative balances through standard transactions |