BPM V2 Commands Reference
Complete developer reference for all BPM V2 commands added to the BankLingo execution engine. These commands handle disbursement processing, NIBSS mandate/collection management, Remita loan lifecycle, and webhook integrations.
Base Endpoint
All BPM commands are executed via the unified execution endpoint:
POST /api/v1/execute
Content-Type: application/json
Authorization: Bearer {token}
Request format:
{
"cmd": "CommandName",
"data": { /* command-specific parameters */ }
}
Standard response:
{
"isSuccessful": true,
"message": "Operation completed",
"data": { /* result */ },
"statusCode": "200",
"count": 0,
"pages": 0,
"size": 0
}
1. Disbursement Commands
Manage batch disbursement processing with maker-checker workflow.
Namespace: App.Commands.BPM.Disbursement
Lifecycle: Initiated → EntriesValidated → PendingReview → ReviewAccepted → Approved → Processed
Enums
DisbursementBatchStatus
| Value | Name | Description |
|---|---|---|
0 | Initiated | Batch created, entries can be added/removed |
1 | EntriesValidated | All destination accounts validated via core banking |
2 | PendingReview | Submitted for reviewer approval |
3 | ReviewRejected | Reviewer rejected the batch |
4 | ReviewAccepted | Reviewer accepted — pending final approval |
5 | Approved | Approver approved — ready for processing |
6 | Rejected | Approver rejected the batch |
7 | Cancelled | Batch cancelled |
8 | Processed | All entries processed (disbursements sent) |
DisbursementBatchEntryStatus
| Value | Name | Description |
|---|---|---|
0 | NotValidated | Entry has not been validated yet |
1 | AccountValidationFailed | Destination account validation failed |
2 | AccountValidationSuccessful | Destination account validated successfully |
3 | DisbursementFailed | Disbursement transaction failed |
4 | DisbursementSuccessful | Disbursement transaction succeeded |
TransactionSourceEnum
| Value | Name | Description |
|---|---|---|
1 | Customer_Account | Disburse from customer account |
2 | MiniCoreBanking | Disburse via mini core-banking |
InitiateDisbursementBatchCommand
Creates a new disbursement batch with entries.
{
"cmd": "InitiateDisbursementBatchCommand",
"data": {
"batchDescription": "January payroll disbursement",
"sourceAccount": "1000012345",
"transactionSource": 1,
"entries": [
{
"DestinationAccount": "0012345678",
"Amount": 150000,
"BankCode": "058",
"Narration": "Jan salary - John Doe"
},
{
"DestinationAccount": "2012345678",
"Amount": 200000,
"BankCode": "044",
"Narration": "Jan salary - Jane Smith"
}
]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
batchDescription | string | Yes | Description of the batch |
sourceAccount | string | Yes | Source account number for debits |
transactionSource | int | No | Transaction source identifier (default: 1) |
entries | array | Yes | List of disbursement entries (max 100, total max ₦15M) |
entries[].DestinationAccount | string | Yes | Destination account number |
entries[].Amount | decimal | Yes | Amount to disburse |
entries[].BankCode | string | Yes | Destination bank code |
entries[].Narration | string | No | Transaction narration |
AddDisbursementBatchEntryCommand
Adds a single entry to an existing Initiated batch.
{
"cmd": "AddDisbursementBatchEntryCommand",
"data": {
"batchId": 42,
"bankCode": "058",
"destinationAccount": "0012345678",
"amount": 150000,
"narration": "Bonus payment"
}
}
RemoveDisbursementBatchEntryCommand
Removes an entry from an Initiated batch.
{
"cmd": "RemoveDisbursementBatchEntryCommand",
"data": { "entryId": 101 }
}
ValidateDisbursementBatchCommand
Validates all destination accounts in a batch via core banking (BankOne account lookup).
{
"cmd": "ValidateDisbursementBatchCommand",
"data": { "batchId": 42 }
}
Response includes: Valid/Invalid entry counts and per-entry validation results.
ConfirmDisbursementBatchCommand
Moves a validated batch to PendingReview.
{
"cmd": "ConfirmDisbursementBatchCommand",
"data": { "batchId": 42, "comment": "Ready for review" }
}
ReviewDisbursementBatchCommand
Reviewer accepts the batch (moves to ReviewAccepted).
{
"cmd": "ReviewDisbursementBatchCommand",
"data": { "batchId": 42, "comment": "Reviewed and confirmed" }
}
RejectDisbursementReviewCommand
Reviewer rejects the batch.
{
"cmd": "RejectDisbursementReviewCommand",
"data": { "batchId": 42, "comment": "Amounts exceed policy limits" }
}
ApproveDisbursementBatchCommand
Approver approves a reviewed batch (moves to Approved).
{
"cmd": "ApproveDisbursementBatchCommand",
"data": { "batchId": 42, "comment": "Approved for processing" }
}
RejectDisbursementApprovalCommand
Approver rejects the batch.
{
"cmd": "RejectDisbursementApprovalCommand",
"data": { "batchId": 42, "comment": "Source account has insufficient funds" }
}
CancelDisbursementBatchCommand
Cancels a batch (not allowed if Processed or Approved).
{
"cmd": "CancelDisbursementBatchCommand",
"data": { "batchId": 42, "comment": "No longer needed" }
}
DeleteDisbursementBatchCommand
Permanently deletes a batch and its entries (only Initiated or Cancelled).
{
"cmd": "DeleteDisbursementBatchCommand",
"data": { "batchId": 42 }
}
RetrieveDisbursementBatchesQuery
Lists disbursement batches with pagination and date filtering.
{
"cmd": "RetrieveDisbursementBatchesQuery",
"data": {
"pageNumber": 1,
"pageSize": 10,
"startDate": "2026-01-01",
"endDate": "2026-01-31",
"isExport": false
}
}
RetrieveDisbursementBatchByIdQuery
Gets full batch details including entries.
{
"cmd": "RetrieveDisbursementBatchByIdQuery",
"data": { "batchId": 42 }
}
RetrieveDisbursementBatchEntriesQuery
Lists entries for a specific batch.
{
"cmd": "RetrieveDisbursementBatchEntriesQuery",
"data": { "batchId": 42, "pageNumber": 1, "pageSize": 50 }
}
RetrieveDisbursementSourcesQuery
Lists configured disbursement source accounts.
{
"cmd": "RetrieveDisbursementSourcesQuery",
"data": { "pageNumber": 1, "pageSize": 20 }
}
RetrieveDisbursementsQuery
Lists individual disbursement transactions.
{
"cmd": "RetrieveDisbursementsQuery",
"data": {
"pageNumber": 1,
"pageSize": 20,
"batchId": 42,
"startDate": "2026-01-01",
"endDate": "2026-01-31"
}
}
2. NIBSS Mandate Commands
Manage NIBSS direct debit mandates including GSI (Group Standing Instruction).
Namespace: App.Commands.BPM.MandateManagement.Nibss
Lifecycle: Draft → PendingAuthorisation → Authorised → Active → Stopped
Enums
SelfServiceMandateTypeEnums
| Value | Name | Description |
|---|---|---|
1 | EMandate | Electronic mandate — created and signed digitally |
2 | GSI | Group Standing Instruction — multi-bank mandate |
3 | PaperMandate | Paper-based mandate — requires physical signed document |
SelfServiceWorkflowStatusEnum
| Value | Name | Description |
|---|---|---|
0 | Draft | New mandate initiated by biller |
1 | NewMandateInitiated | New mandate initiated by biller |
2 | MandateAuthorisedByBiller | Mandate authorised by biller |
3 | MandateRejectedByBiller | Mandate rejected by biller |
4 | MandateApprovedByBiller | Mandate approved by biller |
5 | MandateDisApprovedByBiller | Mandate disapproved by biller |
6 | MandateAuthorisedByBank | Mandate authorised by bank |
7 | MandateRejectedByBank | Mandate rejected by bank |
8 | MandateApprovedByBank | Mandate approved by bank |
9 | MandateDisApprovedByBank | Mandate disapproved by bank |
10 | NewMandateInitatedByBank | New mandate initiated by bank |
SelfServiceMandateStatus
| Value | Name | Description |
|---|---|---|
0 | DEFAULT | Not active — internal status (not a NIBSS status) |
1 | ACTIVE | Mandate is active and can be debited |
2 | SUSPENDED | Mandate is temporarily suspended |
3 | DELETED | Mandate is deleted or rejected |
4 | STOPPED | Mandate was active but has been stopped |
SelfServiceNibssMandateStatus
These are the NIBSS-side mandate statuses returned from NIBSS API:
| Value | Name | Description |
|---|---|---|
1 | ACTIVE | Mandate is active on NIBSS |
2 | SUSPENDED | Mandate is suspended on NIBSS |
3 | DELETED | Mandate is deleted on NIBSS |
ServiceProviderEnum
| Value | Name | Description |
|---|---|---|
0 | NIBSS | Nigeria Inter-Bank Settlement System |
1 | EAZY_PAY | EazyPay payment provider |
2 | INTERSWITCH | Interswitch payment provider |
3 | CREDITSWITCH | CreditSwitch payment provider |
4 | CRC | Credit Reference Company |
5 | FIRST_CENTRAL | First Central Credit Bureau |
6 | REMITTA | Remita payment provider |
7 | WALLZ_AND_QUEEN | Wallz and Queen payment provider |
8 | MONO | Mono open banking provider |
CreateNibssMandateCommand
Creates a single NIBSS mandate for one account.
{
"cmd": "CreateNibssMandateCommand",
"data": {
"narration": "Loan repayment mandate",
"mandate": {
"clientCode": "CLI001",
"productCode": "PRD001",
"amount": 500000,
"debitAmount": 50000,
"numberOfInstallments": 12,
"startDate": "2026-02-01",
"endDate": "2027-01-31",
"mobileNumber": "08012345678",
"emailAddress": "customer@email.com",
"payerName": "John Doe",
"payerAddress": "123 Main St, Lagos",
"branchCode": "BR001",
"organisationCode": "ORG001",
"mandateType": 1,
"accountNumber": "0012345678",
"bvn": "22234567890",
"bankCode": "058",
"accountName": "John Doe"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
mandate.clientCode | string | Yes | Client identifier |
mandate.productCode | string | Yes | Product code |
mandate.amount | decimal | Yes | Total mandate amount |
mandate.debitAmount | decimal | Yes | Amount per debit |
mandate.numberOfInstallments | int | Yes | Number of payments |
mandate.startDate | string | Yes | Mandate start date |
mandate.endDate | string | Yes | Mandate end date |
mandate.accountNumber | string | Yes | Debit account number |
mandate.bvn | string | Yes | BVN |
mandate.bankCode | string | Yes | Bank code |
mandate.mandateType | int | No | See SelfServiceMandateTypeEnums: 1=EMandate, 2=GSI, 3=PaperMandate |
mandate.mandateFileBase64 | string | No | Signed mandate image (base64) |
CreateNibssMandateListCommand
Batch-creates multiple mandates in one batch.
{
"cmd": "CreateNibssMandateListCommand",
"data": {
"narration": "Batch mandates for Q1",
"productCode": "PRD001",
"branchCode": "BR001",
"organisationCode": "ORG001",
"mandates": [
{
"clientCode": "CLI001",
"amount": 500000,
"debitAmount": 50000,
"numberOfInstallments": 12,
"startDate": "2026-02-01",
"endDate": "2027-01-31",
"accountNumber": "0012345678",
"bvn": "22234567890",
"bankCode": "058",
"accountName": "John Doe"
}
]
}
}
CreateNibssGSIMandateCommand
Creates GSI (Group Standing Instruction) mandates — one mandate per account, all linked in the same batch.
{
"cmd": "CreateNibssGSIMandateCommand",
"data": {
"narration": "GSI mandate for multi-bank customer",
"productCode": "PRD001",
"branchCode": "BR001",
"organisationCode": "ORG001",
"clientCode": "CLI001",
"payerName": "John Doe",
"amount": 500000,
"debitAmount": 50000,
"numberOfInstallments": 12,
"startDate": "2026-02-01",
"endDate": "2027-01-31",
"accounts": [
{ "accountNumber": "0012345678", "bvn": "22234567890", "bankCode": "058", "accountName": "John Doe - GTB" },
{ "accountNumber": "1012345678", "bvn": "22234567890", "bankCode": "044", "accountName": "John Doe - Access" }
]
}
}
GSI creates one mandate per account — all mandates share the same batch and are flagged with IsGroupedGSIMandate = true. During collection, the system attempts each account until the full amount is collected.
UpdateNibssMandateCommand
Updates a Draft or Rejected mandate.
{
"cmd": "UpdateNibssMandateCommand",
"data": {
"mandateId": 15,
"amount": 600000,
"debitAmount": 60000,
"numberOfInstallments": 10
}
}
AuthoriseNibssMandateCommand
Authorises a mandate and submits it to NIBSS.
{
"cmd": "AuthoriseNibssMandateCommand",
"data": { "mandateId": 15, "comment": "Verified customer identity" }
}
DisapproveNibssMandateCommand
Disapproves/rejects a mandate.
{
"cmd": "DisapproveNibssMandateCommand",
"data": { "mandateId": 15, "comment": "Invalid BVN" }
}
StartNibssMandateCommand / StopNibssMandateCommand
Starts or stops an active mandate.
{
"cmd": "StartNibssMandateCommand",
"data": { "mandateId": 15 }
}
{
"cmd": "StopNibssMandateCommand",
"data": { "mandateId": 15, "reason": "Customer request" }
}
RefreshNibssMandateStatusCommand
Fetches current mandate status from NIBSS.
{
"cmd": "RefreshNibssMandateStatusCommand",
"data": { "mandateId": 15 }
}
Mandate Queries
// List mandate batches
{ "cmd": "RetrieveNibssMandateBatchesQuery", "data": { "pageNumber": 1, "pageSize": 20 } }
// List mandates (with filters)
{ "cmd": "RetrieveNibssMandatesQuery", "data": { "batchId": 5, "pageNumber": 1, "pageSize": 50 } }
// Get single mandate
{ "cmd": "RetrieveNibssMandateByIdQuery", "data": { "mandateId": 15 } }
// List mandate products
{ "cmd": "RetrieveNibssMandateProductsQuery", "data": { "pageNumber": 1, "pageSize": 20 } }
3. NIBSS Collection Commands
Process direct debit collections against active NIBSS mandates.
Namespace: App.Commands.BPM.MandateManagement.Nibss
Lifecycle: Inactive → Active → Queued → Processing → Completed
Enums
SelfServiceCollectionBatchStatus
| Value | Name | Description |
|---|---|---|
0 | Active | Batch is authorized and ready to run |
1 | Inactive | Batch is pending authorization |
2 | Cancelled | Collection batch has been withdrawn/cancelled |
SelfServiceCollectionTypeEnum
| Value | Name | Description |
|---|---|---|
0 | Default | Collects the exact amount specified. Fails if amount is not available. |
1 | Recovery | Performs a balance check and recovers whatever amount is available in the account. |
CreateNibssCollectionBatchCommand
Creates an empty collection batch.
{
"cmd": "CreateNibssCollectionBatchCommand",
"data": {
"batchName": "February Collections",
"batchDescription": "Monthly loan repayments",
"organisationId": 1,
"collectionType": 0
}
}
CreateNibssCollectionBatchWithItemsCommand
Creates a batch pre-populated with collection items.
{
"cmd": "CreateNibssCollectionBatchWithItemsCommand",
"data": {
"batchName": "February Collections",
"batchDescription": "Monthly repayments",
"organisationId": 1,
"collections": [
{ "mandateId": 15, "amount": 50000, "narration": "Feb instalment", "collectionDate": "2026-02-15" },
{ "mandateId": 22, "amount": 75000, "narration": "Feb instalment" }
]
}
}
AddNibssCollectionToBatchCommand
Adds a single collection to an existing batch.
{
"cmd": "AddNibssCollectionToBatchCommand",
"data": {
"batchId": 10,
"mandateId": 15,
"amount": 50000,
"narration": "Additional collection",
"collectionDate": "2026-02-15"
}
}
ActivateNibssCollectionBatchCommand / DeactivateNibssCollectionBatchCommand
{ "cmd": "ActivateNibssCollectionBatchCommand", "data": { "batchId": 10 } }
{ "cmd": "DeactivateNibssCollectionBatchCommand", "data": { "batchId": 10 } }
CancelNibssCollectionBatchCommand
{ "cmd": "CancelNibssCollectionBatchCommand", "data": { "batchId": 10 } }
RunNibssCollectionBatchCommand
Queues the batch for NIBSS debit processing. Calls NIBSS TransferDirectToNIBSS API for each collection.
{
"cmd": "RunNibssCollectionBatchCommand",
"data": { "batchId": 10 }
}
Collection Queries
// List collection batches
{ "cmd": "RetrieveNibssCollectionBatchesQuery", "data": { "pageNumber": 1, "pageSize": 20 } }
// List collections
{ "cmd": "RetrieveNibssCollectionsQuery", "data": { "batchId": 10, "pageNumber": 1, "pageSize": 50 } }
// List collection transactions
{ "cmd": "RetrieveNibssCollectionTransactionsQuery", "data": { "batchId": 10, "pageNumber": 1, "pageSize": 50 } }
4. Remita Loan Commands
Complete Remita loan origination and collection lifecycle.
Enums
RemitaLoanRequestStatus
| Value | Name | Description |
|---|---|---|
0 | Draft | Loan request created, not yet submitted |
1 | PendingApproval | Submitted and awaiting approval |
2 | Approved | Loan request approved |
3 | Rejected | Loan request rejected |
4 | Disbursed | Loan has been disbursed to customer |
5 | DisbursementFailed | Loan disbursement failed |
6 | Active | Loan is active (disbursed and mandate active) |
7 | Closed | Loan is fully repaid and closed |
8 | Cancelled | Loan request cancelled |
RemitaMandateActivationStatus
| Value | Name | Description |
|---|---|---|
0 | NotActivated | Mandate has not been activated yet |
1 | ActivationPending | Mandate activation is in progress |
2 | Activated | Mandate is activated and ready for collection |
3 | ActivationFailed | Mandate activation failed |
4 | Stopped | Mandate has been stopped |
RemitaDisbursementChannel
| Value | Name | Description |
|---|---|---|
0 | NIP | Disburse via NIP (inter-bank transfer) |
1 | Internal | Disburse via internal (intra-bank) transfer |
LoanTenorType
| Value | Name | Description |
|---|---|---|
0 | DAYS | Day(s) |
1 | WEEKS | Week(s) |
2 | MONTHS | Month(s) — default |
3 | YEARS | Year(s) |
RemitaCollectionBatchStatus
| Value | Name | Description |
|---|---|---|
0 | Initiated | Batch created |
1 | PendingAuthorization | Submitted for authorization |
2 | Authorized | Batch authorized |
3 | Rejected | Batch rejected |
4 | Processing | Batch is being processed |
5 | Completed | All collections in batch completed |
6 | Cancelled | Batch cancelled |
RemitaCollectionStatus
| Value | Name | Description |
|---|---|---|
0 | Pending | Collection pending |
1 | Successful | Collection completed successfully |
2 | Failed | Collection failed |
3 | Reversed | Collection has been reversed |
4.1 Loan Request Management
Namespace: App.Commands.BPM.RemitaManagement
Lifecycle: Draft → PendingApproval → Approved → MandateActivated → Disbursed → Active
CreateRemitaLoanRequestCommand
Creates a new loan request in Draft status.
{
"cmd": "CreateRemitaLoanRequestCommand",
"data": {
"cif": "CIF001",
"accountNumber": "0012345678",
"accountName": "John Doe",
"bvn": "22234567890",
"phoneNumber": "08012345678",
"email": "john@email.com",
"companyName": "ACME Corp",
"employerRegistrationNumber": "REG123",
"loanAmount": 1000000,
"collectionAmount": 100000,
"tenure": 12,
"tenorType": 2,
"interestRate": 18.5,
"disbursementChannel": 0,
"loanAccount": "0012345678",
"currencyCode": "NGN",
"loanType": "Term Loan",
"organisationId": 1,
"tag": "salary-advance",
"bankCode": "058",
"remitaCustomerId": "REM-CUST-001",
"authorisationCode": "AUTH-CODE-123"
}
}
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
cif | string | Yes | — | Customer Identification |
accountNumber | string | Yes | — | Loan disbursement account number |
accountName | string | No | — | Customer account name |
bvn | string | Yes | — | Bank Verification Number |
phoneNumber | string | No | — | Customer phone number |
email | string | No | — | Customer email address |
companyName | string | No | — | Employer company name |
employerRegistrationNumber | string | No | — | Employer registration number |
loanAmount | decimal | Yes | — | Total loan amount |
collectionAmount | decimal | Yes | — | Monthly collection/repayment amount |
tenure | int | Yes | — | Loan tenure (number of periods) |
tenorType | int | No | 2 (Months) | Tenor type enum: 0=Days, 1=Weeks, 2=Months, 3=Years |
interestRate | decimal | No | 0 | Annual interest rate percentage |
disbursementChannel | int | No | 0 (NIP) | Disbursement channel: 0=NIP, 1=Internal |
loanAccount | string | No | — | Loan tracking account |
currencyCode | string | No | "NGN" | Currency code (ISO 4217) |
loanType | string | No | — | Loan product type description |
organisationId | long | Yes | — | Organisation/branch identifier |
tag | string | No | — | Custom tag for categorisation |
bankCode | string | No | — | Customer's bank code |
remitaCustomerId | string | No | — | Remita customer ID |
authorisationCode | string | No | — | Remita authorisation code |
Response:
{
"id": 5,
"cif": "CIF001",
"accountNumber": "0012345678",
"loanAmount": 1000000,
"collectionAmount": 100000,
"tenure": 12,
"status": 0,
"statusDesc": "Draft"
}
UpdateRemitaLoanRequestCommand
Updates an existing loan request. Only allowed when status is Draft (0).
Only provided fields are updated — omitted fields retain their current values.
{
"cmd": "UpdateRemitaLoanRequestCommand",
"data": {
"id": 5,
"accountNumber": "0098765432",
"loanAmount": 1500000,
"collectionAmount": 150000,
"tenure": 10,
"disbursementChannel": 1,
"bankCode": "058",
"remitaCustomerId": "REM-CUST-002",
"authorisationCode": "AUTH-CODE-456"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
accountNumber | string | No | Updated account number |
accountName | string | No | Updated account name |
phoneNumber | string | No | Updated phone number |
email | string | No | Updated email |
companyName | string | No | Updated company name |
employerRegistrationNumber | string | No | Updated employer registration |
loanAmount | decimal | No | Updated loan amount |
collectionAmount | decimal | No | Updated collection amount |
tenure | int | No | Updated tenure |
interestRate | decimal | No | Updated interest rate |
disbursementChannel | int | No | Updated channel: 0=NIP, 1=Internal |
loanAccount | string | No | Updated loan account |
tag | string | No | Updated tag |
bankCode | string | No | Updated bank code |
remitaCustomerId | string | No | Updated Remita customer ID |
authorisationCode | string | No | Updated authorisation code |
Response:
{
"id": 5,
"status": 0,
"statusDesc": "Draft"
}
SubmitRemitaLoanForApprovalCommand
Submits a Draft loan request for approval. Changes status to PendingApproval.
{
"cmd": "SubmitRemitaLoanForApprovalCommand",
"data": { "id": 5 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
Prerequisites: Loan must be in Draft (0) status.
Response:
{
"id": 5,
"status": 1,
"statusDesc": "PendingApproval"
}
ApproveRemitaLoanRequestCommand
Approves a loan request that is PendingApproval. Records the approver and timestamp.
{
"cmd": "ApproveRemitaLoanRequestCommand",
"data": { "id": 5, "comment": "Salary history verified" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Approval comment |
Prerequisites: Loan must be in PendingApproval (1) status.
Response:
{
"id": 5,
"status": 2,
"statusDesc": "Approved",
"approvedBy": "John Admin-(admin@bank.com)",
"approvalDate": "2026-03-15T10:30:00"
}
RejectRemitaLoanRequestCommand
Rejects a loan request that is PendingApproval.
{
"cmd": "RejectRemitaLoanRequestCommand",
"data": { "id": 5, "comment": "Insufficient salary history" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Rejection reason |
Prerequisites: Loan must be in PendingApproval (1) status.
Response:
{
"id": 5,
"status": 3,
"statusDesc": "Rejected",
"approvalComment": "Insufficient salary history"
}
ActivateRemitaMandateCommand
Marks claim for mandate activation. Sets mandate status to ActivationPending.
{
"cmd": "ActivateRemitaMandateCommand",
"data": { "id": 5 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
Prerequisites: Mandate must not already be Activated.
Response:
{
"id": 5,
"mandateActivationStatus": 1,
"mandateActivationStatusDesc": "ActivationPending",
"mandateReference": "MND-REF-001",
"mandateCode": "MND-CODE-001"
}
DisburseRemitaLoanCommand
Sets loan status to Disbursed and generates a disbursement reference.
{
"cmd": "DisburseRemitaLoanCommand",
"data": { "id": 5 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
Prerequisites: Loan must be Approved (2) and mandate must be Activated (2).
Response:
{
"id": 5,
"status": 4,
"statusDesc": "Disbursed",
"disbursementReference": "REM-20260315103000-5",
"disbursementDate": "2026-03-15T10:30:00",
"disbursementChannel": 0,
"disbursementChannelDesc": "NIP"
}
CancelRemitaLoanRequestCommand
Cancels a loan request. Not allowed if already Disbursed or Active.
{
"cmd": "CancelRemitaLoanRequestCommand",
"data": { "id": 5, "comment": "Customer withdrew application" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Cancellation reason |
Prerequisites: Loan must NOT be Disbursed (4) or Active (6).
Response:
{
"id": 5,
"status": 8,
"statusDesc": "Cancelled"
}
RetrieveRemitaLoanRequestsQuery
Returns a paginated list of loan requests with optional filters. Supports Excel export.
{
"cmd": "RetrieveRemitaLoanRequestsQuery",
"data": {
"pageNumber": 1,
"pageSize": 20,
"organisationId": 1,
"startDate": "2026-01-01",
"endDate": "2026-03-31",
"isExport": false
}
}
Request Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
pageNumber | int | No | 1 | Page number |
pageSize | int | No | 10 | Results per page |
organisationId | long | No | — | Filter by organisation |
startDate | string | No | — | Filter by creation date (from). Format: yyyy-MM-dd |
endDate | string | No | — | Filter by creation date (to). Format: yyyy-MM-dd |
isExport | bool | No | false | If true, returns Excel file instead of JSON |
Also supports dynamic predicate filters via standard DynamicPredicateBuilder (filter by any field: status, cif, accountNumber, etc.).
Response (paginated):
{
"data": [
{
"id": 5,
"cif": "CIF001",
"accountNumber": "0012345678",
"accountName": "John Doe",
"bvn": "22234567890",
"phoneNumber": "08012345678",
"email": "john@email.com",
"companyName": "ACME Corp",
"employerRegistrationNumber": "REG123",
"loanAmount": 1000000,
"collectionAmount": 100000,
"tenure": 12,
"tenorType": 2,
"tenorTypeDesc": "Month(s)",
"interestRate": 18.5,
"currencyCode": "NGN",
"loanType": "Term Loan",
"mandateReference": "MND-REF-001",
"mandateCode": "MND-CODE-001",
"mandateActivationStatus": 2,
"mandateActivationStatusDesc": "Activated",
"status": 6,
"statusDesc": "Active",
"loanAccount": "0012345678",
"disbursementChannel": 0,
"disbursementChannelDesc": "NIP",
"disbursementReference": "REM-20260315103000-5",
"disbursementDate": "2026-03-15T10:30:00",
"initiatedBy": "John Admin-(admin@bank.com)",
"approvedBy": "Jane Approver-(jane@bank.com)",
"approvalDate": "2026-03-14T15:00:00",
"tag": "salary-advance",
"createdAt": "2026-03-10T09:00:00",
"organisationName": "Head Office",
"collectionBatchName": "March Collections"
}
],
"pages": 3,
"hasNext": true,
"hasPrevious": false,
"count": 45,
"size": 20
}
Response Fields:
| Field | Type | Description |
|---|---|---|
id | long | Loan request ID |
cif | string | Customer Identification |
accountNumber | string | Disbursement account |
accountName | string | Account holder name |
bvn | string | Bank Verification Number |
phoneNumber | string | Customer phone |
email | string | Customer email |
companyName | string | Employer name |
employerRegistrationNumber | string | Employer registration |
loanAmount | decimal | Total loan amount |
collectionAmount | decimal | Monthly collection amount |
tenure | int | Loan tenure in periods |
tenorType | int | Tenor type enum (see LoanTenorType) |
tenorTypeDesc | string | Tenor type description — e.g. "Month(s)" |
interestRate | decimal | Annual interest rate |
currencyCode | string | Currency code (ISO 4217) |
loanType | string | Loan product type |
mandateReference | string | Remita mandate reference |
mandateCode | string | Remita mandate code |
mandateActivationStatus | int | Mandate activation status: 0=NotActivated, 1=ActivationPending, 2=Activated, 3=ActivationFailed, 4=Stopped |
mandateActivationStatusDesc | string | Mandate status description (e.g. "Activated") |
status | int | Loan request status: 0=Draft, 1=PendingApproval, 2=Approved, 3=Rejected, 4=Disbursed, 5=DisbursementFailed, 6=Active, 7=Closed, 8=Cancelled |
statusDesc | string | Loan status description (e.g. "Active") |
loanAccount | string | Loan tracking account |
disbursementChannel | int | Disbursement channel: 0=NIP, 1=Internal |
disbursementChannelDesc | string | Channel description (e.g. "NIP") |
disbursementReference | string | Disbursement reference |
disbursementDate | datetime | When loan was disbursed |
initiatedBy | string | Who created the request |
approvedBy | string | Who approved the request |
approvalDate | datetime | When approved |
tag | string | Custom tag |
createdAt | datetime | Record creation timestamp |
organisationName | string | Organisation name (from lookup) |
collectionBatchName | string | Linked collection batch name (if any) |
RetrieveRemitaLoanRequestByIdQuery
Returns the full detail of a single loan request, including linked collection batch info.
{
"cmd": "RetrieveRemitaLoanRequestByIdQuery",
"data": { "id": 5 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
Response:
{
"id": 5,
"cif": "CIF001",
"accountNumber": "0012345678",
"accountName": "John Doe",
"bvn": "22234567890",
"phoneNumber": "08012345678",
"email": "john@email.com",
"companyName": "ACME Corp",
"employerRegistrationNumber": "REG123",
"loanAmount": 1000000,
"collectionAmount": 100000,
"tenure": 12,
"tenorType": 2,
"tenorTypeDesc": "Month(s)",
"interestRate": 18.5,
"currencyCode": "NGN",
"loanType": "Term Loan",
"mandateReference": "MND-REF-001",
"mandateCode": "MND-CODE-001",
"mandateActivationStatus": 2,
"mandateActivationStatusDesc": "Activated",
"status": 6,
"statusDesc": "Active",
"loanAccount": "0012345678",
"disbursementChannel": 0,
"disbursementChannelDesc": "NIP",
"disbursementReference": "REM-20260315103000-5",
"disbursementResponseMessage": "Transfer successful",
"disbursementDate": "2026-03-15T10:30:00",
"initiatedBy": "John Admin-(admin@bank.com)",
"initiatedBySelfServiceUserId": 42,
"approvedBy": "Jane Approver-(jane@bank.com)",
"approvalDate": "2026-03-14T15:00:00",
"approvalComment": "Salary history verified",
"tag": "salary-advance",
"createdAt": "2026-03-10T09:00:00",
"organisationName": "Head Office",
"collectionBatch": {
"id": 3,
"batchName": "March Collections",
"batchStatus": 5,
"batchStatusDesc": "Completed"
}
}
Additional fields vs list query:
| Field | Type | Description |
|---|---|---|
disbursementResponseMessage | string | Response message from disbursement attempt |
initiatedBySelfServiceUserId | long | User ID of initiator |
approvalComment | string | Approval/rejection comment |
collectionBatch | object | Linked collection batch (if any) |
collectionBatch.id | long | Batch ID |
collectionBatch.batchName | string | Batch name |
collectionBatch.batchStatus | int | Batch status: 0=Initiated, 1=PendingAuthorization, 2=Authorized, 3=Rejected, 4=Processing, 5=Completed, 6=Cancelled |
collectionBatch.batchStatusDesc | string | Batch status description (e.g. "Completed") |
4.2 Remita Loan Processing (API Integration)
Commands that interact with the Remita API directly. These are typically called by BPMN process tasks, not directly by UI.
ProcessRemitaActivateMandateCommand
Activates a mandate via Remita Disbursement Notification API. On success, sets mandate to Activated and loan status to Active.
{
"cmd": "ProcessRemitaActivateMandateCommand",
"data": { "id": 5, "comment": "Activating mandate" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Comment to append to approval notes |
API call: Sends disbursement notification to Remita with customer details, loan amounts, and repayment schedule.
Response:
{
"id": 5,
"mandateReference": "MND-REF-001",
"authorisationCode": "AUTH-UPDATED-789",
"mandateActivationStatus": 2,
"mandateActivationStatusDesc": "Activated",
"status": 6,
"statusDesc": "Active"
}
ProcessRemitaStopMandateCommand
Stops a mandate via Remita Stop Loan Collection API.
{
"cmd": "ProcessRemitaStopMandateCommand",
"data": { "id": 5, "comment": "Customer request to stop collections" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Reason for stopping |
Response:
{
"id": 5,
"mandateReference": "MND-REF-001",
"mandateActivationStatus": 4,
"mandateActivationStatusDesc": "Stopped"
}
ProcessRemitaDisburseLoanCommand
Disburses the loan via core banking. Uses Internal transfer for same-bank or NIP for external accounts.
{
"cmd": "ProcessRemitaDisburseLoanCommand",
"data": { "id": 5, "comment": "Disbursing loan" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Disbursement comment |
Prerequisites: Mandate must be Activated (2). Loan must NOT already be Disbursed.
Response:
{
"id": 5,
"status": 4,
"statusDesc": "Disbursed",
"disbursementReference": "REM-20260315103000-5",
"disbursementDate": "2026-03-15T10:30:00",
"disbursementChannel": 1,
"disbursementChannelDesc": "Internal"
}
On failure, status is set to
DisbursementFailed(5) with adisbursementResponseMessage.
ProcessRemitaRejectLoanCommand
Rejects a loan and sends email notification to the customer.
{
"cmd": "ProcessRemitaRejectLoanCommand",
"data": { "id": 5, "comment": "BVN validation failed" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
comment | string | No | Rejection reason |
Response:
{
"id": 5,
"status": 3,
"statusDesc": "Rejected",
"approvalComment": "BVN validation failed"
}
GetRemitaSalaryHistoryQuery
Retrieves customer salary history directly from Remita API.
{
"cmd": "GetRemitaSalaryHistoryQuery",
"data": {
"firstName": "John",
"lastName": "Doe",
"middleName": "",
"accountNumber": "0012345678",
"bankCode": "058",
"bvn": "22234567890",
"phoneNumber": "08012345678",
"useMobileNumberForSearch": false,
"authorisationChannel": "USSD",
"authorisationCode": "AUTH-CODE-123"
}
}
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
firstName | string | No | — | Customer first name |
lastName | string | No | — | Customer last name |
middleName | string | No | — | Customer middle name |
accountNumber | string | No | — | Bank account number |
bankCode | string | No | — | Customer bank code |
bvn | string | No | — | Bank Verification Number |
phoneNumber | string | No | — | Customer phone number |
useMobileNumberForSearch | bool | No | false | Search by mobile number instead of account |
authorisationChannel | string | No | "USSD" | Remita authorisation channel |
authorisationCode | string | No | — | Remita authorisation code |
Response: Returns a CommandExecutionResponse wrapping the Remita salary history data.
{
"isSuccessful": true,
"statusCode": "success",
"message": "Salary history retrieved.",
"data": {
/* Raw Remita salary history payload */
}
}
| Field | Type | Description |
|---|---|---|
isSuccessful | bool | true if Remita returned status "success" |
statusCode | string | Remita response code or status |
message | string | Remita response message or default description |
data | object | Raw Remita salary history data (employer info, salary records, etc.) |
GetRemitaPaymentHistoryQuery
Retrieves repayment history from Remita. Supports lookup by loan ID or direct API parameters.
// Mode 1: By loan request ID
{
"cmd": "GetRemitaPaymentHistoryQuery",
"data": { "id": 5 }
}
// Mode 2: Direct Remita API params
{
"cmd": "GetRemitaPaymentHistoryQuery",
"data": {
"authorisationCode": "AUTH-CODE-123",
"customerId": "REM-CUST-001",
"mandateRef": "MND-REF-001"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | No | Loan request ID (auto-resolves Remita params) |
authorisationCode | string | No | Direct Remita authorisation code |
customerId | string | No | Direct Remita customer ID |
mandateRef | string | No | Direct mandate reference |
Response: Returns a CommandExecutionResponse wrapping the Remita payment history data.
{
"isSuccessful": true,
"statusCode": "00",
"message": "Payment history retrieved.",
"data": {
/* Raw Remita payment/repayment history payload */
}
}
| Field | Type | Description |
|---|---|---|
isSuccessful | bool | true if Remita response code is "00" |
statusCode | string | Remita response code ("00" = success) |
message | string | Remita response message |
data | object | Raw Remita repayment history data |
SyncRemitaPaymentHistoryCommand
Syncs payment history from Remita and creates local RemitaCollection records for newly discovered payments. Deduplicates by TransactionReference + MandateReference.
{
"cmd": "SyncRemitaPaymentHistoryCommand",
"data": { "id": 5 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Loan request ID |
Response:
{
"id": 5,
"mandateReference": "MND-REF-001",
"totalPaidRepayments": 8,
"newCollectionsRecorded": 3,
"repayments": [ /* raw Remita repayment data */ ]
}
4.3 Remita Collection Management
RetrieveRemitaCollectionsQuery
Returns a paginated list of individual collection records. Supports Excel export.
{
"cmd": "RetrieveRemitaCollectionsQuery",
"data": {
"pageNumber": 1,
"pageSize": 20,
"loanRequestId": 5,
"batchId": 3,
"isPosted": false,
"startDate": "2026-01-01",
"endDate": "2026-03-31",
"isExport": false
}
}
Request Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
pageNumber | int | No | 1 | Page number |
pageSize | int | No | 10 | Results per page |
batchId | long | No | — | Filter by collection batch ID |
loanRequestId | long | No | — | Filter by loan request ID |
isPosted | bool | No | — | Filter by posting status |
startDate | string | No | — | Filter from date. Format: yyyy-MM-dd |
endDate | string | No | — | Filter to date. Format: yyyy-MM-dd |
isExport | bool | No | false | If true, returns Excel file |
Also supports dynamic predicate filters.
Response (paginated):
{
"data": [
{
"id": 101,
"mandateReference": "MND-REF-001",
"mandateCode": "MND-CODE-001",
"transactionAmount": 100000,
"paymentStatus": 1,
"paymentStatusDesc": "Successful",
"paymentStatusMessage": "Payment received",
"transactionReference": "TXN-REF-001",
"providerReference": "PROV-REF-001",
"isPosted": true,
"postingReference": "POST-20260315-101",
"postingDate": "2026-03-16T08:00:00",
"accountNumber": "0012345678",
"accountName": "John Doe",
"bankCode": "058",
"narration": "Loan repayment",
"createdAt": "2026-03-15T10:00:00",
"loanRequest": {
"id": 5,
"cif": "CIF001",
"accountNumber": "0012345678",
"accountName": "John Doe",
"loanAmount": 1000000,
"collectionAmount": 100000,
"status": 6,
"statusDesc": "Active"
},
"collectionBatch": {
"id": 3,
"batchName": "March Collections",
"batchStatus": 5,
"batchStatusDesc": "Completed"
}
}
],
"pages": 1,
"hasNext": false,
"hasPrevious": false,
"count": 8,
"size": 20
}
RetrieveRemitaCollectionByIdQuery
Returns full detail of a single collection record.
{
"cmd": "RetrieveRemitaCollectionByIdQuery",
"data": { "id": 101 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Collection ID |
Response: Same fields as list query, with additional detail in the loanRequest object:
Additional loanRequest Fields | Type | Description |
|---|---|---|
bvn | string | BVN |
tenure | int | Loan tenure |
mandateReference | string | Mandate reference |
organisationName | string | Organisation name |
PostRemitaCollectionCommand
Marks a successful collection as posted (e.g., after journal entry).
{
"cmd": "PostRemitaCollectionCommand",
"data": { "id": 101, "postingReference": "JNL-2026-001" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Collection ID |
postingReference | string | No | Journal reference. Auto-generated if omitted: POST-{yyyyMMddHHmmss}-{id} |
Prerequisites: Collection paymentStatus must be Successful (1) and not already posted.
Response:
{
"id": 101,
"isPosted": true,
"postingReference": "JNL-2026-001",
"postingDate": "2026-03-16T08:00:00"
}
ReverseRemitaCollectionCommand
Reverses a successful collection.
{
"cmd": "ReverseRemitaCollectionCommand",
"data": { "id": 101, "reason": "Duplicate debit" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Collection ID |
reason | string | No | Reversal reason. Defaults to "Manual reversal" |
Prerequisites: Collection paymentStatus must be Successful (1).
Response:
{
"id": 101,
"paymentStatus": 3,
"paymentStatusDesc": "Reversed",
"paymentStatusMessage": "Duplicate debit"
}
4.4 Remita Collection Batch Management
Lifecycle: Initiated → PendingAuthorization → Authorized → Processing → Completed
CreateRemitaCollectionBatchCommand
Creates a new collection batch and optionally links loan requests to it.
{
"cmd": "CreateRemitaCollectionBatchCommand",
"data": {
"batchName": "March Collections",
"batchDescription": "Monthly Remita repayments",
"organisationId": 1,
"loanRequestIds": [5, 8, 12]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
batchName | string | Yes | Batch name |
batchDescription | string | No | Batch description |
organisationId | long | Yes | Organisation ID |
loanRequestIds | long[] | No | Loan request IDs to link to this batch |
Response:
{
"id": 3,
"batchName": "March Collections",
"batchStatus": 0,
"batchStatusDesc": "Initiated",
"totalCount": 3,
"totalAmount": 350000,
"linkedLoanRequests": 3
}
AuthorizeRemitaCollectionBatchCommand
Authorizes a collection batch for processing.
{
"cmd": "AuthorizeRemitaCollectionBatchCommand",
"data": { "id": 3, "comment": "Verified amounts" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Batch ID |
comment | string | No | Authorisation comment |
Prerequisites: Batch must be in Initiated (0) or PendingAuthorization (1).
Response:
{
"id": 3,
"batchStatus": 2,
"batchStatusDesc": "Authorized",
"authorizedBy": "Jane Approver-(jane@bank.com)",
"authorizationDate": "2026-03-15T14:00:00"
}
RejectRemitaCollectionBatchCommand
Rejects a collection batch.
{
"cmd": "RejectRemitaCollectionBatchCommand",
"data": { "id": 3, "comment": "Amounts incorrect" }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Batch ID |
comment | string | No | Rejection reason |
Prerequisites: Batch must be in PendingAuthorization (1) or Initiated (0).
Response:
{
"id": 3,
"batchStatus": 3,
"batchStatusDesc": "Rejected",
"authorizationComment": "Amounts incorrect"
}
RunRemitaCollectionBatchCommand
Runs an authorized batch — creates RemitaCollection records for each linked loan with an activated mandate and sets batch to Processing.
{
"cmd": "RunRemitaCollectionBatchCommand",
"data": { "id": 3 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Batch ID |
Prerequisites: Batch must be Authorized (2) and not already Processing.
Response:
{
"id": 3,
"batchStatus": 4,
"batchStatusDesc": "Processing",
"totalCount": 3,
"totalAmount": 350000
}
CancelRemitaCollectionBatchCommand
Cancels a collection batch. Not allowed if already Processing or Completed.
{
"cmd": "CancelRemitaCollectionBatchCommand",
"data": { "id": 3 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Batch ID |
Response:
{
"id": 3,
"batchStatus": 6,
"batchStatusDesc": "Cancelled"
}
RetrieveRemitaCollectionBatchesQuery
Returns a paginated list of collection batches. Supports Excel export.
{
"cmd": "RetrieveRemitaCollectionBatchesQuery",
"data": {
"pageNumber": 1,
"pageSize": 20,
"organisationId": 1,
"startDate": "2026-01-01",
"endDate": "2026-03-31"
}
}
Request Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
pageNumber | int | No | 1 | Page number |
pageSize | int | No | 10 | Results per page |
organisationId | long | No | — | Filter by organisation |
startDate | string | No | — | Filter from date |
endDate | string | No | — | Filter to date |
isExport | bool | No | false | If true, returns Excel file |
Response (paginated):
{
"data": [
{
"id": 3,
"batchName": "March Collections",
"batchDescription": "Monthly Remita repayments",
"dateCreated": "2026-03-01T09:00:00",
"batchStatus": 5,
"batchStatusDesc": "Completed",
"initiatedBy": "John Admin-(admin@bank.com)",
"authorizedBy": "Jane Approver-(jane@bank.com)",
"authorizationDate": "2026-03-01T10:00:00",
"totalCount": 3,
"totalAmount": 350000,
"successCount": 3,
"failureCount": 0,
"createdAt": "2026-03-01T09:00:00",
"organisationName": "Head Office"
}
],
"pages": 1,
"hasNext": false,
"hasPrevious": false,
"count": 5,
"size": 20
}
RetrieveRemitaCollectionBatchByIdQuery
Returns full detail of a single batch, including linked loan requests and collection records.
{
"cmd": "RetrieveRemitaCollectionBatchByIdQuery",
"data": { "id": 3 }
}
| Field | Type | Required | Description |
|---|---|---|---|
id | long | Yes | Batch ID |
Response:
{
"id": 3,
"batchName": "March Collections",
"batchDescription": "Monthly Remita repayments",
"dateCreated": "2026-03-01T09:00:00",
"batchStatus": 5,
"batchStatusDesc": "Completed",
"initiatedBy": "John Admin-(admin@bank.com)",
"initiatedBySelfServiceUserId": 42,
"authorizedBy": "Jane Approver-(jane@bank.com)",
"authorizationDate": "2026-03-01T10:00:00",
"authorizationComment": "Verified amounts",
"totalCount": 3,
"totalAmount": 350000,
"successCount": 3,
"failureCount": 0,
"createdAt": "2026-03-01T09:00:00",
"organisationName": "Head Office",
"loanRequests": [
{
"id": 5,
"cif": "CIF001",
"accountNumber": "0012345678",
"accountName": "John Doe",
"loanAmount": 1000000,
"collectionAmount": 100000,
"mandateReference": "MND-REF-001",
"status": 6,
"statusDesc": "Active",
"mandateActivationStatus": 2,
"mandateActivationStatusDesc": "Activated"
}
],
"collections": [
{
"id": 101,
"mandateReference": "MND-REF-001",
"transactionAmount": 100000,
"paymentStatus": 1,
"paymentStatusDesc": "Successful",
"transactionReference": "TXN-REF-001",
"isPosted": true,
"accountNumber": "0012345678",
"createdAt": "2026-03-15T10:00:00"
}
]
}
5. Webhook Endpoints
5.1 Fixed Webhook Endpoints
These endpoints receive callbacks from external providers.
NIBSS Mono Callback
POST /api/bpm/webhooks/mono_callback
Authorization: Bearer {token}
Handles Mono direct debit mandate lifecycle events:
events.mandates.created— Mandate createdevents.mandates.approved— Mandate approvedevents.mandates.rejected— Mandate rejectedevents.mandates.ready— Mandate ready for debitevents.mandate.action.pause— Mandate pausedevents.mandate.action.cancel— Mandate cancelledevents.mandate.action.reinstate— Mandate reinstatedevents.mandates.debit.processing— Debit being processedevents.mandates.debit.success— Debit successfulevents.mandates.debit.failed— Debit failed
Remita Webhook
POST /api/bpm/webhooks/remita_webhook
Authorization: None (AllowAnonymous)
Handles Remita mandate lifecycle events:
mandate_activation_success— Mandate activatedmandate_activation_failed— Mandate activation failedmandate_stopped— Mandate stoppedcollection_success— Collection succeededcollection_failed— Collection failed
Remita Collection Notification
POST /api/bpm/webhooks/remita_collection
Authorization: None (AllowAnonymous)
Receives Remita repayment/collection notifications. Creates RemitaCollection records and triggers payment history sync.
Payload:
{
"mandateRef": "MAND-REF-001",
"customer_id": "CUST-001",
"request_id": "REQ-001",
"amount": 100000,
"payment_date": "2026-02-15",
"payment_status": "01",
"payment_ref": "PAY-REF-001",
"status_reason": "Successful"
}
5.2 Dynamic Webhook Router
POST|GET|PUT|DELETE|PATCH /api/webhook/{*path}
A configurable webhook router that matches incoming requests against WebHookConfig records. Supports IP filtering and three execution modes:
| Mode | Value | Description |
|---|---|---|
ExecuteNativeCommand | 0 | Runs a named BPM command |
ExecuteCode | 2 | Runs inline script via formula engine |
StartProcess | 3 | Starts a BPMN process instance |
Webhook Config Commands
// Create webhook config
{
"cmd": "CreateWebHookConfigCommand",
"data": {
"key": "paystack_callback",
"description": "Paystack payment callback",
"isEnabled": true,
"path": "paystack/callback",
"action": "POST",
"executionType": 0,
"commandName": "ProcessPaystackPaymentCommand",
"allowableIPs": "52.31.139.75,52.49.173.169"
}
}
// Toggle webhook
{ "cmd": "ActivateWebHookConfigCommand", "data": { "id": 1 } }
{ "cmd": "DeactivateWebHookConfigCommand", "data": { "id": 1 } }
// Query webhooks
{ "cmd": "GetWebHookConfigListQuery", "data": { "pageNumber": 1, "pageSize": 20 } }
{ "cmd": "GetWebHookConfigByIdQuery", "data": { "id": 1 } }
{ "cmd": "LookupWebHookByKeyCommand", "data": { "key": "paystack_callback" } }
6. Configuration
Remita API Configuration
The Remita API integration requires these tenant configuration keys:
| Key | Description |
|---|---|
REMITTA:API_KEY | Remita API key |
REMITTA:API_TOKEN | Remita API token (for HMAC signing) |
REMITTA:MERCHANT_ID | Remita merchant identifier |
REMITTA:BASE_ENDPOINT | Remita API base URL |
Authentication uses SHA-512 HMAC: hash = SHA512(apiKey + requestId + apiToken)
Channel Configuration (CC Config) — YAML
The Channel Configuration (ConfigDefinition with code CC) is a YAML-based configuration that defines transaction channels, sales channels, services, mandate products, and disbursement sources. It is stored in the ConfigDefinition table and deserialized into ChannelsConfig.
Full YAML Schema
# ── Transaction Channels ──────────────────────────────────────────────
transactionChannels:
- code: MOBILE
name: Mobile Banking
accountNumber: '1000001'
allowedOperations:
- deposit
- withdraw
- transfer
- code: TELLER
name: Teller
accountNumber: '1000002'
allowedOperations:
- deposit
- withdraw
- transfer
- code: WEB
name: Web Banking
accountNumber: '1000001'
allowedOperations:
- deposit
- withdraw
- transfer
# ── Mandate Products ──────────────────────────────────────────────────
# Used by: CreateNibssMandateCommand, RetrieveNibssMandateProductsQuery
# Each mandate must reference a valid productCode from this list.
mandateProducts:
- productCode: PROD-LN-001
productName: Loan Repayment
productDescription: Direct debit mandate for loan repayment collections
isActive: true
- productCode: PROD-INS-001
productName: Insurance Premium
productDescription: Recurring insurance premium collection via direct debit
isActive: true
- productCode: PROD-SAV-001
productName: Savings Plan
productDescription: Automated savings collection via NIBSS direct debit
isActive: true
- productCode: PROD-SUB-001
productName: Subscription
productDescription: Recurring subscription payment collection
isActive: false
# ── Disbursement Sources ──────────────────────────────────────────────
# Used by: RetrieveDisbursementSourcesQuery, InitiateDisbursementBatchCommand
# Defines the source accounts from which disbursements are funded.
disbursementSources:
- accountNumber: '0011234567'
sourceAccountName: Main Disbursement Account
sourceAccountCIF: CIF001
sourceChannel: INTERNAL
disbursementSourceAccountGroup: 1
sourceGroupDescription: Primary Disbursement Pool
isEnabled: true
- accountNumber: '0019876543'
sourceAccountName: Payroll Disbursement Account
sourceAccountCIF: CIF002
sourceChannel: INTERNAL
disbursementSourceAccountGroup: 2
sourceGroupDescription: Payroll Pool
isEnabled: true
- accountNumber: '0015556789'
sourceAccountName: Vendor Payment Account
sourceAccountCIF: CIF003
sourceChannel: NIBSS
disbursementSourceAccountGroup: 3
sourceGroupDescription: Vendor Payments
isEnabled: false
Mandate Products Schema
| Field | Type | Required | Description |
|---|---|---|---|
productCode | string | Yes | Unique product identifier (referenced in CreateNibssMandateCommand) |
productName | string | Yes | Display name for the product |
productDescription | string | No | Detailed product description |
isActive | bool | No | Whether the product is available for new mandates (default: true) |
Disbursement Sources Schema
| Field | Type | Required | Description |
|---|---|---|---|
accountNumber | string | Yes | Source account number |
sourceAccountName | string | Yes | Display name for the source account |
sourceAccountCIF | string | No | Core banking CIF for the source account |
sourceChannel | string | No | Channel identifier (e.g. INTERNAL, NIBSS) |
disbursementSourceAccountGroup | int | No | Group number for categorising sources (default: 1) |
sourceGroupDescription | string | No | Description of the source group |
isEnabled | bool | No | Whether the source is available for new batches (default: true) |
The CC config is managed via the Config Definition screen in the admin portal. Use CreateConfigDefinitionCommand with code CC to create or update the configuration programmatically. The YAML is validated on save using ChannelYamlConfigValidation.
NIBSS Configuration
NIBSS integration uses the ITransferProviderWrapper with provider key Nibss. Connection strings are configured per-tenant via:
ConnectionStrings:NibssConnection— Direct NIBSS databaseConnectionStrings:NibssExternalConnection— External NIBSS access
Auto-Migration
Both Administration.Api and Nibss.Api support automatic database migration on startup:
{
"AutoMigrate": {
"Enabled": true
}
}
When enabled:
- Administration.Api: Iterates all active tenants from MasterDb and applies pending
AdministrationDbContextmigrations for each - Nibss.Api: Applies pending
NibssDbContextmigrations (or creates schema if no migrations exist)
Set AutoMigrate:Enabled to false in production unless you want migrations to auto-apply. Recommended: enable only during deployment, then disable.
7. Process Entity Types & Trigger Events
These enums are used when configuring BPMN process definitions to bind a process to a specific entity type and trigger event.
ProcessEntityType
Used in process definition YAML as the entityType field. Determines which entity a process instance is associated with.
| Value | YAML Alias | Description |
|---|---|---|
0 | none | Not associated with any entity |
1 | entity | Generic entity |
2 | contact | Core Banking — Contact |
3 | loan | Core Banking — Loan |
4 | deposit | Core Banking — Deposit |
5 | insurancePolicy | Core Insurance — Policy |
6 | insuranceClaim | Core Insurance — Claims |
11 | transaction | Core Banking — Transaction |
13 | teller | Core Banking — Teller Transaction |
14 | inwardTransaction | Integrations — Inward Transaction |
15 | scheduledProcess | Scheduled Process |
16 | employeeRecord | HR — Employee Record |
100 | customerRegistration | Channel — Customer Registration |
101 | loanRequest | Channel — Loan Request |
102 | transferRequest | Channel — Transfer Request |
103 | billsPaymentRequest | Channel — Bills Payment Request |
104 | airtimeRechargeRequest | Channel — Airtime Recharge Request |
105 | dataRechargeRequest | Channel — Data Recharge Request |
106 | selfServiceUser | Channel — User (Corporate or Individual) |
200 | reconciliationJob | Reconciliation Job |
250 | transactionMonitoringData | Transaction Monitoring Data |
300 | disbursementBatch | Operations — Disbursement Batch |
301 | disbursement | Operations — Disbursement |
310 | nibssMandateBatch | NIBSS — Mandate Batch |
311 | nibssMandate | NIBSS — Mandate |
320 | nibssCollectionBatch | NIBSS — Collection Batch |
321 | nibssCollection | NIBSS — Collection |
330 | remitaLoanRequest | Remita — Loan Request |
331 | remitaCollectionBatch | Remita — Collection Batch |
332 | remitaCollection | Remita — Collection |
ProcessDefinitionTriggerEventsEnum
Used in process definition YAML as the triggerEvent field. Determines which event automatically starts a process instance.
Customer / Contact Events (1–99)
| Value | YAML Alias | Description |
|---|---|---|
1 | onCustomerCreation | New customer created |
2 | onCustomerUpdated | Customer info updated |
3 | onNewRegistration | New customer registration completed |
Loan Events (100–199)
| Value | YAML Alias | Description |
|---|---|---|
100 | onLoanCreation | New loan created |
101 | onLoanDisbursed | Loan disbursed |
102 | onLoanRescheduled | Loan rescheduled |
103 | onLoanRefinanced | Loan refinanced |
104 | onLoanUpdated | Loan details updated |
Deposit / Account Events (200–299)
| Value | YAML Alias | Description |
|---|---|---|
200 | onAccountCreation | New account created |
201 | onDepositCreation | New deposit created |
202 | onDepositAccountUpdated | Deposit account updated |
Transaction Events (300–399)
| Value | YAML Alias | Description |
|---|---|---|
300 | onTransactionCreation | New transaction created |
301 | onTransactionIngestion | Transaction ingested for monitoring |
302 | onTransactionEvaluation | Transaction evaluated by rules |
Transfer Events (400–499)
| Value | YAML Alias | Description |
|---|---|---|
400 | onTransferReceived | Transfer received |
401 | onTransferInitiated | Transfer initiated |
402 | onTransferCompleted | Transfer completed |
Inward Transaction / NIBSS Events (500–599)
| Value | YAML Alias | Description |
|---|---|---|
500 | onInwardTransactionReceived | Inward transaction received from NIBSS |
501 | onInwardTransactionProcessed | Inward transaction processed |
502 | onInwardTransactionFailed | Inward transaction failed |
503 | onInwardTransactionReversed | Inward transaction reversed |
Bills Payment Events (600–699)
| Value | YAML Alias | Description |
|---|---|---|
600 | onBillsPaymentTransactionInitiated | Bills payment initiated |
601 | onBillsPaymentTransactionCompleted | Bills payment completed |
602 | onBillsPaymentTransactionFailed | Bills payment failed |
603 | onBillsPaymentTransactionReversed | Bills payment reversed |
Airtime Recharge Events (700–799)
| Value | YAML Alias | Description |
|---|---|---|
700 | onAirtimeRechargeTransactionInitiated | Airtime recharge initiated |
701 | onAirtimeRechargeTransactionCompleted | Airtime recharge completed |
702 | onAirtimeRechargeTransactionFailed | Airtime recharge failed |
703 | onAirtimeRechargeTransactionReversed | Airtime recharge reversed |
Data Recharge Events (800–899)
| Value | YAML Alias | Description |
|---|---|---|
800 | onDataRechargeTransactionInitiated | Data recharge initiated |
801 | onDataRechargeTransactionCompleted | Data recharge completed |
802 | onDataRechargeTransactionFailed | Data recharge failed |
803 | onDataRechargeTransactionReversed | Data recharge reversed |
Teller Events (900–999)
| Value | YAML Alias | Description |
|---|---|---|
900 | onCashDeposit | Cash deposit at teller |
901 | onCashWithdrawal | Cash withdrawal at teller |
902 | onTellerBalanceCheck | Teller balance check |
903 | onTellerEndOfDay | Teller end-of-day closing |
904 | onTellerTransactionReversal | Teller transaction reversed |
Insurance Events (1000–1099)
| Value | YAML Alias | Description |
|---|---|---|
1000 | onInsurancePolicyCreation | New insurance policy created |
Reconciliation Events (1100–1199)
| Value | YAML Alias | Description |
|---|---|---|
1100 | onReconciliationJobStart | Reconciliation job started |
1101 | onReconciliationJobCompletion | Reconciliation job completed |
1102 | onReconciliationDataUpdate | Reconciliation data updated |
1103 | onReconciliationError | Reconciliation error occurred |
Monitoring / Alert Events (1200–1299)
| Value | YAML Alias | Description |
|---|---|---|
1200 | onMonitoringAlertRaised | Monitoring alert raised |
1201 | onMonitoringAlertAcknowledged | Monitoring alert acknowledged |
1202 | onMonitoringAlertResolved | Monitoring alert resolved |
Channel / Self-Service User Events (1300–1399)
| Value | YAML Alias | Description |
|---|---|---|
1300 | onChannelCustomerRegistration | Customer registered via self-service |
1301 | onLoanOriginationRequestCreated | Loan origination request created |
1302 | onChannelDocumentUploaded | Document uploaded via channel |
1303 | onChannelIdentityDocumentUploaded | Identity document uploaded |
1304 | onCorporateUserCreated | Corporate self-service user created |
1305 | onBackOfficeUserCreated | Back-office user created |
1306 | onUserLoginCompleted | Self-service user login completed |
Loan Request Events (1400–1499)
| Value | YAML Alias | Description |
|---|---|---|
1400 | onChannelLoanRequestCreated | Channel loan request created |
1401 | onChannelLoanRequestCreditSearchMade | Credit search made for loan request |
1402 | onChannelLoanRequestStatementRequestMade | Statement request made for loan request |
Employee Record Events (1500–1599)
| Value | YAML Alias | Description |
|---|---|---|
1500 | onEmployeeRecordCreated | New employee record created |
1501 | onEmployeeRecordUpdated | Employee record updated |
1502 | onEmployeeRecordDeactivated | Employee record deactivated |
Disbursement Batch Events (1600–1699)
| Value | YAML Alias | Description |
|---|---|---|
1600 | onDisbursementBatchCreated | New disbursement batch created |
1601 | onDisbursementBatchApproved | Disbursement batch approved |
1602 | onDisbursementBatchProcessed | Disbursement batch fully processed |
1603 | onDisbursementBatchFailed | Disbursement batch failed |
Disbursement Events (1700–1799)
| Value | YAML Alias | Description |
|---|---|---|
1700 | onDisbursementCreated | New disbursement created |
1701 | onDisbursementCompleted | Disbursement completed successfully |
1702 | onDisbursementFailed | Disbursement failed |
1703 | onDisbursementReversed | Disbursement reversed |
NIBSS Mandate Batch Events (1800–1899)
| Value | YAML Alias | Description |
|---|---|---|
1800 | onNibssMandateBatchCreated | New NIBSS mandate batch created |
1801 | onNibssMandateBatchSubmitted | NIBSS mandate batch submitted |
1802 | onNibssMandateBatchCompleted | NIBSS mandate batch fully processed |
1803 | onNibssMandateBatchFailed | NIBSS mandate batch failed |
NIBSS Mandate Events (1900–1999)
| Value | YAML Alias | Description |
|---|---|---|
1900 | onNibssMandateCreated | New NIBSS mandate created |
1901 | onNibssMandateActivated | NIBSS mandate activated |
1902 | onNibssMandateSuspended | NIBSS mandate suspended |
1903 | onNibssMandateCancelled | NIBSS mandate cancelled |
NIBSS Collection Batch Events (2000–2099)
| Value | YAML Alias | Description |
|---|---|---|
2000 | onNibssCollectionBatchCreated | New NIBSS collection batch created |
2001 | onNibssCollectionBatchSubmitted | NIBSS collection batch submitted |
2002 | onNibssCollectionBatchCompleted | NIBSS collection batch fully processed |
2003 | onNibssCollectionBatchFailed | NIBSS collection batch failed |
NIBSS Collection Events (2100–2199)
| Value | YAML Alias | Description |
|---|---|---|
2100 | onNibssCollectionCreated | New NIBSS collection created |
2101 | onNibssCollectionCompleted | NIBSS collection completed successfully |
2102 | onNibssCollectionFailed | NIBSS collection failed |
2103 | onNibssCollectionReversed | NIBSS collection reversed |
Remita Loan Request Events (2200–2299)
| Value | YAML Alias | Description |
|---|---|---|
2200 | onRemitaLoanRequestCreated | New Remita loan request created |
2201 | onRemitaLoanRequestApproved | Remita loan request approved |
2202 | onRemitaLoanRequestRejected | Remita loan request rejected |
2203 | onRemitaLoanMandateActivated | Remita loan mandate activated |
2204 | onRemitaLoanDisbursed | Remita loan disbursed |
Remita Collection Batch Events (2300–2399)
| Value | YAML Alias | Description |
|---|---|---|
2300 | onRemitaCollectionBatchCreated | New Remita collection batch created |
2301 | onRemitaCollectionBatchAuthorized | Remita collection batch authorized |
2302 | onRemitaCollectionBatchCompleted | Remita collection batch completed |
2303 | onRemitaCollectionBatchFailed | Remita collection batch failed |
Remita Collection Events (2400–2499)
| Value | YAML Alias | Description |
|---|---|---|
2400 | onRemitaCollectionCreated | New Remita collection created |
2401 | onRemitaCollectionCompleted | Remita collection completed successfully |
2402 | onRemitaCollectionFailed | Remita collection failed |
2403 | onRemitaCollectionReversed | Remita collection reversed |
Scheduled Execution
| Value | YAML Alias | Description |
|---|---|---|
9999 | onScheduledExecution | Triggered by Hangfire scheduled process |