Loan Product - Accounting Configuration (V2)
Module: Loan Products
Configuration Section: accountingConfig
Version: V2 (ConfigData YAML)
Status: ✅ Production Ready
Overview
The Accounting Configuration section defines how loan transactions are posted to the General Ledger. V2 uses a flexible Account Leg system where each transaction component maps to specific GL accounts based on the accounting methodology.
Key Concepts
- Account Legs: Predefined transaction components (e.g., PortfolioControl, InterestReceivable)
- Methodology: Accrual or Cash accounting
- GL Account Mapping: Each leg maps to a specific GL account code
- Multi-Company Support: Optional company-specific GL accounts
Accounting Methodology
| Methodology | Description | When to Use | Impact |
|---|---|---|---|
| Cash | Recognize revenue when cash is received | Simple operations, high-risk lending | Revenue only when collected |
| Accrual | Recognize revenue when earned (regardless of payment) | Standard banking practice, IFRS 9 compliance | Revenue accrued daily, provisions tracked |
Cash vs Accrual Comparison
Cash Accounting:
accountingConfig:
interestRecognitionMethod: Cash
- ✅ Simple revenue recognition
- ✅ No accruals to manage
- ⌠Overstates profitability (ignores unpaid interest)
- ⌠Poor risk visibility
- Use Case: Microfinance, high-risk consumer lending
Accrual Accounting:
accountingConfig:
interestRecognitionMethod: Accrual
- ✅ True financial position (IFRS 9 compliant)
- ✅ Shows expected cash flows
- ✅ Better risk management (provisions, NPLs)
- ⌠More complex GL posting
- Use Case: Commercial banking, regulatory compliance
Account Leg Types
The V2 system defines 9 standard account legs for loan products:
1. PortfolioControl (Required)
Purpose: Loan principal outstanding (asset account)
Account Type: Asset
Normal Balance: Debit
Transactions:
- Disbursement: Debit (increase asset)
- Principal Repayment: Credit (decrease asset)
- Write-off: Credit (remove asset)
Example:
- legType: PortfolioControl
accountCode: "1020100" # Loans and Advances - Customer
description: "Loan portfolio principal outstanding"
2. InterestReceivable (Accrual Only)
Purpose: Accrued but uncollected interest income
Account Type: Asset
Normal Balance: Debit
Transactions:
- Daily Accrual: Debit (increase receivable)
- Interest Payment: Credit (clear receivable)
- Write-off: Credit (remove uncollectible)
Example:
- legType: InterestReceivable
accountCode: "1020200" # Interest Receivable on Loans
description: "Accrued interest on loan portfolio"
3. InterestIncome (Required)
Purpose: Interest revenue earned
Account Type: Income
Normal Balance: Credit
Transactions:
- Accrual Accounting: Credit (daily accrual)
- Cash Accounting: Credit (when payment received)
Example:
- legType: InterestIncome
accountCode: "4020100" # Interest Income on Loans
description: "Interest revenue from loan portfolio"
4. FeeReceivable (Accrual Only)
Purpose: Accrued but uncollected fee income
Account Type: Asset
Normal Balance: Debit
Transactions:
- Fee Charge: Debit (increase receivable)
- Fee Payment: Credit (clear receivable)
Example:
- legType: FeeReceivable
accountCode: "1020300" # Fee Receivable
description: "Processing and management fees receivable"
5. FeeIncome (Required)
Purpose: Fee revenue earned
Account Type: Income
Normal Balance: Credit
Transactions:
- Processing Fee: Credit (at disbursement)
- Management Fee: Credit (periodic)
- Late Payment Fee: Credit (when charged)
Example:
- legType: FeeIncome
accountCode: "4020200" # Fee Income on Loans
description: "Non-interest income from loan products"
6. PenaltyReceivable (Accrual Only)
Purpose: Accrued but uncollected penalties
Account Type: Asset
Normal Balance: Debit
Transactions:
- Penalty Charge: Debit (increase receivable)
- Penalty Payment: Credit (clear receivable)
- Waiver: Credit (forgive penalty)
Example:
- legType: PenaltyReceivable
accountCode: "1020400" # Penalty Receivable
description: "Late payment and default penalties"
7. PenaltyIncome (Optional)
Purpose: Penalty revenue earned
Account Type: Income
Normal Balance: Credit
Transactions:
- Late Payment Penalty: Credit (when charged)
- Default Penalty: Credit (when applied)
Example:
- legType: PenaltyIncome
accountCode: "4020300" # Penalty Income
description: "Revenue from penalties and late fees"
8. WriteOffExpensePrincipal (Required for Write-offs)
Purpose: Loss on uncollectible principal
Account Type: Expense
Normal Balance: Debit
Transactions:
- Write-off Principal: Debit (recognize loss)
- Recovery: Credit (reverse loss)
Example:
- legType: WriteOffExpensePrincipal
accountCode: "5030100" # Loan Write-off Expense - Principal
description: "Uncollectible loan principal expense"
9. WriteOffExpenseInterest (Optional)
Purpose: Loss on uncollectible interest
Account Type: Expense
Normal Balance: Debit
Transactions:
- Write-off Interest: Debit (recognize loss)
- Recovery: Credit (reverse loss)
Example:
- legType: WriteOffExpenseInterest
accountCode: "5030200" # Loan Write-off Expense - Interest
description: "Uncollectible interest expense"
Complete AccountingConfig Section
Basic Structure
accountingConfig:
interestRecognitionMethod: Cash | Accrual
accountLegs:
- legType: PortfolioControl
accountCode: "string"
companyCode: "string" # Optional
description: "string" # Optional
- legType: InterestIncome
accountCode: "string"
# ... additional legs
Field Reference
| Field Name | Data Type | Required | Description | Example |
|---|---|---|---|---|
interestRecognitionMethod | Enum | ✅ Yes | Accounting methodology | "Cash" or "Accrual" |
accountLegs[] | Array | ✅ Yes | GL account mappings | See below |
accountLegs[].legType | Enum | ✅ Yes | Account leg type | "PortfolioControl" |
accountLegs[].accountCode | String | ✅ Yes | GL account code | "1020100" |
accountLegs[].companyCode | String | No | Company code (multi-company) | "COMP001" |
accountLegs[].description | String | No | Leg description | "Loan principal" |
Required Account Legs by Methodology
| Methodology | Required Legs | Optional Legs |
|---|---|---|
| Cash | • PortfolioControl • InterestIncome • FeeIncome | • PenaltyIncome • WriteOffExpensePrincipal • WriteOffExpenseInterest |
| Accrual | • PortfolioControl • InterestReceivable • InterestIncome • FeeReceivable • FeeIncome | • PenaltyReceivable • PenaltyIncome • WriteOffExpensePrincipal • WriteOffExpenseInterest |
Sample Configurations
Example 1: Cash Accounting (Simple Consumer Loan)
accountingConfig:
interestRecognitionMethod: Cash
accountLegs:
# Loan principal outstanding
- legType: PortfolioControl
accountCode: "1020100"
description: "Personal Loan Portfolio"
# Interest income (recognized when received)
- legType: InterestIncome
accountCode: "4020100"
description: "Interest Income on Personal Loans"
# Processing and management fees
- legType: FeeIncome
accountCode: "4020200"
description: "Loan Fee Income"
# Optional: Penalties
- legType: PenaltyIncome
accountCode: "4020300"
description: "Late Payment Penalties"
# Optional: Write-offs
- legType: WriteOffExpensePrincipal
accountCode: "5030100"
description: "Bad Debt Expense - Principal"
Transaction Flow (Disbursement of ₦100,000):
DR: PortfolioControl (1020100) ₦100,000
CR: Cash/Disbursement Account ₦100,000
Transaction Flow (Repayment: ₦10,000 Principal + ₦2,000 Interest):
DR: Cash Account ₦12,000
CR: PortfolioControl (1020100) ₦10,000
CR: InterestIncome (4020100) ₦2,000
Example 2: Accrual Accounting (Standard Banking)
accountingConfig:
interestRecognitionMethod: Accrual
accountLegs:
# Loan principal outstanding
- legType: PortfolioControl
accountCode: "1020100"
description: "Term Loan Portfolio"
# Accrued interest receivable
- legType: InterestReceivable
accountCode: "1020200"
description: "Interest Receivable on Term Loans"
# Interest income (accrued daily)
- legType: InterestIncome
accountCode: "4020100"
description: "Interest Income on Term Loans"
# Fee receivable
- legType: FeeReceivable
accountCode: "1020300"
description: "Fee Receivable"
# Fee income
- legType: FeeIncome
accountCode: "4020200"
description: "Loan Fee Income"
# Penalty receivable
- legType: PenaltyReceivable
accountCode: "1020400"
description: "Penalty Receivable"
# Penalty income
- legType: PenaltyIncome
accountCode: "4020300"
description: "Penalty Income"
# Write-off expense accounts
- legType: WriteOffExpensePrincipal
accountCode: "5030100"
description: "Write-off Expense - Principal"
- legType: WriteOffExpenseInterest
accountCode: "5030200"
description: "Write-off Expense - Interest"
Transaction Flow (Daily Interest Accrual of ₦50):
DR: InterestReceivable (1020200) ₦50
CR: InterestIncome (4020100) ₦50
Transaction Flow (Repayment: ₦10,000 Principal + ₦2,000 Interest):
DR: Cash Account ₦12,000
CR: PortfolioControl (1020100) ₦10,000
CR: InterestReceivable (1020200) ₦2,000
Transaction Flow (Write-off: ₦5,000 Principal + ₦500 Interest):
DR: WriteOffExpensePrincipal (5030100) ₦5,000
DR: WriteOffExpenseInterest (5030200) ₦500
CR: PortfolioControl (1020100) ₦5,000
CR: InterestReceivable (1020200) ₦500
Example 3: Multi-Company Configuration
accountingConfig:
interestRecognitionMethod: Accrual
accountLegs:
# Company A - Retail loans
- legType: PortfolioControl
accountCode: "1020100"
companyCode: "RETAIL"
description: "Retail Loan Portfolio"
# Company B - SME loans
- legType: PortfolioControl
accountCode: "1020150"
companyCode: "SME"
description: "SME Loan Portfolio"
# Shared interest income (no company code)
- legType: InterestIncome
accountCode: "4020100"
description: "Interest Income (All Companies)"
# ... other legs
Transaction Processing
How BPMCore Uses AccountingConfig
All BPMCore loan transaction handlers follow this pattern:
Implementation details removed for security.
Contact support for implementation guidance.
Repayment Waterfall Logic
When a payment is received, it's applied in this order:
- Penalty (oldest first)
- Fee (processing, management)
- Interest (accrued)
- Principal (remaining amount)
Example: ₦15,000 Payment
Outstanding Balances:
- Penalty: ₦500
- Fee: ₦1,000
- Interest: ₦3,500
- Principal: ₦95,000
Payment Allocation:
1. ₦500 → PenaltyReceivable
2. ₦1,000 → FeeReceivable
3. ₦3,500 → InterestReceivable
4. ₦10,000 → PortfolioControl (principal)
Total: ₦15,000
Validation Rules
The system automatically validates:
- Required Legs Present: Based on methodology
- Valid Account Codes: GL accounts must exist
- No Duplicates: Each leg type appears once per company
- Methodology Consistency: Accrual requires receivable accounts
Example Validation Error:
# ⌠INVALID: Missing InterestReceivable for Accrual
accountingConfig:
interestRecognitionMethod: Accrual
accountLegs:
- legType: PortfolioControl
accountCode: "1020100"
- legType: InterestIncome
accountCode: "4020100"
# Missing: InterestReceivable (required for Accrual)
Error Message: "Accrual accounting requires InterestReceivable account leg"
Advanced Scenarios
Scenario 1: Interest Capitalization
When unpaid interest is added to principal:
// Accrual: Move from InterestReceivable to PortfolioControl
DR: InterestReceivable (1020200) (₦1,000) [Reduce receivable]
CR: InterestReceivable (1020200) ₦1,000 [Reverse accrual]
DR: PortfolioControl (1020100) ₦1,000 [Increase principal]
CR: InterestIncome (4020100) ₦1,000 [Recognize as income]
Scenario 2: Partial Write-off (Restructuring)
When ₦10,000 of ₦50,000 loan is forgiven:
DR: WriteOffExpensePrincipal (5030100) ₦10,000
CR: PortfolioControl (1020100) ₦10,000
New Principal: ₦40,000
Scenario 3: Loan Recovery (After Write-off)
When previously written-off ₦5,000 is recovered:
DR: Cash Account ₦5,000
CR: WriteOffExpensePrincipal (5030100) ₦5,000 [Reverse expense]
OR (alternative treatment):
DR: Cash Account ₦5,000
CR: RecoveryIncome (4020400) ₦5,000 [New income]
Migration from V1
V1 Structure (Old)
Implementation details removed for security.
Contact support for implementation guidance.
V2 Structure (New)
accountingConfig:
interestRecognitionMethod: Accrual
accountLegs:
- legType: PortfolioControl
accountCode: "1020100"
- legType: InterestReceivable
accountCode: "1020200"
- legType: InterestIncome
accountCode: "4020100"
Migration Benefits
- Flexibility: Add custom legs without schema changes
- Multi-Company: Support multiple companies in one product
- Granularity: Separate write-off by component (principal vs interest)
- Validation: Built-in YAML validation
- Documentation: Self-documenting with descriptions
Automatic V1 Fallback
If ConfigData is null, the system automatically uses V1:
Implementation details removed for security.
Contact support for implementation guidance.
Troubleshooting
Common Issues
Issue 1: Missing Required Leg
Error: "PortfolioControl account leg is required"
Solution:
accountingConfig:
interestRecognitionMethod: Cash
accountLegs:
- legType: PortfolioControl # ✅ Add this
accountCode: "1020100"
Issue 2: Invalid GL Account
Error: "GL Account '9999999' not found"
Solution: Verify account code exists in Chart of Accounts
Issue 3: Receivable Missing for Accrual
Error: "Accrual methodology requires InterestReceivable"
Solution: Add missing receivable accounts for Accrual
Issue 4: Write-off Without Expense Account
Error: "WriteOffExpensePrincipal account required for write-off transactions"
Solution: Add write-off expense accounts if write-offs are expected
Best Practices
1. Use Accrual for Regulated Institutions
# ✅ RECOMMENDED: IFRS 9 compliance
interestRecognitionMethod: Accrual
2. Always Include Write-off Accounts
# ✅ GOOD: Prepared for NPLs
- legType: WriteOffExpensePrincipal
accountCode: "5030100"
- legType: WriteOffExpenseInterest
accountCode: "5030200"
3. Document Each Leg
# ✅ GOOD: Clear descriptions
- legType: PortfolioControl
accountCode: "1020100"
description: "Personal loan portfolio - retail customers"
4. Separate Write-off by Type
# ✅ GOOD: Track principal vs interest separately
- legType: WriteOffExpensePrincipal
accountCode: "5030100" # Principal losses
- legType: WriteOffExpenseInterest
accountCode: "5030200" # Interest losses
5. Plan for Recoveries
# ✅ GOOD: Use same write-off account for recoveries
# OR create separate recovery income account
- legType: RecoveryIncome # Future extension
accountCode: "4020400"
Related Documentation
- Loan Product Overview
- Personal Loan Configuration
- Business Loan Configuration
- Overdraft Configuration
- Loan Transaction API
- Loan Write-off Process
Version History
| Version | Date | Changes |
|---|---|---|
| V2.0 | Jan 2026 | Initial V2 AccountingConfig documentation |
| V1.0 | - | Legacy table-based accounting (deprecated) |
Support
For questions or issues:
- Check Troubleshooting section
- Review Sample Configurations
- Contact: Technical Support Team