Skip to main content

Cheque Transaction

Complete guide to cheque transactions in BankLingo V2, including clearing cycle, state management, and settlement processes.


Overview

A Cheque Transaction processes physical or electronic cheques through a multi-day clearing cycle before funds are finally transferred.

Key Characteristics:

  • Multi-Day Clearing Cycle: Typically 3-5 business days
  • State Progression: PENDING → CLEARING → CLEARED/RETURNED
  • Settlement Integration: Integration with cheque clearing house (e.g., NIBSS Instant Payment)
  • Reversal Support: Cheques can be returned unpaid
  • Imaging Support: Capture and store cheque images

Transaction Types:

  • Cheque Deposit: Customer deposits a cheque (credit to account after clearing)
  • Cheque Withdrawal: Customer writes a cheque (debit from account on clearing)
  • Cheque Return: Cheque bounced/dishonored (reversal)

Transaction Flow

Cheque Deposit Flow

Cheque Withdrawal Flow

Entities Impacted

Scenario 1: Local Cheque Deposit (Instant Credit)

Customer deposits NGN 100,000 cheque from same bank

PENDING/CLEARING Phase (Instant Credit):

{
transactionId: "CHQ123456",
transactionState: "CLEARING",
chequeClearingId: 789,
impactedEntities: [
// Deposit Account (Immediate Credit)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "AvailableBalance",
oldValue: 50000.00,
newValue: 150000.00,
deltaAmount: +100000.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "BookBalance",
oldValue: 50000.00,
newValue: 150000.00,
deltaAmount: +100000.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "State",
oldValue: "PENDING",
newValue: "CLEARING",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "ImmediateCredit",
oldValue: null,
newValue: true,
deltaAmount: 0
}
]
}
```text
**CLEARED Phase** (Final Settlement):

```typescript
{
transactionId: "CHQ123456",
transactionState: "CLEARED",
impactedEntities: [
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "State",
oldValue: "CLEARING",
newValue: "CLEARED",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "ClearedDate",
oldValue: null,
newValue: "2025-12-28T10:30:00Z",
deltaAmount: 0
},
// GL Accounts (Settlement)
{
entityType: "GLAccount",
entityKey: "1200-001", // Clearing Account
fieldName: "DebitAmount",
deltaAmount: +100000.00
},
{
entityType: "GLAccount",
entityKey: "2100-001", // Customer Deposits
fieldName: "CreditAmount",
deltaAmount: +100000.00
}
]
}
```text
### Scenario 2: External Cheque Deposit (No Immediate Credit)

**Customer deposits NGN 200,000 cheque from another bank**

**PENDING Phase** (No Credit Yet):

```typescript
{
transactionId: "CHQ234567",
transactionState: "PENDING",
chequeClearingId: 890,
impactedEntities: [
// Deposit Account (No Balance Change)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "PendingCredits",
oldValue: 0.00,
newValue: 200000.00,
deltaAmount: +200000.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 890,
entityKey: "CHQ-CLR-890",
fieldName: "State",
oldValue: null,
newValue: "PENDING",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 890,
entityKey: "CHQ-CLR-890",
fieldName: "IssuerBankCode",
oldValue: null,
newValue: "058", // External bank
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 890,
entityKey: "CHQ-CLR-890",
fieldName: "ExpectedClearingDate",
oldValue: null,
newValue: "2026-01-02", // 3 business days
deltaAmount: 0
}
]
}
```text
**CLEARED Phase** (Credit After Clearing):

```typescript
{
transactionId: "CHQ234567",
transactionState: "CLEARED",
impactedEntities: [
// Deposit Account (Credit Now)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "AvailableBalance",
oldValue: 50000.00,
newValue: 250000.00,
deltaAmount: +200000.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "BookBalance",
oldValue: 50000.00,
newValue: 250000.00,
deltaAmount: +200000.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "PendingCredits",
oldValue: 200000.00,
newValue: 0.00,
deltaAmount: -200000.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 890,
entityKey: "CHQ-CLR-890",
fieldName: "State",
oldValue: "PENDING",
newValue: "CLEARED",
deltaAmount: 0
},
// Settlement Account
{
entityType: "SettlementAccount",
entityId: 50,
entityKey: "NIBSS-SETTLE-001",
fieldName: "PendingCredits",
oldValue: 500000.00,
newValue: 300000.00,
deltaAmount: -200000.00
},
{
entityType: "SettlementAccount",
entityId: 50,
entityKey: "NIBSS-SETTLE-001",
fieldName: "Balance",
oldValue: 1000000.00,
newValue: 1200000.00,
deltaAmount: +200000.00
},
// GL Accounts
{
entityType: "GLAccount",
entityKey: "1200-001", // Settlement Account
fieldName: "DebitAmount",
deltaAmount: +200000.00
},
{
entityType: "GLAccount",
entityKey: "2100-001", // Customer Deposits
fieldName: "CreditAmount",
deltaAmount: +200000.00
}
]
}
```text
### Scenario 3: Cheque Return (Dishonored)

**Cheque from Scenario 1 is returned - insufficient funds at issuer**

**RETURNED Phase** (Reversal + Fee):

```typescript
{
transactionId: "CHQ123456-RET",
originalTransactionId: "CHQ123456",
transactionState: "RETURNED",
impactedEntities: [
// Deposit Account (Reverse Credit)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "AvailableBalance",
oldValue: 150000.00,
newValue: 49500.00, // 50000 - 500 (return fee)
deltaAmount: -100500.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "BookBalance",
oldValue: 150000.00,
newValue: 49500.00,
deltaAmount: -100500.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "State",
oldValue: "CLEARING",
newValue: "RETURNED",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "ReturnReason",
oldValue: null,
newValue: "INSUFFICIENT_FUNDS",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 789,
entityKey: "CHQ-CLR-789",
fieldName: "ReturnDate",
oldValue: null,
newValue: "2025-12-29T14:00:00Z",
deltaAmount: 0
},
// GL Accounts (Reversal + Fee)
{
entityType: "GLAccount",
entityKey: "2100-001", // Customer Deposits
fieldName: "DebitAmount",
deltaAmount: +100000.00 // Reverse credit
},
{
entityType: "GLAccount",
entityKey: "1200-001", // Clearing Account
fieldName: "CreditAmount",
deltaAmount: +100000.00
},
{
entityType: "GLAccount",
entityKey: "2100-001", // Customer Deposits (Fee)
fieldName: "DebitAmount",
deltaAmount: +500.00
},
{
entityType: "GLAccount",
entityKey: "4100-006", // Cheque Return Fee Income
fieldName: "CreditAmount",
deltaAmount: +500.00
}
]
}
```text
### Scenario 4: Cheque Withdrawal

**Customer writes cheque for NGN 50,000**

**CLEARING Phase** (Hold Placement):

```typescript
{
transactionId: "CHQ345678",
transactionState: "CLEARING",
chequeClearingId: 991,
impactedEntities: [
// Deposit Account (Hold)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "AvailableBalance",
oldValue: 100000.00,
newValue: 50000.00,
deltaAmount: -50000.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "HoldAmount",
oldValue: 0.00,
newValue: 50000.00,
deltaAmount: +50000.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 991,
entityKey: "CHQ-CLR-991",
fieldName: "State",
oldValue: null,
newValue: "CLEARING",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 991,
entityKey: "CHQ-CLR-991",
fieldName: "ChequeType",
oldValue: null,
newValue: "WITHDRAWAL",
deltaAmount: 0
}
]
}
```text
**CLEARED Phase** (Debit Finalized):

```typescript
{
transactionId: "CHQ345678",
transactionState: "CLEARED",
impactedEntities: [
// Deposit Account (Release Hold, Debit BookBalance)
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "BookBalance",
oldValue: 100000.00,
newValue: 50000.00,
deltaAmount: -50000.00
},
{
entityType: "DepositAccount",
entityId: 100,
entityKey: "ACC-001",
fieldName: "HoldAmount",
oldValue: 50000.00,
newValue: 0.00,
deltaAmount: -50000.00
},
// Cheque Clearing Transaction
{
entityType: "ChequeClearingTransaction",
entityId: 991,
entityKey: "CHQ-CLR-991",
fieldName: "State",
oldValue: "CLEARING",
newValue: "CLEARED",
deltaAmount: 0
},
// GL Accounts
{
entityType: "GLAccount",
entityKey: "2100-001", // Customer Deposits
fieldName: "DebitAmount",
deltaAmount: +50000.00
},
{
entityType: "GLAccount",
entityKey: "1200-001", // Clearing Account
fieldName: "CreditAmount",
deltaAmount: +50000.00
}
]
}

V2 API Commands

BankLingo V2 provides BPMCore-compatible commands for cheque processing that integrate with the BPM workflow engine and provide robust transaction lifecycle management.

Architecture Overview

All V2 cheque commands follow the BPMCore Command Pattern:

  • BPM Integration: Commands accept parameters via BpmUtil.GetPropertyValue() for seamless BPMN integration
  • State Management: Transactions progress through defined states (PENDING → SETTLED/CANCELLED)
  • Impact Tracking: All balance and entity changes tracked via TransactionImpactTracker
  • Approval Workflows: Transactions can require approval before settlement
  • Reversal Support: Built-in support for bounce and cancellation scenarios

Implementation: CB.Administration.Api/Commands/BPMCore/Tellering/AdministrationCoreTelleringChequeCommandHandlers.cs


1. InitiateChequeDepositCommand

Purpose: Post a cheque deposit in PENDING state (awaiting clearing)

Command: InitiateChequeDepositCommand

Transaction State: PENDING (balance not yet credited)

BPM Parameters

{
"commandName": "InitiateChequeDepositCommand",
"data": {
"accountEncodedKey": "string (mandatory)",
"amount": "decimal (mandatory)",
"chequeNo": "string (mandatory)",
"tillId": "string (optional)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Parameter Details

ParameterTypeRequiredDescription
accountEncodedKeystring✅ YesTarget account for cheque deposit
amountdecimal✅ YesCheque amount (must be > 0)
chequeNostring✅ YesCheque number for tracking
tillIdstring❌ NoTeller till ID (if teller-initiated)
referenceIdstring❌ NoExternal reference/transaction ID
remarksstring❌ NoAdditional notes

Balance Impact (PENDING State)

IMPORTANT: Cheque deposits do NOT immediately credit account balance
Balance FieldChangeReason
AccountBalanceNO CHANGE ❌Awaits clearing
AvailableBalanceNO CHANGE ❌Awaits clearing
UnclearedChequeAmount+amount ✅Track uncleared deposit
TillBalance+amount ✅If tillId provided (teller cash in)

Transaction Lifecycle

States:

  1. PENDING: Cheque posted, awaiting clearing (NO balance credit)
  2. SETTLED: Cheque cleared (balance NOW credited via InitiateClearChequeCommand)
  3. CANCELLED: Cheque bounced/cancelled (NO balance change ever)

Example Request/Response

Request:

{
"commandName": "InitiateChequeDepositCommand",
"data": {
"accountEncodedKey": "8a8080827f23abcd017f23def456",
"amount": 50000.00,
"chequeNo": "CHQ-2025-001234",
"tillId": "TILL-001",
"remarks": "Customer deposit - external bank cheque"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQ-DEP-20251229-0001",
"transactionState": "PENDING",
"message": "Cheque deposit posted successfully (awaiting clearing)",
"data": {
"accountEncodedKey": "8a8080827f23abcd017f23def456",
"amount": 50000.00,
"chequeNo": "CHQ-2025-001234",
"state": "PENDING",
"unclearedAmount": 50000.00,
"balanceImpact": {
"accountBalance": 0,
"unclearedChequeAmount": 50000.00,
"tillBalance": 50000.00
}
}
}

Clearing Process

To complete the deposit (credit balance), use:

  • ✅ Success: InitiateClearChequeCommand → Credits balance
  • ❌ Failure: InitiateBounceChequeCommand → No balance change

2. InitiateChequeWithdrawalCommand

Purpose: Post a cheque withdrawal (balance IMMEDIATELY deducted)

Command: InitiateChequeWithdrawalCommand

Transaction State: PENDING (balance already deducted)

⚠️ CRITICAL DIFFERENCE: Unlike deposits, withdrawals deduct balance IMMEDIATELY when posted

BPM Parameters

{
"commandName": "InitiateChequeWithdrawalCommand",
"data": {
"accountEncodedKey": "string (mandatory)",
"amount": "decimal (mandatory)",
"chequeNo": "string (mandatory)",
"tillId": "string (optional)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Balance Impact (IMMEDIATE - PENDING State)

⚠️ CRITICAL: Balance is IMMEDIATELY DEDUCTED when cheque withdrawal is posted
Balance FieldChangeReason
AccountBalance-amount ✅IMMEDIATE DEDUCTION
AvailableBalance-amount ✅IMMEDIATE DEDUCTION
UnclearedChequeAmount+amount ✅Track uncleared withdrawal
TillBalance-amount ✅If tillId provided (teller cash out)

Balance Check: Command validates sufficient balance BEFORE posting

Transaction Lifecycle

States:

  1. PENDING: Cheque posted, balance already deducted
  2. SETTLED: Cheque cleared (balance remains deducted)
  3. CANCELLED: Cheque bounced/cancelled (⚠️ balance RESTORED)

Reversal Logic (CRITICAL)

When a cheque withdrawal is bounced or cancelled:

// Balance restoration on bounce/cancel
AccountBalance += amount; // RESTORE deducted balance
AvailableBalance += amount; // RESTORE available balance
UnclearedChequeAmount -= amount; // Clear uncleared tracking
TillBalance += amount; // RESTORE till balance (if till used)

Impact Tracking: Reversal creates isReversal: true impact records

Example Request/Response

Request:

{
"commandName": "InitiateChequeWithdrawalCommand",
"data": {
"accountEncodedKey": "8a8080827f23abcd017f23def456",
"amount": 75000.00,
"chequeNo": "CHQ-2025-005678",
"tillId": "TILL-002",
"remarks": "Customer withdrawal - cheque payment"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQ-WTD-20251229-0002",
"transactionState": "PENDING",
"message": "Cheque withdrawal posted (balance deducted)",
"data": {
"accountEncodedKey": "8a8080827f23abcd017f23def456",
"amount": 75000.00,
"chequeNo": "CHQ-2025-005678",
"state": "PENDING",
"balanceImpact": {
"accountBalance": -75000.00,
"unclearedChequeAmount": 75000.00,
"tillBalance": -75000.00,
"newAccountBalance": 425000.00
}
}
}

3. InitiateClearChequeCommand

Purpose: Clear a PENDING cheque to SETTLED/CLEARED state

Command: InitiateClearChequeCommand

Transaction State: SETTLED (final state)

Use Cases:

  • ✅ Cheque deposit cleared → NOW credit balance
  • ✅ Cheque withdrawal cleared → Balance stays deducted (already done)

BPM Parameters

{
"commandName": "InitiateClearChequeCommand",
"data": {
"transactionId": "string (mandatory)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Parameter Details

ParameterTypeRequiredDescription
transactionIdstring✅ YesOriginal cheque transaction ID to clear
referenceIdstring❌ NoClearing house reference
remarksstring❌ NoClearing notes

Balance Impact (By Cheque Type)

For Cheque DEPOSIT (was PENDING):

Balance FieldChangeReason
AccountBalance+amount ✅NOW credited
AvailableBalance+amount ✅NOW available
UnclearedChequeAmount-amount ✅Clear tracking

For Cheque WITHDRAWAL (was PENDING):

Balance FieldChangeReason
AccountBalanceNO CHANGE ❌Already deducted
UnclearedChequeAmount-amount ✅Clear tracking

State Validation

  • ✅ Can only clear transactions in PENDING state
  • ❌ Cannot clear SETTLED or CANCELLED transactions
  • ✅ Command is idempotent (safe to retry)

Example Request/Response

Request:

{
"commandName": "InitiateClearChequeCommand",
"data": {
"transactionId": "TXN-CHQ-DEP-20251229-0001",
"referenceId": "CLR-NIBSS-2025-1234567",
"remarks": "Cleared via NIBSS after 3 days"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQ-CLR-20251229-0003",
"originalTransactionId": "TXN-CHQ-DEP-20251229-0001",
"transactionState": "SETTLED",
"message": "Cheque cleared successfully (balance credited)",
"data": {
"chequeNo": "CHQ-2025-001234",
"amount": 50000.00,
"state": "SETTLED",
"clearedDate": "2025-12-29T14:30:00Z",
"balanceImpact": {
"accountBalance": 50000.00,
"unclearedChequeAmount": -50000.00,
"newAccountBalance": 550000.00
}
}
}

4. InitiateBounceChequeCommand

Purpose: Bounce a PENDING cheque (cheque dishonored/returned)

Command: InitiateBounceChequeCommand

Transaction State: CANCELLED (final state)

Use Cases:

  • ❌ Cheque deposit bounced → No balance change (was never credited)
  • ❌ Cheque withdrawal bounced → ⚠️ RESTORE deducted balance

BPM Parameters

{
"commandName": "InitiateBounceChequeCommand",
"data": {
"transactionId": "string (mandatory)",
"bounceReason": "string (optional)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Parameter Details

ParameterTypeRequiredDescription
transactionIdstring✅ YesOriginal cheque transaction ID to bounce
bounceReasonstring❌ NoReason code (e.g., "INSUFFICIENT_FUNDS")
referenceIdstring❌ NoClearing house bounce reference
remarksstring❌ NoBounce notes

Balance Impact (By Cheque Type)

For Cheque DEPOSIT Bounce (was PENDING):

Balance FieldChangeReason
AccountBalanceNO CHANGE ❌Was never credited
UnclearedChequeAmount-amount ✅Clear tracking
TillBalance-amount ✅Reverse till credit (if till used)

For Cheque WITHDRAWAL Bounce (was PENDING) ⚠️ CRITICAL:

Balance FieldChangeReason
AccountBalance+amount ✅RESTORE (reversal)
AvailableBalance+amount ✅RESTORE (reversal)
UnclearedChequeAmount-amount ✅Clear tracking
TillBalance+amount ✅RESTORE till balance (if till used)

Impact Records: Created with isReversal: true flag

Bounce Reasons (Common)

Reason CodeDescription
INSUFFICIENT_FUNDSDrawer account has insufficient balance
ACCOUNT_CLOSEDDrawer account is closed
SIGNATURE_MISMATCHSignature doesn't match bank records
POST_DATEDCheque presented before date
STALE_DATEDCheque older than 6 months
PAYMENT_STOPPEDDrawer requested stop payment
REFER_TO_DRAWERIssuer bank requires drawer contact

Example Request/Response

Request (Bounce Withdrawal - Balance Restoration):

{
"commandName": "InitiateBounceChequeCommand",
"data": {
"transactionId": "TXN-CHQ-WTD-20251229-0002",
"bounceReason": "INSUFFICIENT_FUNDS",
"referenceId": "BOUNCE-NIBSS-2025-7654321",
"remarks": "Issuer bank returned - insufficient funds"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQ-BNC-20251229-0004",
"originalTransactionId": "TXN-CHQ-WTD-20251229-0002",
"transactionState": "CANCELLED",
"message": "Cheque bounced (balance restored)",
"data": {
"chequeNo": "CHQ-2025-005678",
"amount": 75000.00,
"state": "CANCELLED",
"bounceReason": "INSUFFICIENT_FUNDS",
"bouncedDate": "2025-12-29T16:45:00Z",
"balanceImpact": {
"accountBalance": 75000.00,
"unclearedChequeAmount": -75000.00,
"tillBalance": 75000.00,
"newAccountBalance": 500000.00,
"isReversal": true
}
}
}

5. InitiateCancelChequeCommand

Purpose: Cancel a PENDING cheque (user/system cancellation)

Command: InitiateCancelChequeCommand

Transaction State: CANCELLED (final state)

Use Cases:

  • ⚠️ Teller error correction (posted wrong cheque)
  • ⚠️ Customer requests cancellation before clearing
  • ⚠️ System timeout/expiry cancellation

⚠️ CRITICAL: Same balance restoration logic as bounce (for withdrawals)

BPM Parameters

{
"commandName": "InitiateCancelChequeCommand",
"data": {
"transactionId": "string (mandatory)",
"cancellationReason": "string (optional)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Balance Impact

Identical to InitiateBounceChequeCommand:

  • Deposit cancellation: No balance change (was never credited)
  • Withdrawal cancellation: RESTORE deducted balance + till balance

Difference: Bounce vs Cancel

AspectBounceCancel
InitiatorClearing house / issuer bankTeller / system / customer
ReasonCheque dishonored by issuerError correction / user request
TimingAfter clearing attemptBefore/during clearing
Balance Logic✅ Same (restoration for withdrawal)✅ Same (restoration for withdrawal)

Example Request/Response

Request:

{
"commandName": "InitiateCancelChequeCommand",
"data": {
"transactionId": "TXN-CHQ-WTD-20251229-0005",
"cancellationReason": "TELLER_ERROR",
"remarks": "Teller posted wrong cheque number - customer correction"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQ-CXL-20251229-0006",
"originalTransactionId": "TXN-CHQ-WTD-20251229-0005",
"transactionState": "CANCELLED",
"message": "Cheque cancelled (balance restored)",
"data": {
"chequeNo": "CHQ-2025-009999",
"amount": 25000.00,
"state": "CANCELLED",
"cancellationReason": "TELLER_ERROR",
"cancelledDate": "2025-12-29T17:15:00Z",
"balanceImpact": {
"accountBalance": 25000.00,
"unclearedChequeAmount": -25000.00,
"tillBalance": 25000.00,
"newAccountBalance": 475000.00,
"isReversal": true
}
}
}

V2 Command Summary Matrix

Command Purpose Quick Reference

CommandPurposeInitial StateFinal StateBalance Impact
InitiateChequeDepositCommandPost cheque depositN/APENDING❌ No credit (awaits clear)
InitiateChequeWithdrawalCommandPost cheque withdrawalN/APENDING✅ Immediate deduction
InitiateClearChequeCommandClear pending chequePENDINGSETTLED✅ Credit deposit / Keep withdrawal
InitiateBounceChequeCommandBounce dishonored chequePENDINGCANCELLED⚠️ Restore withdrawal balance
InitiateCancelChequeCommandCancel cheque (user/error)PENDINGCANCELLED⚠️ Restore withdrawal balance

Balance Restoration Matrix (Withdrawal Scenarios)

ScenarioAccountBalanceAvailableBalanceUnclearedAmountTillBalanceReversal Flag
Post Withdrawal-amount-amount+amount-amountfalse
Clear WithdrawalNO CHANGENO CHANGE-amountNO CHANGEfalse
Bounce Withdrawal+amount+amount-amount+amounttrue ✅
Cancel Withdrawal+amount+amount-amount+amounttrue ✅

Typical Workflows

Successful Deposit Workflow

1. InitiateChequeDepositCommand → PENDING (no balance credit)
2. Wait 3-5 days (clearing cycle)
3. InitiateClearChequeCommand → SETTLED (balance credited)

Successful Withdrawal Workflow

1. InitiateChequeWithdrawalCommand → PENDING (balance deducted)
2. Wait for clearing
3. InitiateClearChequeCommand → SETTLED (balance stays deducted)

Bounced Withdrawal Workflow (Balance Restoration)

1. InitiateChequeWithdrawalCommand → PENDING (balance deducted)
2. Wait for clearing
3. InitiateBounceChequeCommand → CANCELLED (⚠️ balance RESTORED)

Cancelled Deposit Workflow (Error Correction)

1. InitiateChequeDepositCommand → PENDING (no balance credit)
2. Teller discovers error
3. InitiateCancelChequeCommand → CANCELLED (no balance impact)

Developer Documentation

For comprehensive technical implementation details, see:

  • V2 Cheque Commands Complete Technical Documentation (see repository root: BankLingo.Documentation.Docusaurus/V2_CHEQUE_COMMANDS_COMPLETE.md)

Implementation File: CB.Administration.Api/Commands/BPMCore/Tellering/AdministrationCoreTelleringChequeCommandHandlers.cs

Key Features:

  • ✅ BPM parameter parsing with BpmUtil.GetPropertyValue()
  • ✅ Balance validation with concurrent safety (locking)
  • ✅ Impact tracking for all balance changes
  • ✅ State machine enforcement (PENDING → SETTLED/CANCELLED)
  • ✅ Reversal logic with isReversal flag
  • ✅ Till integration for teller transactions
  • ✅ Approval workflow support

Clearing Cycle

Typical Clearing Timeline

DayActivityState
Day 0Cheque deposited/presentedPENDING
Day 0Submitted to clearing housePENDING
Day 1Clearing house processes batchCLEARING
Day 2Issuer bank validatesCLEARING
Day 3Cleared or ReturnedCLEARED/RETURNED

Clearing Days by Cheque Type

Cheque TypeClearing DaysImmediate Credit?
Local (Same Bank)0-1 daysYes
Local (Same City)1-2 daysConfigurable
Inter-City2-3 daysNo
Inter-Bank3-5 daysNo
International7-14 daysNo

Cheque States

Code Removed

Implementation details removed for security.

Contact support for implementation guidance.

State Transitions

PENDING ──────┐
│
├──► CLEARING ──┬──► CLEARED
│ │
│ └──► RETURNED
│
└──► CANCELLED

(Time > 6 months)
│
â–¼
EXPIRED
```text
---

## Cheque Return Reasons

:::warning[Code Removed]
**Implementation details removed for security.**

Contact support for implementation guidance.
:::text
---

## Validation Rules

### Cheque Deposit Validation

| Rule | Check | Error Code | Message |
|------|-------|------------|---------|
| **Account Active** | Account.State is ACTIVE | 05 | Account not active |
| **Valid Amount** | Amount > 0 and Amount matches MICR | 12 | Invalid amount |
| **Valid Cheque Number** | ChequeNumber matches MICR | 12 | Invalid cheque number |
| **Valid Bank Code** | BankCode exists in bank directory | 14 | Invalid bank code |
| **Not Duplicate** | ChequeNumber not already deposited | 26 | Duplicate cheque |
| **Not Expired** | ChequeDate within 6 months | 27 | Stale cheque |
| **Not Post-Dated** | ChequeDate on or before Today | 28 | Post-dated cheque |
| **Image Captured** | Front and back images exist | 29 | Cheque image required |

### Cheque Withdrawal Validation

| Rule | Check | Error Code | Message |
|------|-------|------------|---------|
| **Account Active** | Account.State is ACTIVE | 05 | Account not active |
| **Valid Amount** | Amount > 0 | 12 | Invalid amount |
| **Sufficient Balance** | Amount not exceeds AvailableBalance | 51 | Insufficient funds |
| **Cheque Not Cleared** | ChequeNumber not already cleared | 26 | Cheque already processed |
| **Not Reported Lost** | ChequeNumber not in stolen list | 57 | Cheque reported lost/stolen |
| **Valid Signature** | Signature matches (if required) | 58 | Signature verification failed |

---

## Fee Configuration

### Fee Types

```yaml
chequeFees:
- feeType: DEPOSIT
local: true
amount: 100.00

- feeType: DEPOSIT
local: false
amount: 500.00

- feeType: RETURN
amount: 500.00
chargedTo: DEPOSITOR

- feeType: BOOK_REQUEST
perLeaf: 50.00
minimumCharge: 500.00

GL Posting

Journal Entries

Example 1: Local Cheque Deposit (Cleared)

AccountDescriptionDebitCredit
1200-001Clearing Account100,000.00-
2100-001Customer Deposits-100,000.00

Example 2: External Cheque Deposit (Cleared)

AccountDescriptionDebitCredit
1200-002NIBSS Settlement200,000.00-
2100-001Customer Deposits-200,000.00

Example 3: Cheque Return

AccountDescriptionDebitCredit
2100-001Customer Deposits100,000.00-
1200-001Clearing Account-100,000.00
2100-001Customer Deposits (Fee)500.00-
4100-006Cheque Return Fee Income-500.00

Example 4: Cheque Withdrawal (Cleared)

AccountDescriptionDebitCredit
2100-001Customer Deposits50,000.00-
1200-001Clearing Account-50,000.00

API Usage

Cheque Deposit Request

POST /api/v2/transactions/cheque/deposit
Content-Type: application/json
Authorization: Bearer {token}

{
"accountEncodedKey": "ACC-001",
"amount": 100000.00,
"chequeNumber": "123456",
"issuerBankCode": "044",
"issuerAccountNumber": "0987654321",
"chequeDate": "2025-12-25",
"frontImageBase64": "data:image/jpeg;base64,...",
"backImageBase64": "data:image/jpeg;base64,...",
"micrData": "c044a0987654321a123456c",
"channelType": "TELLER"
}
```text
### Response - Success (Immediate Credit)

```json
{
"success": true,
"transactionKey": "CHQ123456",
"chequeClearingId": 789,
"state": "CLEARING",
"accountNumber": "0123456789",
"amount": 100000.00,
"immediateCredit": true,
"newBalance": 150000.00,
"expectedClearingDate": "2025-12-29",
"clearingDays": 1,
"message": "Cheque deposited successfully. Funds available immediately."
}
```text
### Response - Success (No Immediate Credit)

```json
{
"success": true,
"transactionKey": "CHQ234567",
"chequeClearingId": 890,
"state": "PENDING",
"accountNumber": "0123456789",
"amount": 200000.00,
"immediateCredit": false,
"pendingCredits": 200000.00,
"expectedClearingDate": "2026-01-02",
"clearingDays": 3,
"message": "Cheque accepted. Funds will be available after clearing."
}
```text
### Cheque Status Query

```http
GET /api/v2/transactions/cheque/{chequeClearingId}/status
Authorization: Bearer {token}
```text
### Response - Cleared

```json
{
"chequeClearingId": 789,
"transactionKey": "CHQ123456",
"state": "CLEARED",
"amount": 100000.00,
"clearedDate": "2025-12-28T10:30:00Z",
"clearingDays": 1,
"accountNumber": "0123456789",
"accountBalance": 150000.00
}
```text
### Response - Returned

```json
{
"chequeClearingId": 789,
"transactionKey": "CHQ123456",
"state": "RETURNED",
"amount": 100000.00,
"returnDate": "2025-12-29T14:00:00Z",
"returnReason": "INSUFFICIENT_FUNDS",
"returnFee": 500.00,
"accountNumber": "0123456789",
"accountBalance": 49500.00,
"message": "Cheque returned unpaid. Reason: Insufficient funds at issuer."
}
```text
---

## Error Codes

| Code | Message | Cause | Resolution |
|------|---------|-------|------------|
| 00 | Success | Cheque accepted | None |
| 05 | Account inactive | Account not ACTIVE | Contact branch |
| 12 | Invalid cheque data | Amount/number mismatch, MICR error | Verify cheque details |
| 14 | Invalid bank code | Bank code not found | Verify issuer bank |
| 26 | Duplicate cheque | Cheque already deposited | Check transaction history |
| 27 | Stale cheque | Cheque > 6 months old | Request new cheque from issuer |
| 28 | Post-dated cheque | Cheque date in future | Wait until cheque date |
| 29 | Image required | Missing front/back image | Capture cheque images |
| 51 | Insufficient funds | Not enough balance (withdrawal) | Deposit funds |
| 57 | Cheque stopped/stolen | Stop payment or reported lost | Contact issuer |
| 58 | Signature mismatch | Signature doesn't match | Verify with account holder |
| 91 | System error | Database/network failure | Retry or contact support |

---

## Best Practices

### For Tellers

1. **Verify Cheque Quality**: Check for alterations, damages, clarity
2. **Capture Clear Images**: Ensure front and back images are legible
3. **Validate MICR**: Verify MICR line matches cheque details
4. **Check Date**: Ensure cheque is not stale or post-dated
5. **Set Expectations**: Inform customer about clearing timeline
6. **Document Issues**: Note any irregularities for audit

### For Developers

1. **Track Clearing States**: Use proper state machine (PENDING → CLEARING → CLEARED/RETURNED)
2. **Handle Returns**: Implement proper reversal logic for returned cheques
3. **Manage Images**: Store cheque images securely with retention policy
4. **Settlement Integration**: Integrate with clearing house APIs
5. **Concurrent Safety**: Use locks when placing holds for withdrawals
6. **Audit Trail**: Log all state transitions and clearing decisions

### For Operations

1. **Monitor Clearing Queue**: Review pending cheques daily
2. **Expedite Local Cheques**: Process same-bank cheques quickly
3. **Handle Returns Promptly**: Notify customers immediately on returns
4. **Review High-Value Cheques**: Flag cheques > threshold for verification
5. **Reconcile Daily**: Match clearing house reports with internal records
6. **Manage Exceptions**: Investigate stuck or expired cheques

---

## Implementation Checklist

### Database Requirements

- [ ] Create `ChequeClearingTransaction` table
- [ ] Add columns: State, ChequeType, ChequeNumber, IssuerBankCode, IssuerAccountNumber, ChequeDate, Amount
- [ ] Add columns: FrontImagePath, BackImagePath, MICRData
- [ ] Add columns: ImmediateCredit, ExpectedClearingDate, ClearedDate, ReturnDate, ReturnReason
- [ ] Add `PendingCredits` column to DepositAccount
- [ ] Create `TransactionImpactRecord` and `ImpactedEntity` tables
- [ ] Add index on `ChequeClearingTransaction(ChequeNumber, IssuerBankCode)`
- [ ] Add index on `ChequeClearingTransaction(State, ExpectedClearingDate)`

### Code Requirements

- [ ] Implement `ProcessChequeDepositAsync` with immediate credit logic
- [ ] Implement `ProcessChequeWithdrawalAsync` with hold placement
- [ ] Add clearing cycle management (batch submission)
- [ ] Implement cheque return handler with reversal
- [ ] Add MICR data extraction and validation
- [ ] Implement image capture and storage
- [ ] Add settlement account integration
- [ ] Create background job for clearing status updates
- [ ] Implement cheque status query API

### Testing Requirements

- [ ] Unit test: Local cheque with immediate credit
- [ ] Unit test: External cheque with deferred credit
- [ ] Unit test: Cheque return with reversal
- [ ] Integration test: Full clearing cycle (deposit → clearing → cleared)
- [ ] Integration test: Cheque withdrawal with hold
- [ ] Integration test: Duplicate cheque detection
- [ ] Performance test: Batch processing 1000 cheques
- [ ] UI test: Teller cheque deposit workflow

### Documentation Requirements

- [ ] Update API documentation with cheque endpoints
- [ ] Create teller guide on cheque validation
- [ ] Document clearing timelines by cheque type
- [ ] Create customer FAQ on cheque clearing
- [ ] Document return reasons and actions

---

**Navigation**:
- [← Back to Transfer Transaction](./transfer.md)
- [↑ Back to Transaction Processing](./index.md)