Skip to main content

Universal Transaction Management

Overview

BankLingo provides a universal transaction management system that standardizes approval, rejection, cancellation, and reversal workflows across all transaction types. These commands work consistently whether you're managing deposits, withdrawals, cheque transactions, loan disbursements, teller operations, vault movements, or till transfers.

This document describes the four universal commands that enable consistent transaction lifecycle management throughout the core banking system.

Transaction State Model

All transactions in BankLingo follow a standardized state model with four possible states:

Transaction States

State Descriptions

StateDescriptionEntry PointExit PointsBalance ImpactHold Impact
PENDINGTransaction awaits approvalCreated with requireApproval=trueSETTLED (approve), CANCELLED (reject/cancel)NoneIncreased
SETTLEDTransaction completed successfullyCreated with requireApproval=false OR approved from PENDINGREVERSED (reverse)UpdatedReleased
CANCELLEDTransaction rejected before settlementRejected/cancelled from PENDINGNone (terminal)NoneReleased
REVERSEDTransaction reversed after settlementReversed from SETTLEDNone (terminal)RestoredN/A

Universal Commands

1. ApproveTransactionCommand

Approves a pending transaction, transitioning it from PENDING to SETTLED and applying balance changes.

Endpoint

POST /api/bpm/cmd/ApproveTransaction

Request Body

FieldTypeRequiredDescription
transactionIdguidYesUnique identifier of the pending transaction
approverNotesstringNoOptional notes from approver (max 500 characters)
approvalDatedatetimeNoOptional approval date (defaults to current time)

Example Request

{
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"approverNotes": "High-value deposit verified. Customer identity confirmed via BVN.",
"approvalDate": "2026-01-01T14:30:00Z"
}

Response (200 OK)

{
"isSuccessful": true,
"message": "Transaction approved successfully",
"data": {
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"previousState": "PENDING",
"newState": "SETTLED",
"approvedBy": "Jane Smith",
"approvalDate": "2026-01-01T14:30:00Z",
"balanceImpact": {
"accountNumber": "2001234567",
"previousBalance": 100000.00,
"newBalance": 600000.00,
"transactionAmount": 500000.00,
"holdReleased": 500000.00
}
}
}

Approval Effects by Transaction Type

Transaction TypeBalance ChangeAdditional Effects
DepositAccount balance increasedHold released, available balance increased
WithdrawalAccount balance decreasedHold released, cash dispensed, available balance decreased
Cheque DepositAccount balance increasedCheque state → CLEARED (if cheque also approved), hold released
Cheque WithdrawalAccount balance decreasedCheque state → CLEARED, hold released
Loan DisbursementLoan account fundedLoan state → DISBURSED, disbursement amount transferred
Teller TransactionTill/account balance updatedTill balance updated, hold released
Vault TransactionVault balance updatedVault inventory updated
Till TransferBoth tills updatedSource till decreased, destination till increased

2. RejectTransactionCommand

Rejects a pending transaction, transitioning it from PENDING to CANCELLED without applying balance changes.

Endpoint

POST /api/bpm/cmd/RejectTransaction

Request Body

FieldTypeRequiredDescription
transactionIdguidYesUnique identifier of the pending transaction
rejectionReasonstringYesReason for rejection (required for audit, max 1000 characters)
rejectionCategorystringNoCategory: FRAUD, COMPLIANCE, INSUFFICIENT_DOCUMENTATION, POLICY_VIOLATION, OTHER

Example Request

{
"transactionId": "b2c3d4e5-f6g7-8901-bcde-f12345678901",
"rejectionReason": "Customer unable to provide valid source of funds documentation. Transaction flagged for AML review.",
"rejectionCategory": "COMPLIANCE"
}

Response (200 OK)

{
"isSuccessful": true,
"message": "Transaction rejected successfully",
"data": {
"transactionId": "b2c3d4e5-f6g7-8901-bcde-f12345678901",
"previousState": "PENDING",
"newState": "CANCELLED",
"rejectedBy": "John Doe",
"rejectionDate": "2026-01-01T15:00:00Z",
"rejectionReason": "Customer unable to provide valid source of funds documentation. Transaction flagged for AML review.",
"rejectionCategory": "COMPLIANCE",
"balanceImpact": {
"accountNumber": "2001234567",
"balance": 100000.00,
"holdReleased": 500000.00,
"netChange": 0.00
}
}
}

Rejection Effects

  • ✅ Transaction state: PENDING → CANCELLED
  • ✅ Hold released (if applicable)
  • ✅ Balance unchanged (transaction never settled)
  • ✅ Customer notified of rejection (via SMS/Email)
  • ✅ Audit trail created with rejection reason
  • ✅ Compliance report generated (if fraud/AML category)

3. CancelTransactionCommand

Cancels a pending transaction, transitioning it from PENDING to CANCELLED. Functionally equivalent to RejectTransaction but typically initiated by the transaction creator rather than an approver.

Endpoint

POST /api/bpm/cmd/CancelTransaction

Request Body

FieldTypeRequiredDescription
transactionIdguidYesUnique identifier of the pending transaction
cancellationReasonstringYesReason for cancellation (required for audit, max 1000 characters)

Example Request

{
"transactionId": "c3d4e5f6-g7h8-9012-cdef-123456789012",
"cancellationReason": "Customer requested cancellation before approval. Will re-submit with correct beneficiary account."
}

Response (200 OK)

{
"isSuccessful": true,
"message": "Transaction cancelled successfully",
"data": {
"transactionId": "c3d4e5f6-g7h8-9012-cdef-123456789012",
"previousState": "PENDING",
"newState": "CANCELLED",
"cancelledBy": "Jane Smith",
"cancellationDate": "2026-01-01T16:00:00Z",
"cancellationReason": "Customer requested cancellation before approval. Will re-submit with correct beneficiary account.",
"balanceImpact": {
"accountNumber": "2001234567",
"balance": 100000.00,
"holdReleased": 500000.00,
"netChange": 0.00
}
}
}

Cancel vs Reject

AspectCancelTransactionRejectTransaction
InitiatorTransaction creator, customer, or systemApprover or compliance officer
ContextVoluntary cancellation (error correction, customer request)Denial after review (fraud, policy violation, insufficient docs)
Reason RequiredYesYes
Category FieldNoYes (FRAUD, COMPLIANCE, etc.)
Compliance ReportNoYes (for certain categories)
Customer NotificationOptionalMandatory
EffectPENDING → CANCELLEDPENDING → CANCELLED

4. ReverseTransactionCommand

Reverses a settled transaction, transitioning it from SETTLED to REVERSED and restoring the original balance state.

Endpoint

POST /api/bpm/cmd/ReverseTransaction

Request Body

FieldTypeRequiredDescription
transactionIdguidYesUnique identifier of the settled transaction
reversalReasonstringYesReason for reversal (required for audit, max 1000 characters)
reversalNarrationstringNoNarration for reversal transaction (max 200 characters)
reversalCategorystringNoCategory: ERROR_CORRECTION, FRAUD, CUSTOMER_REQUEST, SYSTEM_ERROR, DUPLICATE, OTHER

Example Request

{
"transactionId": "d4e5f6g7-h8i9-0123-defg-234567890123",
"reversalReason": "Duplicate transaction detected. Original transaction TXN-20260101-123456 already processed on 2025-12-31.",
"reversalNarration": "Reversal: Duplicate Deposit - TXN-20260101-234567",
"reversalCategory": "DUPLICATE"
}

Response (200 OK)

{
"isSuccessful": true,
"message": "Transaction reversed successfully",
"data": {
"transactionId": "d4e5f6g7-h8i9-0123-defg-234567890123",
"previousState": "SETTLED",
"newState": "REVERSED",
"reversedBy": "John Doe",
"reversalDate": "2026-01-02T09:00:00Z",
"reversalReason": "Duplicate transaction detected. Original transaction TXN-20260101-123456 already processed on 2025-12-31.",
"reversalCategory": "DUPLICATE",
"balanceImpact": {
"accountNumber": "2001234567",
"previousBalance": 600000.00,
"newBalance": 100000.00,
"reversalAmount": -500000.00
},
"reversalTransactionId": "e5f6g7h8-i9j0-1234-efgh-345678901234",
"originalTransaction": {
"transactionDate": "2026-01-01T10:00:00Z",
"amount": 500000.00,
"narration": "Cash Deposit"
}
}
}

Reversal Effects by Transaction Type

Transaction TypeBalance ChangeAdditional Effects
DepositAccount balance decreasedFunds withdrawn from account
WithdrawalAccount balance increasedFunds returned to account (cash must be physically returned)
Cheque DepositAccount balance decreasedCheque state → BOUNCED or REVERSED
Cheque WithdrawalAccount balance increasedCheque state → CANCELLED
Loan DisbursementLoan account defundedLoan state → APPROVED (reverted), funds returned to disbursement GL
Teller TransactionTill/account balance reversedTill balance adjusted, audit log updated
Vault TransactionVault balance reversedVault inventory adjusted
Till TransferBoth tills reversedSource till increased, destination till decreased

Reversal Restrictions

Reversal Time Limits

Most transactions have time limits for reversal:

  • Same-Day Reversals: Typically allowed within 24 hours
  • Next-Day Reversals: May require supervisor approval
  • Aged Reversals (more than 48 hours): Require senior management approval and detailed justification
  • Inter-Bank Transfers: May be irreversible after settlement window closes
  • Loan Disbursements: Require customer account to have sufficient balance if funds already withdrawn

Workflow Examples

Example 1: High-Value Deposit with Approval

Scenario: Customer deposits ₦5,000,000 cash. Bank policy requires approval for deposits greater than ₦1,000,000.

Step 1: Create Deposit (PENDING)

POST /api/bpm/cmd/InitiateDeposit

{
"accountNumber": "2001234567",
"amount": 5000000.00,
"narration": "Cash Deposit",
"requireApproval": true,
"channel": "BRANCH"
}

Response:
{
"transactionId": "txn-001",
"status": "PENDING",
"holdAmount": 5000000.00,
"balance": 100000.00,
"availableBalance": 100000.00
}

Step 2: Approve Deposit

POST /api/bpm/cmd/ApproveTransaction

{
"transactionId": "txn-001",
"approverNotes": "Cash source verified. Customer provided employment letter and payslip."
}

Response:
{
"newState": "SETTLED",
"balance": 5100000.00,
"availableBalance": 5100000.00,
"holdReleased": 5000000.00
}

Example 2: Suspicious Withdrawal Rejected

Scenario: Customer attempts to withdraw ₦2,000,000. Transaction flagged for suspicious activity (account dormant for 6 months, sudden large withdrawal).

Step 1: Create Withdrawal (PENDING)

POST /api/bpm/cmd/InitiateWithdrawal

{
"accountNumber": "2001234567",
"amount": 2000000.00,
"narration": "Cash Withdrawal",
"requireApproval": true,
"channel": "BRANCH"
}

Response:
{
"transactionId": "txn-002",
"status": "PENDING",
"holdAmount": 2000000.00,
"balance": 5100000.00,
"availableBalance": 3100000.00
}

Step 2: Reject Withdrawal

POST /api/bpm/cmd/RejectTransaction

{
"transactionId": "txn-002",
"rejectionReason": "Account dormant for 6 months. Large withdrawal request requires additional KYC verification and face-to-face interview with branch manager.",
"rejectionCategory": "COMPLIANCE"
}

Response:
{
"newState": "CANCELLED",
"balance": 5100000.00,
"availableBalance": 5100000.00,
"holdReleased": 2000000.00
}

Example 3: Duplicate Deposit Reversal

Scenario: Teller accidentally processes same deposit twice. Second deposit must be reversed.

Step 1: Create Two Deposits (SETTLED - direct)

POST /api/bpm/cmd/InitiateDeposit

{
"accountNumber": "2001234567",
"amount": 50000.00,
"narration": "Cash Deposit",
"requireApproval": false
}

Response 1: balance = 5150000.00
Response 2 (duplicate): balance = 5200000.00

Step 2: Reverse Duplicate

POST /api/bpm/cmd/ReverseTransaction

{
"transactionId": "txn-004",
"reversalReason": "Duplicate transaction. Original transaction txn-003 already processed.",
"reversalNarration": "Reversal: Duplicate Deposit",
"reversalCategory": "DUPLICATE"
}

Response:
{
"newState": "REVERSED",
"previousBalance": 5200000.00,
"newBalance": 5150000.00,
"reversalAmount": -50000.00
}

Example 4: Customer-Requested Cancellation

Scenario: Customer initiates online transfer, realizes wrong beneficiary account, cancels before approval.

Step 1: Create Transfer (PENDING)

POST /api/bpm/cmd/InitiateWithdrawal

{
"accountNumber": "2001234567",
"amount": 100000.00,
"narration": "Transfer to 3001234567",
"requireApproval": true,
"channel": "ONLINE"
}

Response:
{
"transactionId": "txn-005",
"status": "PENDING",
"availableBalance": 5050000.00
}

Step 2: Cancel Transfer

POST /api/bpm/cmd/CancelTransaction

{
"transactionId": "txn-005",
"cancellationReason": "Customer entered wrong beneficiary account. Will re-submit with correct account number."
}

Response:
{
"newState": "CANCELLED",
"balance": 5150000.00,
"availableBalance": 5150000.00,
"holdReleased": 100000.00
}

Balance Impact Formulas

PENDING State (Approval Required)

When a transaction is created with requireApproval = true:

Deposit:

Account Balance:        Unchanged
Hold Amount: +Transaction Amount
Available Balance: Unchanged

Withdrawal:

Account Balance:        Unchanged
Hold Amount: +Transaction Amount
Available Balance: -Transaction Amount

SETTLED State (Approved or Direct)

When a transaction is approved or created with requireApproval = false:

Deposit:

Account Balance:        +Transaction Amount
Hold Amount: -Transaction Amount (released)
Available Balance: +Transaction Amount

Withdrawal:

Account Balance:        -Transaction Amount
Hold Amount: -Transaction Amount (released)
Available Balance: Unchanged (hold already deducted)

CANCELLED State (Rejected or Cancelled)

When a transaction is rejected or cancelled:

Deposit:

Account Balance:        Unchanged
Hold Amount: -Transaction Amount (released)
Available Balance: Unchanged

Withdrawal:

Account Balance:        Unchanged
Hold Amount: -Transaction Amount (released)
Available Balance: +Transaction Amount (restored)

REVERSED State (Reversal)

When a settled transaction is reversed:

Deposit Reversal:

Account Balance:        -Transaction Amount
Available Balance: -Transaction Amount

Withdrawal Reversal:

Account Balance:        +Transaction Amount
Available Balance: +Transaction Amount

Authorization & Permissions

Universal commands require specific permissions based on transaction amount and type:

Permission Matrix

CommandPermissionAdditional Requirements
ApproveTransactiontransactions.approveAmount-based approval limits (see below)
RejectTransactiontransactions.approve OR transactions.rejectRejection reason required
CancelTransactiontransactions.create (own txn) OR transactions.cancel (any txn)Must be transaction creator or have cancel permission
ReverseTransactiontransactions.reverseReversal reason required, time limits apply

Approval Limits by Role

RoleAmount LimitTransaction Types
Teller≤ ₦500,000Deposits, Withdrawals, Teller transactions
Senior Teller≤ ₦2,000,000All retail transactions
Approver≤ ₦5,000,000All transaction types
Branch Manager≤ ₦50,000,000All transaction types including loan disbursements
Regional Manager≤ ₦200,000,000All transaction types, multi-branch
AdminUnlimitedAll transaction types

Configuration

Approval Threshold Configuration

Configure approval thresholds by transaction type and channel:

{
"transactionType": "DEPOSIT",
"channel": "BRANCH",
"thresholds": [
{
"accountTier": "BASIC",
"amountThreshold": 500000.00,
"requireApproval": true,
"approverRole": "Teller"
},
{
"accountTier": "PREMIUM",
"amountThreshold": 2000000.00,
"requireApproval": true,
"approverRole": "Senior Teller"
},
{
"accountTier": "VIP",
"amountThreshold": 10000000.00,
"requireApproval": true,
"approverRole": "Branch Manager"
}
]
}

Reversal Window Configuration

Configure time limits for reversals:

{
"transactionType": "DEPOSIT",
"reversalWindows": [
{
"windowName": "Same-Day",
"maxHours": 24,
"requiresApproval": false
},
{
"windowName": "Next-Day",
"maxHours": 48,
"requiresApproval": true,
"approverRole": "Branch Manager"
},
{
"windowName": "Aged",
"maxHours": 720,
"requiresApproval": true,
"approverRole": "Regional Manager",
"requiresDetailedJustification": true
}
]
}

Error Handling

Common Error Codes

CodeHTTP StatusDescriptionResolution
TRANSACTION_NOT_FOUND404Transaction ID does not existVerify transaction ID
INVALID_STATE_TRANSITION400Cannot transition from current stateCheck transaction current state
TRANSACTION_NOT_PENDING400Transaction is not in PENDING stateOnly PENDING transactions can be approved/rejected/cancelled
TRANSACTION_NOT_SETTLED400Transaction is not in SETTLED stateOnly SETTLED transactions can be reversed
INSUFFICIENT_PERMISSIONS403User lacks required permissionsAssign appropriate role/permissions
APPROVAL_LIMIT_EXCEEDED403Transaction amount exceeds user's approval limitEscalate to higher-level approver
REVERSAL_WINDOW_EXPIRED400Transaction too old to reverseRequires special approval or alternative correction
DUPLICATE_REQUEST409Transaction already in target stateRefresh transaction status
CUSTOMER_ACCOUNT_CLOSED400Customer account is closedCannot process transactions on closed accounts
INSUFFICIENT_BALANCE400Insufficient balance for reversalReversal of withdrawal requires sufficient balance

Error Response Example

{
"isSuccessful": false,
"message": "Transaction approval failed",
"errors": [
{
"code": "APPROVAL_LIMIT_EXCEEDED",
"message": "Transaction amount (₦10,000,000) exceeds your approval limit (₦5,000,000). Escalate to Branch Manager.",
"transactionAmount": 10000000.00,
"userApprovalLimit": 5000000.00,
"requiredRole": "Branch Manager"
}
]
}

Audit & Compliance

Audit Log Entries

Every universal command execution creates an audit log entry:

{
"eventType": "TransactionApproved",
"timestamp": "2026-01-01T14:30:00Z",
"userId": "user-123",
"userName": "Jane Smith",
"role": "Branch Manager",
"action": "ApproveTransaction",
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"transactionType": "DEPOSIT",
"transactionAmount": 5000000.00,
"previousState": "PENDING",
"newState": "SETTLED",
"approverNotes": "Cash source verified. Customer provided employment letter and payslip.",
"balanceImpact": {
"previousBalance": 100000.00,
"newBalance": 5100000.00,
"holdReleased": 5000000.00
},
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"branchId": "branch-456",
"branchName": "Lagos Main Branch"
}

Compliance Reporting

High-value transactions and certain categories trigger compliance reports:

Triggers:

  • Transactions greater than ₦5,000,000 (AML reporting threshold)
  • Rejection category: FRAUD, COMPLIANCE
  • Multiple failed approval attempts
  • Reversals greater than ₦1,000,000
  • Frequent cancellations by same user (velocity check)

Reports Generated:

  • Suspicious Activity Report (SAR): Submitted to NFIU (Nigeria Financial Intelligence Unit)
  • High-Value Transaction Report: Daily report to Central Bank of Nigeria
  • Reversal Report: Weekly report to Risk Management and Audit

Best Practices

When to Require Approval

DO Require Approval When:

  • Transaction amount exceeds configured threshold
  • Customer account flagged for suspicious activity
  • Dormant account (no activity greater than 90 days)
  • New account (less than 30 days old)
  • High-risk transaction channel (ATM, online, mobile)
  • Customer's first international transfer
  • Unusual transaction pattern detected

DO NOT Require Approval When:

  • Low-value routine transactions (less than ₦50,000)
  • Automated recurring transactions (salary, bill payments)
  • Pre-authorized standing orders
  • Inter-account transfers within same customer
  • Teller-to-teller till transfers (branch operations)

When to Reverse vs Cancel

Use CancelTransaction:

  • Transaction still in PENDING state
  • Customer requests cancellation before approval
  • Data entry error detected before settlement
  • Duplicate pending transaction identified
  • Customer account validation fails

Use ReverseTransaction:

  • Transaction already SETTLED
  • Duplicate settled transaction detected
  • Fraud identified after settlement
  • Customer disputes transaction post-settlement
  • System error resulted in incorrect settlement

Security Considerations

  1. Dual Authorization

    • High-value approvals (greater than ₦10M) require two approvers
    • Reversal of high-value transactions requires maker-checker workflow
    • Inter-bank transfers require additional authorization
  2. Time-Based Controls

    • Reversals older than 48 hours require additional approval
    • Pending transactions auto-expire after 24 hours (configurable)
    • Approval SLA monitoring (flag transactions pending greater than 4 hours)
  3. Fraud Prevention

    • Velocity checks (max 5 approvals per user per hour)
    • Amount-based alerts (flag approvals greater than user's typical limit)
    • Pattern detection (unusual approval times, locations, devices)
  4. Audit Trail

    • All actions logged with user identity, timestamp, IP address
    • Immutable audit logs stored for 10 years (regulatory requirement)
    • Real-time monitoring of high-value approvals/reversals

Transaction Type Support

Universal commands work across all BankLingo transaction types:

Transaction CategoryTransaction TypesApproval SupportReversal Support
DepositsCash Deposit, Cheque Deposit, Transfer-In✅ Full✅ Full
WithdrawalsCash Withdrawal, Cheque Withdrawal, Transfer-Out✅ Full✅ Full
Cheque OperationsCheque Deposit, Cheque Withdrawal, Cheque Clearing✅ Full (two-level)✅ Full
Loan TransactionsLoan Disbursement, Loan Repayment⏳ Planned (disbursement)✅ Full
Teller OperationsDeposit to Till, Withdraw from Till✅ Full✅ Full
Till ManagementAdd Cash, Remove Cash, Transfer Between Tills✅ Full✅ Full
Vault OperationsFund Vault, Transfer from Vault✅ Full✅ Full


Performance Characteristics

MetricValueNotes
Average Approval Time200-300msInternal processing
Average Rejection Time150-200msFaster than approval (no balance update)
Average Cancellation Time150-200msSame as rejection
Average Reversal Time300-500msSlower due to accounting entries
Concurrent ApprovalsUp to 1000/secondHorizontally scalable
Approval SLA4 hoursTransactions pending greater than 4 hours flagged

Summary

BankLingo's universal transaction management system provides:

Standardized Workflow: Consistent approval/rejection/cancellation/reversal across all transaction types
Flexible Approval: Configurable thresholds by amount, account tier, channel, and transaction type
Granular Permissions: Role-based approval limits with escalation support
Complete Audit Trail: Immutable logs for every state transition
Balance Safety: Holds prevent double-spending, reversals restore original state
Compliance Ready: Automated reporting for high-value transactions and suspicious activity
Future-Proof: Approval workflow being extended to loan disbursements (planned)

Key Commands:

  • ApproveTransaction: PENDING → SETTLED (apply balance changes)
  • RejectTransaction: PENDING → CANCELLED (release hold, no balance change)
  • CancelTransaction: PENDING → CANCELLED (same as reject, different initiator)
  • ReverseTransaction: SETTLED → REVERSED (restore original balance)