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
| Parameter | Type | Required | Description |
|---|---|---|---|
accountEncodedKey | string | ✅ Yes | Target account for cheque deposit |
amount | decimal | ✅ Yes | Cheque amount (must be > 0) |
chequeNo | string | ✅ Yes | Cheque number for tracking |
tillId | string | ⌠No | Teller till ID (if teller-initiated) |
referenceId | string | ⌠No | External reference/transaction ID |
remarks | string | ⌠No | Additional notes |
Balance Impact (PENDING State)
IMPORTANT: Cheque deposits do NOT immediately credit account balance
| Balance Field | Change | Reason |
|---|---|---|
AccountBalance | NO CHANGE ⌠| Awaits clearing |
AvailableBalance | NO CHANGE ⌠| Awaits clearing |
UnclearedChequeAmount | +amount ✅ | Track uncleared deposit |
TillBalance | +amount ✅ | If tillId provided (teller cash in) |
Transaction Lifecycle
States:
- PENDING: Cheque posted, awaiting clearing (NO balance credit)
- SETTLED: Cheque cleared (balance NOW credited via
InitiateClearChequeCommand) - 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 Field | Change | Reason |
|---|---|---|
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:
- PENDING: Cheque posted, balance already deducted
- SETTLED: Cheque cleared (balance remains deducted)
- 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
| Parameter | Type | Required | Description |
|---|---|---|---|
transactionId | string | ✅ Yes | Original cheque transaction ID to clear |
referenceId | string | ⌠No | Clearing house reference |
remarks | string | ⌠No | Clearing notes |
Balance Impact (By Cheque Type)
For Cheque DEPOSIT (was PENDING):
| Balance Field | Change | Reason |
|---|---|---|
AccountBalance | +amount ✅ | NOW credited |
AvailableBalance | +amount ✅ | NOW available |
UnclearedChequeAmount | -amount ✅ | Clear tracking |
For Cheque WITHDRAWAL (was PENDING):
| Balance Field | Change | Reason |
|---|---|---|
AccountBalance | NO 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
| Parameter | Type | Required | Description |
|---|---|---|---|
transactionId | string | ✅ Yes | Original cheque transaction ID to bounce |
bounceReason | string | ⌠No | Reason code (e.g., "INSUFFICIENT_FUNDS") |
referenceId | string | ⌠No | Clearing house bounce reference |
remarks | string | ⌠No | Bounce notes |
Balance Impact (By Cheque Type)
For Cheque DEPOSIT Bounce (was PENDING):
| Balance Field | Change | Reason |
|---|---|---|
AccountBalance | NO CHANGE ⌠| Was never credited |
UnclearedChequeAmount | -amount ✅ | Clear tracking |
TillBalance | -amount ✅ | Reverse till credit (if till used) |
For Cheque WITHDRAWAL Bounce (was PENDING) âš ï¸ CRITICAL:
| Balance Field | Change | Reason |
|---|---|---|
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 Code | Description |
|---|---|
INSUFFICIENT_FUNDS | Drawer account has insufficient balance |
ACCOUNT_CLOSED | Drawer account is closed |
SIGNATURE_MISMATCH | Signature doesn't match bank records |
POST_DATED | Cheque presented before date |
STALE_DATED | Cheque older than 6 months |
PAYMENT_STOPPED | Drawer requested stop payment |
REFER_TO_DRAWER | Issuer 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
| Aspect | Bounce | Cancel |
|---|---|---|
| Initiator | Clearing house / issuer bank | Teller / system / customer |
| Reason | Cheque dishonored by issuer | Error correction / user request |
| Timing | After clearing attempt | Before/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
| Command | Purpose | Initial State | Final State | Balance Impact |
|---|---|---|---|---|
InitiateChequeDepositCommand | Post cheque deposit | N/A | PENDING | ⌠No credit (awaits clear) |
InitiateChequeWithdrawalCommand | Post cheque withdrawal | N/A | PENDING | ✅ Immediate deduction |
InitiateClearChequeCommand | Clear pending cheque | PENDING | SETTLED | ✅ Credit deposit / Keep withdrawal |
InitiateBounceChequeCommand | Bounce dishonored cheque | PENDING | CANCELLED | âš ï¸ Restore withdrawal balance |
InitiateCancelChequeCommand | Cancel cheque (user/error) | PENDING | CANCELLED | âš ï¸ Restore withdrawal balance |
Balance Restoration Matrix (Withdrawal Scenarios)
| Scenario | AccountBalance | AvailableBalance | UnclearedAmount | TillBalance | Reversal Flag |
|---|---|---|---|---|---|
| Post Withdrawal | -amount | -amount | +amount | -amount | false |
| Clear Withdrawal | NO CHANGE | NO CHANGE | -amount | NO CHANGE | false |
| Bounce Withdrawal | +amount | +amount | -amount | +amount | true ✅ |
| Cancel Withdrawal | +amount | +amount | -amount | +amount | true ✅ |
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
isReversalflag - ✅ Till integration for teller transactions
- ✅ Approval workflow support
Clearing Cycle
Typical Clearing Timeline
| Day | Activity | State |
|---|---|---|
| Day 0 | Cheque deposited/presented | PENDING |
| Day 0 | Submitted to clearing house | PENDING |
| Day 1 | Clearing house processes batch | CLEARING |
| Day 2 | Issuer bank validates | CLEARING |
| Day 3 | Cleared or Returned | CLEARED/RETURNED |
Clearing Days by Cheque Type
| Cheque Type | Clearing Days | Immediate Credit? |
|---|---|---|
| Local (Same Bank) | 0-1 days | Yes |
| Local (Same City) | 1-2 days | Configurable |
| Inter-City | 2-3 days | No |
| Inter-Bank | 3-5 days | No |
| International | 7-14 days | No |
Cheque States
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)
| Account | Description | Debit | Credit |
|---|---|---|---|
| 1200-001 | Clearing Account | 100,000.00 | - |
| 2100-001 | Customer Deposits | - | 100,000.00 |
Example 2: External Cheque Deposit (Cleared)
| Account | Description | Debit | Credit |
|---|---|---|---|
| 1200-002 | NIBSS Settlement | 200,000.00 | - |
| 2100-001 | Customer Deposits | - | 200,000.00 |
Example 3: Cheque Return
| Account | Description | Debit | Credit |
|---|---|---|---|
| 2100-001 | Customer Deposits | 100,000.00 | - |
| 1200-001 | Clearing Account | - | 100,000.00 |
| 2100-001 | Customer Deposits (Fee) | 500.00 | - |
| 4100-006 | Cheque Return Fee Income | - | 500.00 |
Example 4: Cheque Withdrawal (Cleared)
| Account | Description | Debit | Credit |
|---|---|---|---|
| 2100-001 | Customer Deposits | 50,000.00 | - |
| 1200-001 | Clearing 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)