Admin-Assisted Loan Creation
Overview
These commands allow a back-office administrator to create a loan application on behalf of a customer — either an existing channel customer or a brand-new walk-in customer.
The admin must have the Channels.AdminCreateLoanOnBehalf permission ("chn_admin_create_loan_on_behalf").
Typical workflow:
1. AdminCreateLoanForNewCustomerBpmCommand ← new walk-in customer
OR
AdminCreateLoanForExistingCustomerBpmCommand ← existing channel customer
↓
2. (Optional) AdminSendWelcomeEmailToCustomerBpmCommand ← send login credentials
↓
3. Existing loan approval workflow continues as normal
AdminCreateLoanForNewCustomerBpmCommand
Creates a new SelfServiceUser profile (CUSTOMER classification) and a loan quote in a single operation.
The customer account is immediately Active. No OTP is required — the admin is the verified party.
A hashed temporary password is set on the account but not returned in the response; use AdminSendWelcomeEmailToCustomerBpmCommand to deliver credentials to the customer.
Request
{
"cmd": "AdminCreateLoanForNewCustomerBpmCommand",
"data": {
"firstName": "Adaeze",
"lastName": "Okonkwo",
"middleName": "Grace",
"mobileNumber": "08031234567",
"mobileCountryCode": "+234",
"emailAddress": "adaeze.okonkwo@example.com",
"dateOfBirth": "1990-04-15",
"gender": "Female",
"biometricsId": "22345678901",
"productCode": "PERSONAL_LOAN_01",
"loanAmount": 500000,
"loanTenor": 12,
"loanTenorType": 2,
"branchId": 3
}
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
firstName | string | Yes | Customer first name |
lastName | string | Yes | Customer last name |
middleName | string | No | Customer middle name |
mobileNumber | string | Yes | Mobile number (digits only, no country code prefix) |
mobileCountryCode | string | Yes | e.g. "+234" |
emailAddress | string | Yes | Must be unique across all channel customers |
dateOfBirth | string | Yes | ISO date format: "YYYY-MM-DD" |
gender | string | Yes | e.g. "Male" / "Female" |
biometricsId | string | Yes | BVN — must be unique. Validated against core banking. |
productCode | string | Yes | Loan product code from YAML configuration |
loanAmount | decimal | Yes | Requested loan amount |
loanTenor | int | Yes | Loan duration as a number |
loanTenorType | int | Yes | 0 = Days, 1 = Weeks, 2 = Months, 3 = Years |
branchId | long | No | Branch to assign. Defaults to the admin's own branch, then the system default. |
Uniqueness Validation
The system rejects the request if any of the following already exist on another SelfServiceUser:
emailAddressbiometricsId(BVN)mobileNumber
Response
{
"isSuccessful": true,
"statusCode": "00",
"message": "Customer profile and loan application created successfully. Use 'Send Welcome Email' to deliver login credentials to the customer.",
"data": {
"selfServiceUserId": 2048,
"userId": "adaeze.okonkwo@example.com",
"loanQuoteId": 501,
"requestId": "02048PERSONAL_LOAN_01218",
"productCode": "PERSONAL_LOAN_01",
"loanAmount": 500000
}
}
AdminCreateLoanForExistingCustomerBpmCommand
Creates a loan quote for an existing channel customer. Supply at least one lookup identifier.
Request
{
"cmd": "AdminCreateLoanForExistingCustomerBpmCommand",
"data": {
"emailAddress": "adaeze.okonkwo@example.com",
"productCode": "PERSONAL_LOAN_01",
"loanAmount": 250000,
"loanTenor": 6,
"loanTenorType": 2,
"branchId": 3
}
}
Customer Lookup Fields (at least one required)
| Field | Type | Description |
|---|---|---|
selfServiceUserId | long | Database ID of the SelfServiceUser |
emailAddress | string | Registered email address |
mobileNumber | string | Registered mobile number |
biometricsId | string | BVN |
Loan Fields
| Field | Type | Required | Description |
|---|---|---|---|
productCode | string | Yes | Loan product code |
loanAmount | decimal | Yes | Requested amount |
loanTenor | int | Yes | Duration |
loanTenorType | int | Yes | 0=Days, 1=Weeks, 2=Months, 3=Years |
branchId | long | No | Defaults to admin's branch |
Validation
- Customer must have
UserClassification == CUSTOMER - Customer must not be
BlackListedorDeactivated - BVN is re-validated against core banking if present
AdminSendWelcomeEmailToCustomerBpmCommand
Sends a welcome email to a channel customer. Generates a fresh temporary password, saves it to the customer's account, and emails it to them in plaintext.
This command is independent of loan creation — it can be triggered at any time after account creation.
Request
{
"cmd": "AdminSendWelcomeEmailToCustomerBpmCommand",
"data": {
"selfServiceUserId": 2048,
"subject": "Welcome to EmpireTrust Digital Banking",
"message": "Please visit any of our branches to complete your KYC."
}
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
selfServiceUserId | long | Yes | The SelfServiceUser.Id of the customer |
subject | string | No | Email subject override. Defaults to "Welcome — Your channel account is ready" |
message | string | No | Extra paragraph appended to the standard email body |
What it does
- Generates a new 10-character temporary password
- Hashes it and saves it as the customer's current password
- Clears any login blocks (
IsPasswordBlocked = false,FailedLoginAttempts = 0) - Emails the plaintext temporary password to the customer's registered email
- Does not return the password in the API response
Response
{
"isSuccessful": true,
"statusCode": "00",
"message": "Welcome email sent to 'adaeze.okonkwo@example.com'. The customer can now log in with their new temporary password.",
"data": {
"selfServiceUserId": 2048,
"emailAddress": "adaeze.okonkwo@example.com"
}
}
Developer Notes (Tunde)
| Item | Detail |
|---|---|
| Command file | CB.Administration.Api/Commands/BPM/SelfService/AdminLoanCreationBpmCommands.cs |
| Handlers | AdminLoanCreationBpmCommandHandlers, AdminSendWelcomeEmailToCustomerBpmCommandHandler |
| New user classification | SelfUserClassificationEnum.CUSTOMER |
| No OTP flow | Customer created directly as UserStatus.Active — admin is the verified party |
| Temp password | Set internally, never returned in response. Delivered only via welcome email command. |
| Branch resolution | Caller-supplied branchId → admin's branch (by email lookup) → system default branch |
| Initiator tracking | LoanQuote.InitiatorSelfServiceUserId = admin's SelfServiceUser.Id (resolved by email from JWT) |
| CBS validation | IBankOneService.ValidateCustomerExistsOnCoreBankingAsync(bvn, mobile, email, false) |
| Permission | PermissionStandardCodes.Channels.AdminCreateLoanOnBehalf ("chn_admin_create_loan_on_behalf") |
| Product config | Product details read from YAML via ConfigDefinition where Code == "loanProductConfiguration" |