Skip to content

Accounting Setup

Apache Fineract uses double-entry accounting. Every financial transaction - a loan disbursement, a repayment, a savings deposit, a fee payment - automatically generates the corresponding journal entries in the general ledger based on the accounting rules you configure for each product. Getting accounting right before going live is critical: retrospective corrections to journal entries are complex, and incorrect mappings produce misleading financial statements from day one.

This guide walks through the setup sequence: chart of accounts first, then product mappings.

Account Types

Fineract uses five standard account types, each serving a distinct accounting purpose:

TypeUsage
AssetWhat the institution owns or is owed: loan portfolios, cash, bank accounts, interest receivable
LiabilityWhat the institution owes: savings balances, deposits, borrowings
EquityRetained earnings, paid-up capital, reserves
IncomeRevenue: interest income, fee income, penalty income
ExpenseCosts: provisioning, write-off losses, operating expenses

Setting Up the Chart of Accounts

A default chart of accounts is seeded when your Fineract instance is provisioned. Review it before creating any loan or savings products - the default accounts may not match your institution's GL structure or regulatory requirements.

View Existing Accounts

bash
curl https://your-instance.finecko.com/fineract-provider/api/v1/glaccounts \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)"

Each account has a GL code (your institution's internal code), a name, and a type.

Create an Account

bash
curl -X POST \
  https://your-instance.finecko.com/fineract-provider/api/v1/glaccounts \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Loan Portfolio - Personal Loans",
    "glCode": "1100",
    "type": 1,
    "manualEntriesAllowed": false,
    "usage": 1
  }'

Account type codes: 1 = Asset, 2 = Liability, 3 = Equity, 4 = Income, 5 = Expense.

Usage codes: 1 = Detail (used in postings), 2 = Header (for grouping only, not used in postings).

Set manualEntriesAllowed: false for accounts that should only receive system-generated entries (loan portfolio accounts, interest income accounts). This prevents accidental manual postings that corrupt the GL.

Account Hierarchy

Accounts can be organised into a parent-child hierarchy for reporting purposes. A header account (e.g. "Total Loan Portfolio") can have detail accounts beneath it (e.g. "Personal Loans", "Group Loans", "SME Loans"). The header account shows the aggregate in balance sheet reports; postings only go to detail accounts.

Set the parent when creating a child account:

bash
-d '{
  "name": "Personal Loans",
  "glCode": "1101",
  "type": 1,
  "parentId": 10,
  "usage": 1,
  "manualEntriesAllowed": false
}'

Minimum Required Accounts

Before you can create a loan product, you need at minimum these GL accounts:

AccountTypeUsed for
Loan portfolio accountAssetOutstanding principal balance
Interest receivableAssetAccrued but uncollected interest (for accrual-based products)
Fund sourceAsset or LiabilitySource of disbursed funds (cash, bank, or donor funds)
Loan income account (interest)IncomeInterest revenue recognised on repayment or accrual
Fee income accountIncomeFee revenue
Penalty income accountIncomePenalty/overdue charge revenue
Overpayment liabilityLiabilityCustomer overpayments held pending refund

Before you can create a savings product:

AccountTypeUsed for
Savings referenceLiabilityCustomer savings balances
Savings controlLiabilityClearing account for savings transactions
Interest on savingsExpenseInterest paid to savers
Savings transfers in suspenseLiabilityFunds in transit

Loan Product Accounting Mappings

Every loan product has an accounting configuration section. When you create or edit a loan product, you map each event to a GL account:

MappingWhat it does
Fund sourceWhere disbursed funds come from (debit this, credit loan portfolio)
Loan portfolioThe outstanding principal balance account
Interest receivableAccrued interest not yet collected (accrual-based products only)
Income from interestInterest revenue account
Income from feesFee revenue account
Income from penaltiesPenalty/overdue charge revenue
Losses written offExpense account for write-offs
Goodwill creditExpense account for goodwill credits
Overpayment liabilityLiability account for customer overpayments

Accounting Method: Cash vs Accrual

Each loan product uses either cash-basis or accrual-basis accounting. This choice drives which accounts are required and how journal entries are posted.

Cash basis: Interest income is recognised when the repayment is received. No interest receivable account is required. Simpler to set up; does not show a full picture of earned-but-uncollected income on the balance sheet.

Accrual basis: Interest income is recognised each day it is earned, regardless of whether it has been collected. COB posts daily accrual entries to the interest receivable and income accounts. Requires an interest receivable account. Provides accurate income recognition for financial reporting.

Most regulated financial institutions are required to use accrual-basis accounting.

Example: Simple Accrual Loan Product Mappings

Assuming this chart of accounts:

GL CodeNameType
1100Loan PortfolioAsset
1200Interest ReceivableAsset
1300Cash at BankAsset
4100Interest IncomeIncome
4200Fee IncomeIncome
4300Penalty IncomeIncome
5100Loan Write-Off LossExpense
2100Customer OverpaymentsLiability

Product mapping:

FieldGL Account
Fund source1300 - Cash at Bank
Loan portfolio1100 - Loan Portfolio
Interest receivable1200 - Interest Receivable
Income from interest4100 - Interest Income
Income from fees4200 - Fee Income
Income from penalties4300 - Penalty Income
Losses written off5100 - Loan Write-Off Loss
Overpayment liability2100 - Customer Overpayments

When a loan is disbursed: debit 1100 (Loan Portfolio), credit 1300 (Cash at Bank). When COB runs accruals: debit 1200 (Interest Receivable), credit 4100 (Interest Income). When a repayment is received: debit 1300 (Cash at Bank), credit 1100 (principal portion) and 1200 (interest portion).

Savings Product Accounting Mappings

MappingWhat it does
Savings referenceThe primary customer liability account (savings balance)
Savings controlClearing account for in-progress transfers
Transfers in suspenseFunds in transit during inter-account transfers
Interest on savingsExpense account for interest paid to savers
Income from feesRevenue from savings account fees
Overdraft portfolio controlIf overdraft is enabled: liability for overdraft balances
Income from interestFor overdraft products: interest income on overdraft balances
Write-offOverdraft write-offs

Verifying Accounting After Setup

After creating a product and running a test loan or savings account end-to-end, verify the journal entries:

bash
# List recent journal entries
curl "https://your-instance.finecko.com/fineract-provider/api/v1/journalentries?dateFormat=yyyy-MM-dd&fromDate=2024-01-01&toDate=2024-12-31&offset=0&limit=50" \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)"

Check that:

  • A disbursement produces a debit to the loan portfolio account and a credit to the fund source
  • A repayment produces debits to cash and credits to the loan portfolio and income accounts in the expected proportions
  • Running an accrual (via COB or manual trigger) produces debits to interest receivable and credits to interest income

If entries appear in unexpected accounts, re-check the product's accounting mappings. There is no automatic way to correct historical journal entries - fix the product mapping and re-run any test transactions.

Manual Journal Entries

Some adjustments cannot be handled through product mappings and require direct journal entries: write-backs of over-provisioned amounts, adjustments after data migration, opening balances when migrating from a previous system.

Manual entries require the CREATE_JOURNALENTRY permission and can only be posted to accounts with manualEntriesAllowed: true.

bash
curl -X POST \
  https://your-instance.finecko.com/fineract-provider/api/v1/journalentries \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "officeId": 1,
    "transactionDate": "15 March 2024",
    "dateFormat": "dd MMMM yyyy",
    "locale": "en",
    "currencyCode": "KES",
    "comments": "Opening balance adjustment",
    "debits": [
      { "glAccountId": 10, "amount": 500000.00 }
    ],
    "credits": [
      { "glAccountId": 25, "amount": 500000.00 }
    ]
  }'

Every manual entry requires a comment explaining why it was posted. Manual entries are audited and should be reviewed by a second authoriser in your institution's workflow.

Chart of Accounts Import

For institutions migrating from another system with an established GL structure, the chart of accounts can be imported in bulk via the Mifos Web UI (Administration - Accounting - Chart of Accounts - Import). Prepare a spreadsheet following the Mifos import template format and upload it to create all accounts at once rather than one by one through the API.

Trial Balance and Financial Statements

Once accounting is configured and transactions are flowing, verify the trial balance is in balance:

bash
GET /fineract-provider/api/v1/runreports/Trial Balance Report?locale=en&dateFormat=yyyy-MM-dd

A balanced trial balance (total debits equal total credits) confirms the accounting engine is posting entries correctly. Run this after your first end-to-end test transactions before going live.