CreateSelfServiceLoanQuoteCommand
Overview
Creates a new loan application (loan quote) in the system. This is the starting point for the loan origination process. Once created, additional information like identity documents, guarantors, credit bureau searches, and bank statements can be attached to the loan quote.
Command Structure
{
"cmd": "CreateSelfServiceLoanQuoteCommand",
"data": "{\"selfServiceUserId\":123,\"selfServiceBranchId\":5,\"loanProductCode\":\"PERSONAL_LOAN\",\"loanAmount\":500000,\"tenor\":12,\"purpose\":\"Business expansion\"}"
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
selfServiceUserId | long | Yes | The ID of the customer applying for the loan |
selfServiceBranchId | long | Yes | The branch where the loan is being processed |
loanProductCode | string | Yes | The code of the loan product (e.g., "PERSONAL_LOAN", "BUSINESS_LOAN") |
loanAmount | decimal | Yes | The requested loan amount |
tenor | int | Yes | Loan tenure in months |
purpose | string | No | Purpose of the loan (optional) |
interestRate | decimal | No | Custom interest rate (if allowed by product) |
repaymentFrequency | string | No | "MONTHLY", "QUARTERLY", etc. (defaults to product setting) |
Response Structure
Success Response
{
"ok": true,
"statusCode": "00",
"message": "Loan quote created successfully",
"outData": {
"loanQuoteId": 110,
"referenceNumber": "LQ-2024-00110",
"loanAmount": 500000,
"tenor": 12,
"interestRate": 18.5,
"monthlyRepayment": 45625.50,
"totalRepayment": 547506,
"approvalState": "NOT_STARTED",
"currentApprovalLevel": 0,
"createdAt": "2024-01-12T10:30:00Z"
}
}
Error Response
{
"ok": false,
"statusCode": "04",
"message": "Invalid loan product code",
"outData": null
}
Loan Product Codes
Common loan product codes available:
| Product Code | Description | Typical Tenor | Interest Rate Range |
|---|---|---|---|
PERSONAL_LOAN | Personal/Consumer Loan | 6-36 months | 15-24% p.a. |
BUSINESS_LOAN | SME Business Loan | 12-60 months | 18-28% p.a. |
SALARY_ADVANCE | Salary Advance Loan | 1-6 months | 5-10% p.a. |
ASSET_FINANCE | Vehicle/Equipment Finance | 12-60 months | 16-22% p.a. |
OVERDRAFT | Overdraft Facility | 12 months | 20-30% p.a. |
Loan Quote States
After creation, the loan quote progresses through these states:
| State | Description | Next Action |
|---|---|---|
NOT_STARTED | Just created | Add supporting documents |
PENDING_APPROVAL | Submitted for approval | Await approval workflow |
FULLY_APPROVED | All approvals completed | Disburse loan |
REJECTED | Application rejected | Review or reapply |
DISBURSED | Loan disbursed | Loan account created |
Approval Levels
The currentApprovalLevel indicates where the loan is in the approval chain:
| Level | Code | Description | Typical Threshold |
|---|---|---|---|
| 0 | NOT_STARTED | Not yet submitted | - |
| 1 | BRANCH | Branch Manager | Up to ₦1M |
| 2 | AREA | Area Manager | Up to ₦5M |
| 3 | DIVISION | Division Manager | Up to ₦10M |
| 4 | CREDIT_ADMIN | Credit Administrator | Up to ₦20M |
| 5 | HEAD_CREDIT_ADMIN | Head of Credit | Up to ₦50M |
| 6 | CONTROL_OFFICER | Control Officer | Up to ₦100M |
| 7 | MD | Managing Director | Above ₦100M |
Workflow After Creation
Integration Examples
cURL
curl -X POST https://api.yourbank.com/commands \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"cmd": "CreateSelfServiceLoanQuoteCommand",
"data": "{\"selfServiceUserId\":123,\"selfServiceBranchId\":5,\"loanProductCode\":\"PERSONAL_LOAN\",\"loanAmount\":500000,\"tenor\":12,\"purpose\":\"Business expansion\"}"
}'
JavaScript (Fetch API)
const response = await fetch('https://api.yourbank.com/commands', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
cmd: 'CreateSelfServiceLoanQuoteCommand',
data: JSON.stringify({
selfServiceUserId: 123,
selfServiceBranchId: 5,
loanProductCode: 'PERSONAL_LOAN',
loanAmount: 500000,
tenor: 12,
purpose: 'Business expansion'
})
})
});
const result = await response.json();
console.log('Loan Quote ID:', result.outData.loanQuoteId);
C# (MediatR)
var command = new CreateSelfServiceLoanQuoteCommand
{
Data = JsonConvert.SerializeObject(new
{
selfServiceUserId = 123,
selfServiceBranchId = 5,
loanProductCode = "PERSONAL_LOAN",
loanAmount = 500000,
tenor = 12,
purpose = "Business expansion"
})
};
var response = await _mediator.Send(command);
if (response.Ok)
{
var loanQuoteId = response.OutData.loanQuoteId;
// Proceed with adding documents
}
Validation Rules
The system validates:
- User Exists:
selfServiceUserIdmust be a valid customer - Branch Exists:
selfServiceBranchIdmust be a valid branch - Product Valid:
loanProductCodemust exist and be active - Amount Within Limits: Loan amount must be within product's min/max limits
- Tenor Valid: Tenor must be within product's allowed range
- No Duplicate: Customer cannot have multiple pending applications for same product
Error Scenarios
| Error | Status Code | Cause | Solution |
|---|---|---|---|
| User not found | 04 | Invalid selfServiceUserId | Verify user exists |
| Branch not found | 04 | Invalid selfServiceBranchId | Use valid branch ID |
| Invalid product | 04 | Product code doesn't exist | Check available products |
| Amount too low | 99 | Below product minimum | Increase loan amount |
| Amount too high | 99 | Above product maximum | Reduce loan amount or use different product |
| Duplicate application | 99 | Pending application exists | Complete or cancel existing |
Best Practices
- Validate User First: Check user exists and is eligible before creating quote
- Calculate Before Submit: Use loan calculator to show customer repayment amount
- Set Realistic Tenor: Match tenor to customer's repayment capacity
- Add Purpose: Including loan purpose helps in approval process
- Follow Up Quickly: Add all supporting documents immediately after creation
- Track Status: Poll or subscribe to status updates during approval
Technical Notes
- Entity:
LoanQuote(table:[BPMLoanSelfService].[LoanQuote]) - Primary Key:
Id(becomesloanQuoteIdin responses) - Foreign Keys:
SelfServiceUserId→SelfServiceUser.IdSelfServiceBranchId→SelfServiceBranch.Id
- Auto-Generated:
ReferenceNumber,CreatedAt,UpdateAt - Default State:
ApprovalState = NOT_STARTED,CurrentApprovalLevel = 0 - Calculation: System automatically calculates repayment schedule based on product interest rate and tenor
Related Commands
- CreateIdentityDocumentCommand - Add identity verification documents
- CreateAddressInformationCommand - Add address verification
- CreateGuarantorCommand - Add loan guarantors
- CreateCreditBureauSearchCommand - Record credit bureau checks
- CreateStatementCommand - Add bank statement analysis
- InitiateLoanApprovalWorkflow - Submit for approval
- GetCustomerLoanDetailsQuery - Retrieve loan application details