Disburse Loan
Overview
Disburse approved loan funds to the customer's designated account. This command initiates the transfer of loan principal from the institution's loan GL account to the customer's account after successful loan approval.
Endpoint
POST /api/bpm/cmd/InitiateDisbursementFromLoanChannel
Authentication
Requires valid JWT token with loans.disburse permission.
Command Structure
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
sourceAccount | string | Yes | Source GL account number for loan funds (must be configured disbursement channel) |
batchDescription | string | No | Description of the disbursement batch (for multiple disbursements) |
disbursementItemModels | array | Yes | Array of disbursement items (one per loan) |
Disbursement Item Model
| Field | Type | Required | Description |
|---|---|---|---|
amount | decimal | Yes | Loan disbursement amount (principal minus any upfront charges) |
bankCode | string | Yes | Destination bank code (e.g., "033" for United Bank for Africa) |
destinationAccount | string | Yes | Customer's account number to receive funds |
narration | string | Yes | Transaction narration (e.g., "Loan Disbursement - LN123456") |
loanAccountId | guid | Yes | Unique identifier of the loan account |
Response
Success Response (200 OK)
{
"isSuccessful": true,
"message": "Loan disbursement initiated successfully",
"data": {
"batchId": "BATCH-20260101-001",
"disbursementId": "DISB-20260101-001",
"transactionReference": "TXN-20260101-123456",
"status": "SETTLED",
"disbursementDate": "2026-01-01T10:30:00Z"
}
}
Error Response (400 Bad Request)
{
"isSuccessful": false,
"message": "Loan disbursement failed",
"errors": [
{
"code": "LOAN_NOT_APPROVED",
"message": "Loan must be in APPROVED status before disbursement"
}
]
}
Loan Disbursement States
Currently, loan disbursements are directly settled without an intermediate pending state. All disbursements are created with SETTLED status immediately upon successful validation.
Current State Flow
Future Approval Workflow Support
In a future release, loan disbursements may support an approval workflow similar to deposits and withdrawals. The planned implementation would include:
- PENDING State: Disbursement awaits approval
- requireApproval Parameter: Optional flag to enable approval workflow
- Approval Thresholds: Configurable limits (e.g., amounts > ₦1M require approval)
- Universal Commands: ApproveTransaction, RejectTransaction, CancelTransaction, ReverseTransaction
Planned Approval Workflow (Future)
Sample Requests
1. Standard Loan Disbursement
Disburse a ₦500,000 personal loan to customer account:
Request:
{
"sourceAccount": "1000001",
"batchDescription": "January 2026 Loan Disbursements",
"disbursementItemModels": [
{
"amount": 500000.00,
"bankCode": "033",
"destinationAccount": "2001234567",
"narration": "Loan Disbursement - LN123456",
"loanAccountId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
]
}
Response:
{
"isSuccessful": true,
"message": "Loan disbursement initiated successfully",
"data": {
"batchId": "BATCH-20260101-001",
"disbursementId": "DISB-20260101-001",
"transactionReference": "TXN-20260101-123456",
"status": "SETTLED",
"disbursementDate": "2026-01-01T10:30:00Z",
"loanAccountId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"disbursementAmount": 500000.00,
"destinationAccount": "2001234567",
"bankCode": "033"
}
}
Business Rules Applied:
- ✅ Loan must be in
APPROVEDstatus - ✅ Source account must be configured disbursement channel
- ✅ Disbursement channel must be enabled
- ✅ Destination account validated
- ✅ Loan schedules automatically generated
- ✅ Loan state changed to
DISBURSED
2. Loan Disbursement with Upfront Charges
Disburse a ₦1,000,000 SME loan with processing fee deducted:
Request:
{
"sourceAccount": "1000001",
"batchDescription": "SME Loan Disbursements - Q1 2026",
"disbursementItemModels": [
{
"amount": 980000.00,
"bankCode": "044",
"destinationAccount": "3001234567",
"narration": "SME Loan Disbursement - LN789012 (₦20K fee deducted)",
"loanAccountId": "b2c3d4e5-f6g7-8901-bcde-f12345678901"
}
]
}
Response:
{
"isSuccessful": true,
"message": "Loan disbursement initiated successfully",
"data": {
"batchId": "BATCH-20260101-002",
"disbursementId": "DISB-20260101-002",
"transactionReference": "TXN-20260101-234567",
"status": "SETTLED",
"disbursementDate": "2026-01-01T11:15:00Z",
"loanAccountId": "b2c3d4e5-f6g7-8901-bcde-f12345678901",
"loanPrincipal": 1000000.00,
"upfrontCharges": 20000.00,
"disbursementAmount": 980000.00,
"destinationAccount": "3001234567",
"bankCode": "044"
}
}
Charge Calculation:
Loan Principal: ₦1,000,000.00
Processing Fee (2%): -₦20,000.00
-----------------------------------
Disbursement Amount: ₦980,000.00
Note: Customer repays ₦1,000,000 + interest, but receives ₦980,000.
3. Inter-Bank Loan Disbursement
Disburse loan to different bank:
Request:
{
"sourceAccount": "1000001",
"batchDescription": "Inter-Bank Loan Disbursements",
"disbursementItemModels": [
{
"amount": 2500000.00,
"bankCode": "058",
"destinationAccount": "4001234567",
"narration": "Mortgage Loan Disbursement - LN345678",
"loanAccountId": "c3d4e5f6-g7h8-9012-cdef-123456789012"
}
]
}
Response:
{
"isSuccessful": true,
"message": "Loan disbursement initiated successfully",
"data": {
"batchId": "BATCH-20260101-003",
"disbursementId": "DISB-20260101-003",
"transactionReference": "TXN-20260101-345678",
"status": "SETTLED",
"disbursementDate": "2026-01-01T14:30:00Z",
"loanAccountId": "c3d4e5f6-g7h8-9012-cdef-123456789012",
"disbursementAmount": 2500000.00,
"destinationAccount": "4001234567",
"destinationBank": "GTBank (058)",
"transferMethod": "NIBSS",
"estimatedArrival": "2026-01-01T15:00:00Z"
}
}
Inter-Bank Processing:
- ✅ Routed through NIBSS instant payment
- ✅ Transfer confirmation expected within 30 minutes
- ✅ Customer notified via SMS/Email
- ✅ External transaction reference recorded
4. Batch Loan Disbursement
Disburse multiple loans in single batch:
Request:
{
"sourceAccount": "1000001",
"batchDescription": "Salary Advance Loans - January 2026",
"disbursementItemModels": [
{
"amount": 50000.00,
"bankCode": "033",
"destinationAccount": "5001234567",
"narration": "Salary Advance - LN111111",
"loanAccountId": "d4e5f6g7-h8i9-0123-defg-234567890123"
},
{
"amount": 75000.00,
"bankCode": "033",
"destinationAccount": "5001234568",
"narration": "Salary Advance - LN222222",
"loanAccountId": "e5f6g7h8-i9j0-1234-efgh-345678901234"
},
{
"amount": 100000.00,
"bankCode": "044",
"destinationAccount": "6001234569",
"narration": "Salary Advance - LN333333",
"loanAccountId": "f6g7h8i9-j0k1-2345-fghi-456789012345"
}
]
}
Response:
{
"isSuccessful": true,
"message": "Batch loan disbursement initiated successfully",
"data": {
"batchId": "BATCH-20260101-004",
"totalDisbursements": 3,
"totalAmount": 225000.00,
"successfulDisbursements": 3,
"failedDisbursements": 0,
"disbursementDate": "2026-01-01T15:45:00Z",
"disbursements": [
{
"disbursementId": "DISB-20260101-004-01",
"loanAccountId": "d4e5f6g7-h8i9-0123-defg-234567890123",
"amount": 50000.00,
"status": "SETTLED"
},
{
"disbursementId": "DISB-20260101-004-02",
"loanAccountId": "e5f6g7h8-i9j0-1234-efgh-345678901234",
"amount": 75000.00,
"status": "SETTLED"
},
{
"disbursementId": "DISB-20260101-004-03",
"loanAccountId": "f6g7h8i9-j0k1-2345-fghi-456789012345",
"amount": 100000.00,
"status": "SETTLED"
}
]
}
}
Batch Processing:
- All disbursements processed atomically
- If one fails, entire batch fails (transaction integrity)
- Individual status tracked per disbursement
- Batch audit log created
Universal Transaction Commands
Once disbursed, loan transactions support universal transaction management commands:
Reverse Loan Disbursement
POST /api/bpm/cmd/ReverseTransaction
{
"transactionId": "guid-of-disbursement-transaction",
"reason": "Customer requested cancellation before fund utilization",
"reversalNarration": "Reversal: Loan Disbursement - LN123456"
}
Effect:
- Transaction state: SETTLED → REVERSED
- Loan state: DISBURSED → APPROVED (reverted)
- Balance: Funds returned to source GL
- Loan schedules: Deactivated/removed
- Audit trail: Reversal logged with reason
Loan disbursement reversals typically have strict conditions:
- Must be reversed within 24-48 hours
- Customer account must have sufficient balance (if funds already withdrawn)
- No repayments should have been made yet
- Approval from senior management may be required
Disbursement Validations
Pre-Disbursement Checks
| Validation | Check | Error Code |
|---|---|---|
| Loan Status | Loan must be in APPROVED status | LOAN_NOT_APPROVED |
| Source Account | Must be configured disbursement channel | INVALID_SOURCE_ACCOUNT |
| Channel Status | Disbursement channel must be enabled | CHANNEL_DISABLED |
| Destination Account | Account number format valid | INVALID_DESTINATION_ACCOUNT |
| Bank Code | Valid Nigerian bank code | INVALID_BANK_CODE |
| Amount | Must match approved loan amount (minus charges) | AMOUNT_MISMATCH |
| Duplicate Check | Loan not already disbursed | LOAN_ALREADY_DISBURSED |
| GL Balance | Source GL has sufficient balance | INSUFFICIENT_GL_BALANCE |
Example Validation Failures
1. Loan Not Approved:
{
"isSuccessful": false,
"message": "Loan disbursement failed",
"errors": [
{
"code": "LOAN_NOT_APPROVED",
"message": "Loan LN123456 is in PENDING status. Only APPROVED loans can be disbursed.",
"loanStatus": "PENDING",
"requiredStatus": "APPROVED"
}
]
}
2. Source Account Not Configured:
{
"isSuccessful": false,
"message": "The source account selected has not been configured for disbursement.",
"errors": [
{
"code": "INVALID_SOURCE_ACCOUNT",
"message": "Account 1000099 is not configured as a disbursement channel",
"sourceAccount": "1000099"
}
]
}
3. Loan Already Disbursed:
{
"isSuccessful": false,
"message": "Loan disbursement failed",
"errors": [
{
"code": "LOAN_ALREADY_DISBURSED",
"message": "Loan LN123456 was already disbursed on 2025-12-15",
"disbursementDate": "2025-12-15T10:30:00Z",
"disbursementAmount": 500000.00
}
]
}
Balance Impact
Accounting Entries
Loan Disbursement (₦500,000):
| Account | Debit | Credit | Description |
|---|---|---|---|
| Customer Savings Account | ₦500,000 | - | Funds credited to customer |
| Loan Receivable GL | ₦500,000 | - | Loan asset created |
| Loan Disbursement GL | - | ₦1,000,000 | Source of funds |
Net Effect:
Customer Account Balance: +₦500,000
Loan Receivable (Asset): +₦500,000
Loan Disbursement GL: -₦1,000,000
With Upfront Charges
Loan Disbursement with Processing Fee (₦1,000,000 loan, 2% fee):
| Account | Debit | Credit | Description |
|---|---|---|---|
| Customer Savings Account | ₦980,000 | - | Net funds to customer |
| Fee Income GL | ₦20,000 | - | Processing fee earned |
| Loan Receivable GL | ₦1,000,000 | - | Full loan principal |
| Loan Disbursement GL | - | ₦1,000,000 | Source of funds |
Net Effect:
Customer Account Balance: +₦980,000
Fee Income: +₦20,000
Loan Receivable (Asset): +₦1,000,000
Loan Disbursement GL: -₦1,000,000
Configuration
Disbursement Channel Configuration
Configure source accounts for loan disbursements:
{
"accountNumber": "1000001",
"accountName": "Loan Disbursement GL",
"disbursementSourceAccountGroup": "DirectLoanDisbursement",
"isEnabled": true,
"isDirectWithoutSourceGL": false,
"sourceGLAccount": "1000001",
"requiresApproval": false,
"dailyLimit": 50000000.00,
"transactionLimit": 10000000.00,
"allowedBankCodes": ["033", "044", "058", "063"],
"restrictToInternalAccounts": false
}
Future Approval Thresholds (Planned)
When approval workflow is implemented, configurable thresholds:
| Tier | Amount Range | Approval Required | Approver Role |
|---|---|---|---|
| Tier 1 | ≤ ₦500K | No | Auto-approved |
| Tier 2 | ₦500K - ₦2M | Yes | Branch Manager |
| Tier 3 | ₦2M - ₦10M | Yes | Regional Manager |
| Tier 4 | > ₦10M | Yes | Head of Credit + CFO |
Best Practices
When to Disburse Loans
✅ DO Disburse When:
- Loan fully approved through workflow
- All documentation completed
- Customer identity verified (BVN, KYC)
- Collateral registered (if applicable)
- Insurance arranged (if required)
- Destination account validated
❌ DO NOT Disburse When:
- Loan still in PENDING or DRAFT status
- Customer has adverse credit bureau report
- Regulatory compliance checks incomplete
- Destination account flagged for fraud
- Customer account dormant or inactive
Security Considerations
-
Source Account Protection
- Restrict disbursement channels to authorized GL accounts only
- Monitor for unusual disbursement patterns
- Implement daily/monthly disbursement limits
- Require dual authorization for high-value loans
-
Destination Account Validation
- Verify account ownership matches loan applicant
- Check for account freezes or restrictions
- Validate bank code and account format
- Confirm account is active and operational
-
Fraud Prevention
- Compare disbursement amount with approved loan amount
- Flag rapid successive disbursements to same account
- Monitor for unusual destination patterns
- Implement velocity checks (max disbursements per day)
-
Audit Trail
- Log all disbursement attempts (success and failure)
- Record IP address and user details
- Track approval chain for high-value loans
- Maintain immutable audit logs
Integration with Loan Lifecycle
Loan State Transitions
Disbursement Triggers
Automatic Triggers (if configured):
- Loan approved → Auto-disburse to registered account
- Collateral registered → Trigger disbursement
- Insurance policy active → Release funds
Manual Triggers:
- Credit officer initiates disbursement
- Batch disbursement scheduled (e.g., payroll loans)
- Customer requests withdrawal of funds
Error Scenarios
Common Error Codes
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
LOAN_NOT_APPROVED | 400 | Loan not in APPROVED status | Complete loan approval workflow first |
INVALID_SOURCE_ACCOUNT | 400 | Source account not configured | Configure disbursement channel in admin |
CHANNEL_DISABLED | 400 | Disbursement channel disabled | Enable channel or use alternative source |
INVALID_DESTINATION_ACCOUNT | 400 | Invalid account format/number | Verify customer account details |
INVALID_BANK_CODE | 400 | Bank code not recognized | Use valid CBN bank code |
AMOUNT_MISMATCH | 400 | Amount doesn't match loan principal | Recalculate with correct charges |
LOAN_ALREADY_DISBURSED | 409 | Loan already disbursed | Check loan history, may need reversal |
INSUFFICIENT_GL_BALANCE | 400 | Source GL insufficient funds | Fund source GL account |
NIBSS_TIMEOUT | 504 | External payment gateway timeout | Retry after confirming with NIBSS |
DUPLICATE_REQUEST | 409 | Duplicate transaction reference | Use unique reference per request |
Related Commands
- Create Loan Account - Create new loan
- Approve Loan - Approve loan for disbursement
- Record Repayment - Record loan repayment
- Reverse Transaction - Reverse disbursement
- Universal Transaction Management - Transaction commands
Audit & Compliance
Audit Log Entry
{
"eventType": "LoanDisbursed",
"timestamp": "2026-01-01T10:30:00Z",
"userId": "user-123",
"userName": "Jane Smith",
"role": "Credit Officer",
"action": "InitiateDisbursementFromLoanChannel",
"loanAccountId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"loanNumber": "LN123456",
"amount": 500000.00,
"sourceAccount": "1000001",
"destinationAccount": "2001234567",
"bankCode": "033",
"transactionReference": "TXN-20260101-123456",
"status": "SETTLED",
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"branchId": "branch-456",
"branchName": "Lagos Main Branch"
}
Regulatory Reporting
Loan disbursements must be reported to:
- Central Bank of Nigeria (CBN) - Monthly credit data returns
- Credit Bureau - Loan activation notification
- Tax Authority - For interest income tracking
- Anti-Money Laundering (AML) - High-value disbursements (> ₦5M)
Performance Characteristics
| Metric | Value | Notes |
|---|---|---|
| Average Processing Time | 2-5 seconds | Internal accounts |
| Inter-Bank Processing | 30-60 seconds | Via NIBSS |
| Batch Processing | 10-50 items/min | Depends on bank integrations |
| Success Rate | > 98% | Excluding validation failures |
| Reversal Window | 24-48 hours | Institution policy |
Summary
Loan disbursement is a critical operation that transfers approved loan funds to customers. Currently implemented with direct settlement (SETTLED status immediately), with planned support for approval workflows in future releases.
Key Points:
- ✅ All disbursements currently go directly to SETTLED status
- ✅ Source account must be configured disbursement channel
- ✅ Comprehensive validation before disbursement
- ✅ Supports both internal and inter-bank transfers
- ✅ Batch disbursement capability for multiple loans
- ✅ Full audit trail and compliance reporting
- ⏳ Future: Approval workflow with PENDING state
- ⏳ Future: Configurable approval thresholds
Transaction States:
- SETTLED: Direct execution (current default)
- REVERSED: Funds returned to source GL
Planned Enhancement:
- PENDING: Awaiting approval (future release)
- CANCELLED: Rejected before disbursement (future release)
Product Documentation
For business process and technical flow details, see: