Deposit Transaction
Credit funds to a deposit account through various channels (teller, mobile, ATM, transfer).
Overview
Purpose: Process deposits that increase the account balance
Transaction Code: DEP / TELLER_DEP
Typical Use Cases:
- Cash deposit at teller
- Mobile/online banking deposit
- ATM deposit
- Third-party deposit
- Transfer deposit from another account/bank
- Payroll/bulk deposits
Transaction Flow
State Diagram
Entities Impacted
Scenario 1: Cash Deposit via Teller
Transaction: 5,000 cash deposit to account
TransactionImpactRecord {
transactionId: 12345,
transactionType: "Deposit",
transactionState: COMPLETED,
impactedEntities: [
// 1. DEPOSIT ACCOUNT - AvailableBalance
{
entityType: "DepositAccount",
entityId: 789,
entityKey: "ACC-2025-00789",
fieldName: "AvailableBalance",
oldValue: 10000,
newValue: 15000,
deltaAmount: +5000 // Customer can use immediately
},
// 2. DEPOSIT ACCOUNT - BookBalance
{
entityType: "DepositAccount",
entityId: 789,
fieldName: "BookBalance",
oldValue: 10000,
newValue: 15000,
deltaAmount: +5000 // Ledger balance updated
},
// 3. TELLER TILL - CashBalance
{
entityType: "TellerTill",
entityId: 45,
entityKey: "TILL-001-BRANCH-1",
fieldName: "CashBalance",
oldValue: 50000,
newValue: 55000,
deltaAmount: +5000 // Cash received into till
},
// 4. TELLER TILL - TransactionCount
{
entityType: "TellerTill",
entityId: 45,
fieldName: "TransactionCount",
oldValue: 23,
newValue: 24,
deltaAmount: +1
},
// 5. GL ACCOUNT - Cash
{
entityType: "GLAccount",
entityKey: "1010-CASH-IN-TILL",
fieldName: "DebitAmount",
deltaAmount: +5000 // DR: Increase asset
},
// 6. GL ACCOUNT - Customer Deposits
{
entityType: "GLAccount",
entityKey: "2100-CUSTOMER-DEPOSITS",
fieldName: "CreditAmount",
deltaAmount: +5000 // CR: Increase liability
}
]
}
```text
**Balance Changes**:
```text
Customer Account:
Before: AvailableBalance = 10,000, BookBalance = 10,000
After: AvailableBalance = 15,000, BookBalance = 15,000
Teller Till:
Before: CashBalance = 50,000
After: CashBalance = 55,000
```text
### Scenario 2: Transfer Deposit (from another bank)
**Transaction**: 20,000 transferred from external bank
```typescript
TransactionImpactRecord {
transactionId: 12346,
transactionType: "Deposit",
transactionState: COMPLETED,
impactedEntities: [
// DEPOSIT ACCOUNT impacts (same as above)
// SETTLEMENT ACCOUNT - Balance
{
entityType: "SettlementAccount",
entityId: 3,
entityKey: "SETTLEMENT-CENTRAL-BANK",
fieldName: "Balance",
oldValue: 1000000,
newValue: 1020000,
deltaAmount: +20000 // Funds received via settlement
},
// SETTLEMENT ACCOUNT - PendingCredits
{
entityType: "SettlementAccount",
entityId: 3,
fieldName: "PendingCredits",
oldValue: 20000,
newValue: 0,
deltaAmount: -20000 // Clear pending credit
},
// GL ENTRIES
{
entityType: "GLAccount",
entityKey: "1150-SETTLEMENT-ACCOUNT",
fieldName: "DebitAmount",
deltaAmount: +20000 // DR: Increase settlement asset
},
{
entityType: "GLAccount",
entityKey: "2100-CUSTOMER-DEPOSITS",
fieldName: "CreditAmount",
deltaAmount: +20000 // CR: Increase liability
}
]
}
```text
---
## Approval Workflow
### Auto-Approval Conditions
Deposit is auto-approved if **ALL** conditions met:
- Amount ≤ Auto-approval limit (from product config)
- Account is ACTIVE
- No fraud flags on account
- Channel has sufficient limit
### Manual Approval Required
If any condition fails:
1. Transaction state: PENDING
2. Notification sent to approvers
3. Amount may be placed on hold (optional)
4. Awaits approval decision
### Approval Actions
**On Approval**:
- Execute deposit (update balances)
- Post GL entries
- Change state to COMPLETED
- Send confirmation notification
**On Rejection**:
- Change state to REJECTED
- Release any holds
- Send rejection notification
- Audit trail created
---
## Account Activation
If deposit is made to an **APPROVED** (not yet ACTIVE) account:
**Before Deposit**:
```text
Account State: APPROVED
AvailableBalance: 0
BookBalance: 0
```text
**After Deposit**:
```text
Account State: ACTIVE ← Automatically activated
AvailableBalance: 5,000
BookBalance: 5,000
ActivationDate: 2025-12-28 10:30:00
```text
This is the **first transaction** that activates the account.
---
## Limits & Validation
### Pre-Transaction Checks
| Validation | Rule | Error If Failed |
|------------|------|-----------------|
| **Account State** | Must be ACTIVE or APPROVED | "Account is locked/dormant" |
| **Amount** | Must be > 0 | "Invalid amount" |
| **Single Transaction Limit** | Amount ≤ Tier limit | "Transaction limit exceeded" |
| **Maximum Balance** | Current + Amount ≤ Max balance | "Maximum balance exceeded" |
| **Daily Count** | Transactions today < Max count | "Daily transaction limit reached" |
| **Channel Limit** | Amount ≤ Channel limit | "Channel limit exceeded" |
### Limit Examples
```yaml
product_config:
tiers:
default:
depositTransactionLimit: 1000000 # Single transaction
maximumBalance: 50000000 # Account maximum
maxTransactionCountPerDay: 50 # Daily count
Scenario:
- Account balance: 45,000,000
- Deposit amount: 6,000,000
- Maximum balance: 50,000,000
Result: ❌ REJECTED
Reason: "Maximum balance allowed is 50,000,000.
Current: 45,000,000 + Deposit: 6,000,000 = 51,000,000"
```text
---
## Fee Calculation
Deposits may incur fees based on product configuration:
### Fee Configuration
```yaml
fees:
depositFees:
- name: "Cash Deposit Fee"
trigger: OnDeposit
calculationType: Percentage
percentage: 0.1
minimumAmount: 50
maximumAmount: 500
applicableChannels: ["TELLER", "BRANCH"]
Fee Calculation Example
Deposit: 100,000 via teller
Fee: 0.1% = 100 (but minimum is 50, maximum is 500)
Result: Fee = 100
Fee Deduction: Option 1: Deduct from deposit amount
Deposit Amount: 100,000
Fee: -100
Net Credit: 99,900
```text
Option 2: Separate fee transaction
```text
Deposit: +100,000 (full amount credited)
Fee: -100 (separate debit)
Net: 99,900
```text
---
## GL Posting
### Journal Entries - Cash Deposit
```text
Transaction: 5,000 cash deposit via teller
Entry:
Date: 2025-12-28
Reference: TXN-DEP-2025-001
DR: 1010 - Cash in Till 5,000.00
CR: 2100 - Customer Deposits 5,000.00
───────────────────────── ─────────
Total: 5,000.00
```text
### Journal Entries - Transfer Deposit
```text
Transaction: 20,000 transfer from external bank
Entry:
Date: 2025-12-28
Reference: TXN-DEP-2025-002
DR: 1150 - Settlement Account 20,000.00
CR: 2100 - Customer Deposits 20,000.00
───────────────────────── ─────────
Total: 20,000.00
```text
### With Fees
```text
Transaction: 100,000 deposit with 100 fee
Entry:
Date: 2025-12-28
Reference: TXN-DEP-2025-003
DR: 1010 - Cash in Till 100,000.00
CR: 2100 - Customer Deposits 99,900.00
CR: 4100 - Fee Income 100.00
───────────────────────── ──────────
Total: 100,000.00
```text
---
## API Usage
### Request
```http
POST /api/bpm/cmd
Content-Type: application/json
Authorization: Bearer {access_token}
```text
```json
{
"commandName": "InitiateDepositCommand",
"data": {
"accountEncodedKey": "ACC-2025-00789",
"channelCode": "TELLER",
"amount": 5000.00,
"transactionType": 0,
"notes": "Cash deposit from customer",
"serviceId": null,
"serviceDescription": null,
"isBackDated": false,
"backDateValueDate": null,
"isBookingDate": false,
"bookingDate": null,
"entryDate": "2025-12-28T10:30:00Z"
}
}
```text
### Response - Success
```json
{
"isSuccessful": true,
"statusCode": "00",
"message": "Deposit transaction completed successfully.",
"data": {
"transactionKey": "TXN-DEP-2025-001",
"accountNumber": "1234567890",
"accountOfficerEncodedKey": "AO-001",
"branchEncodedKey": "BRANCH-001",
"clientEncodedKey": "CLIENT-789",
"depositEncodedKey": "ACC-2025-00789",
"transactionState": "COMPLETED",
"newBalance": 15000.00
}
}
```text
### Response - Pending Approval
```json
{
"isSuccessful": true,
"statusCode": "00",
"message": "Deposit transaction pending approval.",
"data": {
"transactionKey": "TXN-DEP-2025-002",
"accountNumber": "1234567890",
"transactionState": "PENDING",
"requiresApproval": true,
"approvalReason": "Amount exceeds auto-approval limit"
}
}
```text
### Response - Error (Limit Exceeded)
```json
{
"isSuccessful": false,
"statusCode": "51",
"message": "The maximum balance allowed on the account is 50,000,000.00 NGN.",
"data": null
}
```text
---
## Narration Templates
Deposits use configurable narration templates:
### Customer Narration
Template:
```text
`Deposit of ${context.amount} via ${context.channelName}`
```text
Result:
```text
"Deposit of 5,000.00 via Teller"
```text
### Channel Narration
Template:
```text
`Deposit to ${context.accountNumber}`
```text
Result:
```text
"Deposit to 1234567890"
```text
### Configuring Templates
```yaml
narrationTemplates:
deposit:
customer: "`Deposit of ${context.amount} to ${context.accountNumber} via ${context.channelName}`"
channel: "`Cash deposit from customer ${context.clientName} to account ${context.accountNumber}`"
```text
---
## Error Codes
| Code | Message | Cause | Resolution |
|------|---------|-------|------------|
| `00` | Success | Transaction completed | N/A |
| `05` | Account locked | Account in LOCKED/DORMANT state | Unlock account first |
| `12` | Invalid amount | Amount ≤ 0 or invalid | Check amount |
| `14` | Invalid account | Account not found | Verify account key |
| `51` | Limit exceeded | Transaction or balance limit | Increase limit or split transaction |
| `57` | Account restricted | Account on PND or frozen | Remove restriction |
| `91` | System error | Database/system issue | Retry or contact support |
---
## Backdating & Booking Dates
Deposits support special date handling:
### Backdated Transaction
**Use Case**: Post transaction with past value date
```json
{
"isBackDated": true,
"backDateValueDate": "2025-12-26T00:00:00Z",
"entryDate": "2025-12-28T10:30:00Z"
}
```text
**Result**:
```text
EntryDate: 2025-12-28 (when entered)
ValueDate: 2025-12-26 (effective date)
BookDate: 2025-12-26 (posting date)
```text
### Custom Booking Date
**Use Case**: Post to specific GL period
```json
{
"isBookingDate": true,
"bookingDate": "2025-12-31T00:00:00Z"
}
```text
**Result**:
```text
EntryDate: 2025-12-28
ValueDate: 2025-12-28
BookDate: 2025-12-31 (custom GL date)
```text
---
## Concurrent Transaction Safety
Multiple deposits to same account are safe:
### Scenario
```text
Time 10:00 - Balance: 10,000
Time 10:01 - Deposit A: 5,000 (Teller 1)
├─ Read: Balance = 10,000
├─ Update: Balance = 15,000
└─ Version: 1 → 2
Time 10:01 - Deposit B: 3,000 (Teller 2)
├─ Read: Balance = 10,000 (old)
├─ Update: Balance = 13,000
└─ Version: 1 → 2 ❌ CONFLICT!
System detects version mismatch
├─ Retry Deposit B
├─ Read: Balance = 15,000 (current)
├─ Update: Balance = 18,000
└─ Version: 2 → 3 ✓
Final Balance: 18,000 ✓
```text
**Optimistic Locking** prevents lost updates!
---
## Best Practices
### For Tellers
1. Count cash carefully before processing
2. Verify customer identity
3. Confirm account number verbally
4. Print receipt for customer
5. Balance till at end of shift
### For Developers
1. Always validate account state
2. Check limits before execution
3. Use TransactionImpactRecord
4. Track all entity changes
5. Test concurrent scenarios
6. Handle all error codes
### For Operations
1. Monitor large deposits (AML)
2. Review pending approvals daily
3. Investigate failed transactions
4. Reconcile tills daily
5. Audit deposit patterns
---
## Related Operations
- **[Withdrawal](./withdrawal)**: Opposite operation (debit)
- **[Transfer](./transfer)**: Move between accounts
- **Reversal**: Undo completed deposit
- **Account Activation**: First deposit activates
---
## V2 API Commands
BankLingo V2 provides the **InitiateDepositCommand** for BPMCore integration.
### Command Overview
- **Command**: `InitiateDepositCommand`
- **Implementation**: `CB.Administration.Api/Commands/BPMCore/DepositWithdrawal/AdministrationCoreDepositTransactionCommandHandlers.cs`
- **Purpose**: Initiate deposit transactions with full approval workflow and impact tracking
- **BPM Integration**: Accepts parameters via `BpmUtil.GetPropertyValue()`
- **State Management**: PENDING → APPROVED → SETTLED
### Key Features
**Approval Workflow Integration**:
- Deposits requiring approval remain in PENDING state with available balance impact
- TransactionImpactTracker records all entity changes
- Approval/rejection handled via separate workflow commands
**Impact Tracking**:
- All account balance changes tracked via `TransactionImpactRecord`
- Delta-based tracking enables accurate concurrent transaction handling
- Impact records include: AccountId, EntityType, FieldName, OldValue, NewValue
**Concurrent Safety**:
- Optimistic locking with version checking
- Delta-based balance updates (not absolute values)
- Prevents lost updates in high-volume scenarios
**Till Integration** (Teller Context):
- When `tillId` provided, till balance automatically updated
- Cash deposits increase till balance
- Cheque deposits tracked as uncleared items
For detailed teller deposit workflows, see [Teller Deposit Transaction](../../teller-transactions/product/teller-deposit-technical-flow).
---
## Implementation Checklist
### Database
- [ ] TransactionImpactRecord table exists
- [ ] ImpactedEntity table exists
- [ ] CBSTransaction table includes State column
- [ ] DepositAccount includes Version column
### Code
- [ ] Impact tracking implemented
- [ ] Approval workflow implemented
- [ ] Fee calculation integrated
- [ ] GL posting automatic
- [ ] Narration templates used
- [ ] Limit validation complete
- [ ] Error handling comprehensive
### Testing
- [ ] Unit tests for validation
- [ ] Integration tests for full flow
- [ ] Concurrent deposit tests
- [ ] Approval workflow tests
- [ ] Limit breach tests
- [ ] Fee calculation tests
### Documentation
- [ ] Product config documented
- [ ] API endpoints documented
- [ ] Error codes listed
- [ ] Operator procedures created
---
## Developer Resources
For API implementation details, see:
- [Initiate Deposit API - Developer Guide](../../developer/initiate-deposit)
- [Deposit Transactions API Reference](../../developer/)
---
**Last Updated**: December 28, 2025
**Version**: 2.0
**Status**: Production Ready
**Next**: [Withdrawal Transaction →](./withdrawal)