Skip to main content

Initiate Withdrawal

Overview

The Initiate Withdrawal API allows financial institutions to process withdrawal transactions from customer deposit accounts. This operation debits the account balance, validates withdrawal limits, enforces overdraft rules, and handles all necessary accounting entries through configurable channels (such as teller transactions, ATMs, or online banking).

Command Details

Command Name: InitiateWithdrawalCommand

Operation Type: Command (Write Operation)

Transaction Type: Withdrawal

Use Cases

  • Cash Withdrawals: Process over-the-counter cash withdrawals at bank branches
  • ATM Withdrawals: Handle automated teller machine withdrawal transactions
  • Online/Mobile Banking Withdrawals: Process customer-initiated withdrawals through digital channels
  • Teller Withdrawals: Support assisted withdrawals at teller counters
  • Check Withdrawals: Process check issuance and payment transactions
  • Emergency Withdrawals: Handle urgent withdrawal requests with proper authorization

API Endpoint

POST /api/bpm/cmd
Content-Type: application/json
Authorization: Bearer {access_token}

Request Structure

Request Body

{
"commandName": "InitiateWithdrawalCommand",
"data": {
"accountEncodedKey": "string",
"channelCode": "string",
"amount": 0.00,
"transactionType": 2,
"notes": "string",
"serviceId": "string",
"serviceDescription": "string",
"isBackDated": false,
"backDateValueDate": "2025-12-17T10:30:00Z",
"isBookingDate": false,
"bookingDate": "2025-12-17T10:30:00Z",
"entryDate": "2025-12-17T10:30:00Z"
}
}

Request Fields

Field NameTypeMandatoryDescriptionAdditional Information
accountEncodedKeyStringYesUnique identifier or account number of the deposit accountCan be either encodedKey or account number
channelCodeStringYesCode identifying the transaction channelMust be a valid channel code (e.g., TELLER, ATM, MOBILE, ONLINE)
amountDecimalYesWithdrawal amountMust be positive number with up to 2 decimal places
transactionTypeIntegerYesType of core transactionDefault: 2 (Withdrawal). Enum: CoreTransactionType
notesStringNoTransaction notes or remarksFree text field for additional information
serviceIdStringNoService identifier for the transactionUsed for tracking specific services
serviceDescriptionStringNoDescription of the serviceHuman-readable service description
isBackDatedBooleanNoWhether transaction is backdatedDefault: false. Requires backDateValueDate if true
backDateValueDateDateTimeConditionalValue date for backdated transactionRequired if isBackDated is true. ISO 8601 format
isBookingDateBooleanNoWhether to use specific booking dateDefault: false. Requires bookingDate if true
bookingDateDateTimeConditionalSpecific booking date for transactionRequired if isBookingDate is true. ISO 8601 format
entryDateDateTimeNoTransaction entry dateISO 8601 format. Defaults to current date/time

Sample Requests

1. Standard ATM Cash Withdrawal

{
"commandName": "InitiateWithdrawalCommand",
"data": {
"accountEncodedKey": "8a8e87e87d1234567890abcd",
"channelCode": "ATM",
"amount": 5000.00,
"transactionType": 2,
"notes": "ATM withdrawal - Branch A ATM"
}
}

2. Teller-Assisted Withdrawal

{
"commandName": "InitiateWithdrawalCommand",
"data": {
"accountEncodedKey": "1234567890",
"channelCode": "TELLER",
"amount": 25000.00,
"transactionType": 2,
"notes": "Counter withdrawal - verified with ID",
"serviceId": "TELLER-WD-2025-001",
"serviceDescription": "Teller Withdrawal Service"
}
}

3. Backdated Withdrawal (Administrative Correction)

{
"commandName": "InitiateWithdrawalCommand",
"data": {
"accountEncodedKey": "8a8e87e87d1234567890abcd",
"channelCode": "BRANCH",
"amount": 10000.00,
"transactionType": 2,
"notes": "Correcting missed withdrawal from previous day",
"isBackDated": true,
"backDateValueDate": "2025-12-16T14:00:00Z"
}
}

4. Online Banking Withdrawal

{
"commandName": "InitiateWithdrawalCommand",
"data": {
"accountEncodedKey": "1234567890",
"channelCode": "ONLINE",
"amount": 15000.00,
"transactionType": 2,
"notes": "Online transfer to external account"
}
}

Response Structure

Success Response

{
"isSuccessful": true,
"statusCode": "00",
"message": "Deposit account has been added successfully.",
"data": {
"transactionKey": "2000345",
"accountNumber": "1234567890",
"accountOfficerEncodedKey": "8a8e87e87d0987654321",
"branchEncodedKey": "8a8e87e87d1111222233",
"clientEncodedKey": "8a8e87e87d4444555566",
"depositEncodedKey": "8a8e87e87d1234567890abcd"
}
}

Response Fields

Field NameTypeDescription
transactionKeyStringUnique transaction reference number
accountNumberStringAccount number from which withdrawal was made
accountOfficerEncodedKeyStringEncoded key of the account officer
branchEncodedKeyStringEncoded key of the branch
clientEncodedKeyStringEncoded key of the client/customer
depositEncodedKeyStringEncoded key of the deposit account

Error Responses

1. Invalid Account

{
"isSuccessful": false,
"statusCode": "CBS_404",
"message": "Invalid deposit account encoded key"
}

2. Insufficient Balance

{
"isSuccessful": false,
"statusCode": "CBS_400",
"message": "Insufficient balance"
}

3. Account Frozen

{
"isSuccessful": false,
"statusCode": "CBS_400",
"message": "You cannot perform any transaction on this account. It is presently frozen."
}

4. Withdrawal Limit Exceeded

{
"isSuccessful": false,
"statusCode": "CBS_425",
"message": "The maximum transaction withdrawal limit on the account tier is 50000.00 NGN."
}

5. Daily Limit Exceeded

{
"isSuccessful": false,
"statusCode": "CBS_425",
"message": "Exceeded the transaction limit for the day. The maximum amount allowed for withdrawal for the day is 100000.00 NGN."
}

6. Account Locked

{
"isSuccessful": false,
"statusCode": "CBS_400",
"message": "You cannot perform any transaction on this account. It is presently locked."
}

Business Logic

Transaction Processing Flow

  1. Account Validation

    • Verify account exists and is accessible
    • Check account status (not frozen, locked, or dormant)
    • Validate account type allows withdrawals
  2. Channel Validation

    • Validate channel code exists and is active
    • Verify channel is configured for withdrawal operations
    • Check channel has associated GL account
  3. Balance Validation

    • Check account has sufficient balance for withdrawal
    • Consider minimum balance requirements
    • Factor in available overdraft facilities if configured
    • Account for holds and locks on the account
  4. Limit Validation

    • Check against account tier single withdrawal transaction limit
    • Verify daily withdrawal limit not exceeded
    • Check monthly withdrawal limit not exceeded
    • Validate daily transaction count limit
    • Verify monthly transaction count limit
    • Check product-level maximum withdrawal amount
  5. Overdraft Handling

    • If account has overdraft facility, calculate allowable overdraft
    • Check overdraft expiry date
    • Adjust available balance with overdraft limit
    • Ensure minimum opening balance maintained
  6. Date Processing

    • Apply backdating if specified (requires backDateValueDate)
    • Set booking date if specified
    • Default to current date/time if no special dates
  7. Fee Calculation

    • Calculate applicable withdrawal fees based on product configuration
    • Apply fee trigger rules (OnWithdrawal)
    • Generate fee transactions if applicable
  8. Narration Generation

    • Execute customer narration template with transaction context
    • Execute channel narration template
    • Generate transaction ID from template
  9. Transaction Creation

    • Create CBS transaction record
    • Generate unique transaction key
    • Set transaction state (PENDING or SETTLED based on approval requirements)
  10. Account Updates

    • If pending approval: Decrease hold amount (lock debit), create amount lock transaction
    • If immediate settlement: Debit account balance, create deposit transaction
    • Update account state to Active if currently inactive
    • Create settlement transaction for channel
  11. PND (Post No Debit) Handling

    • If withdrawal limit exceeded and PND not already active, activate PND on account
    • Prevents further debits until PND is released
  12. Persistence

    • Save all transaction records
    • Update account balances
    • Commit changes to database

Special Handling

Overdraft Accounts:

  • Checks for active overdraft adjustment with valid expiry date
  • Calculates allowable overdraft based on overdraft limit
  • Ensures minimum opening balance is maintained even with overdraft

Pending Transactions:

  • Amount is locked (decreases holdAmount for debit lock)
  • Amount lock transaction created with DEBIT_LOCKED state
  • Account balance not updated until approval

Settled Transactions:

  • Account balance immediately debited
  • Deposit transaction created with new balance
  • Account state set to Active

PND Activation:

  • If withdrawal exceeds limit, PND (Post No Debit) is automatically activated
  • Prevents further debit transactions until manually released
  • Requires administrator intervention to release

Account Balance Impact

Immediate Settlement (No Approval Required)

Before Transaction:

  • Account Balance: 50,000.00
  • Available Balance: 50,000.00
  • Hold Amount: 0.00

Withdrawal: 15,000.00

After Transaction:

  • Account Balance: 35,000.00
  • Available Balance: 35,000.00
  • Hold Amount: 0.00

With Overdraft Facility

Before Transaction:

  • Account Balance: 5,000.00
  • Available Balance: 5,000.00
  • Overdraft Limit: 10,000.00
  • Minimum Opening Balance: 1,000.00

Withdrawal: 12,000.00

After Transaction:

  • Account Balance: -7,000.00
  • Available Balance: -7,000.00
  • Overdraft Used: 7,000.00 (within 10,000 limit)
  • Actual Balance after min. requirement: Still acceptable (5,000 - 12,000 + 10,000 overdraft - 1,000 min = valid)

Pending Approval

Before Transaction:

  • Account Balance: 50,000.00
  • Available Balance: 50,000.00
  • Hold Amount: 0.00

Withdrawal (Pending): 40,000.00

After Transaction:

  • Account Balance: 50,000.00 (unchanged)
  • Available Balance: 50,000.00
  • Hold Amount: -40,000.00 (locked for debit until approved)

Architecture Diagram

Security Considerations

  • Authentication: Requires valid bearer token
  • Authorization: User must have permission to process withdrawals on the account
  • Audit Trail: All withdrawals are logged with user information, timestamps, and IP addresses
  • Channel Security: Channel must be properly configured and validated
  • Amount Validation: Prevents negative amounts and enforces limits
  • Fraud Detection: Large withdrawals may trigger fraud alerts
  • PND Protection: Automatic PND activation prevents unauthorized debits after limit violations

Performance Considerations

  • Transaction Speed: Typically completes in 200-500ms
  • Database Impact: Creates 2-4 transaction records per withdrawal
  • Caching: Channel configuration is cached for improved performance
  • Concurrent Transactions: Uses database locking to prevent race conditions
  • Indexing: Account number and transaction key are indexed for fast lookups
  • Balance Calculations: Efficient queries for transaction breakdowns and limits

Troubleshooting

Issue: Insufficient Balance Error

Symptom: CBS_400 error with message "Insufficient balance"

Possible Causes:

  1. Account balance lower than withdrawal amount
  2. Minimum balance requirement not considered
  3. Hold amount reducing available balance
  4. Overdraft facility expired or not configured

Solution:

  1. Check actual account balance vs. withdrawal amount
  2. Verify minimum opening balance requirement from product configuration
  3. Check for pending transactions or holds reducing available balance
  4. If overdraft exists, verify it hasn't expired
  5. Consider splitting withdrawal into smaller amounts

Issue: Daily Limit Exceeded

Symptom: Error stating daily withdrawal limit exceeded

Possible Causes:

  1. Customer has reached daily withdrawal amount limit
  2. Daily transaction count limit reached
  3. Multiple withdrawals throughout the day accumulated
  4. Account tier has restrictive limits

Solution:

  1. Check transaction breakdown for today's withdrawal total
  2. Verify account tier daily withdrawal limit
  3. Inform customer of limit and current usage
  4. Process withdrawal the next business day
  5. Request tier upgrade if customer qualifies

Issue: PND Activated on Account

Symptom: Withdrawal succeeded but subsequent transactions fail with PND error

Possible Causes:

  1. Withdrawal exceeded configured limit, triggering automatic PND
  2. System automatically activated PND for protection
  3. No administrator approval for PND release

Solution:

  1. Verify withdrawal amount vs. configured limits
  2. Check account for active PND flag
  3. Use ReleasePNDFromDepositAccountCommand to remove PND
  4. Investigate why limit was exceeded
  5. Consider tier upgrade or limit adjustment

Issue: Overdraft Not Applied

Symptom: Withdrawal denied despite account having overdraft facility

Possible Causes:

  1. Overdraft adjustment has expired
  2. Withdrawal amount exceeds balance + overdraft limit
  3. Minimum balance still cannot be maintained even with overdraft
  4. Overdraft not properly configured

Solution:

  1. Check overdraft expiry date in DepositAccoundOverdraftAdjustment table
  2. Verify overdraft limit is sufficient for requested withdrawal
  3. Calculate: balance - withdrawal + overdraft - minimum balance
  4. Renew overdraft facility if expired
  5. Increase overdraft limit if customer qualifies

Issue: Channel Unavailable

Symptom: CBS_404 error for channel code

Possible Causes:

  1. Channel code doesn't exist in system
  2. Channel is inactive or disabled
  3. Channel not configured for withdrawal operations
  4. Channel GL account not set up

Solution:

  1. Verify channel code with LookUpTransactionChannelsQuery
  2. Check channel is active and withdrawal operation is enabled
  3. Ensure channel has associated GL account
  4. Contact system administrator for channel configuration
  5. Use alternative channel if available

Issue: Transaction Count Limit Reached

Symptom: Error stating maximum number of transactions reached

Possible Causes:

  1. Customer has made maximum allowed withdrawals for the day
  2. Monthly transaction count limit reached
  3. Account tier has very restrictive transaction limits
  4. Test transactions counted toward limit

Solution:

  1. Check transaction breakdown for count today/this month
  2. Verify account tier transaction count limits
  3. Explain limits to customer
  4. Process urgent withdrawals with supervisor override if authorized
  5. Recommend tier upgrade for customers with high transaction needs

Monitoring and Alerts

Key Metrics to Track

  • Total withdrawal volume (amount)
  • Withdrawal transaction count
  • Success rate percentage
  • Average transaction processing time
  • Failed withdrawal rate
  • Withdrawals by channel
  • Insufficient balance rejection rate
  • PND activation frequency
  • Failed withdrawals exceeding 5% threshold
  • Unusually large withdrawal amounts (potential fraud)
  • Multiple withdrawal attempts on single account
  • High number of insufficient balance errors
  • Withdrawal processing time exceeding 1 second
  • Channel unavailability
  • Frequent PND activations (may indicate limit configuration issues)

Audit and Compliance

Audit Log Entries

Every withdrawal transaction creates audit records including:

  • Transaction key and timestamp
  • User who initiated transaction
  • Account number and customer details
  • Amount and currency
  • Channel used
  • Before and after account balances
  • Notes and remarks
  • IP address and device information
  • Approval workflow (if applicable)
  • PND activation (if triggered)

Compliance Requirements

  • Anti-Money Laundering (AML): Large withdrawals may trigger AML checks
  • Transaction Limits: Must comply with regulatory withdrawal limits
  • Customer Verification: Identity verification required for large withdrawals
  • Reporting: Withdrawals may need to be reported to financial authorities
  • Record Retention: Transaction records retained per regulatory requirements (typically 7+ years)
  • Fraud Prevention: Multiple withdrawal attempts monitored for suspicious patterns

Code Examples

C# Example

using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class WithdrawalService
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl;
private readonly string _bearerToken;

public WithdrawalService(HttpClient httpClient, string baseUrl, string bearerToken)
{
_httpClient = httpClient;
_baseUrl = baseUrl;
_bearerToken = bearerToken;
}

public async Task<WithdrawalResponse> InitiateWithdrawalAsync(string accountEncodedKey,
string channelCode, decimal amount, string notes = null)
{
var request = new
{
commandName = "InitiateWithdrawalCommand",
data = new
{
accountEncodedKey,
channelCode,
amount,
transactionType = 2,
notes
}
};

var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");

_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _bearerToken);

var response = await _httpClient.PostAsync($"{_baseUrl}/api/bpm/cmd", content);
var responseJson = await response.Content.ReadAsStringAsync();

return JsonSerializer.Deserialize<WithdrawalResponse>(responseJson);
}
}

public class WithdrawalResponse
{
public bool IsSuccessful { get; set; }
public string StatusCode { get; set; }
public string Message { get; set; }
public WithdrawalData Data { get; set; }
}

public class WithdrawalData
{
public string TransactionKey { get; set; }
public string AccountNumber { get; set; }
public string AccountOfficerEncodedKey { get; set; }
public string BranchEncodedKey { get; set; }
public string ClientEncodedKey { get; set; }
public string DepositEncodedKey { get; set; }
}

// Usage
var withdrawalService = new WithdrawalService(httpClient, "https://api.banklingo.com", "your-token-here");
var result = await withdrawalService.InitiateWithdrawalAsync(
"8a8e87e87d1234567890abcd",
"ATM",
5000.00m,
"ATM withdrawal - Branch A"
);

if (result.IsSuccessful)
{
Console.WriteLine($"Withdrawal successful. Transaction Key: {result.Data.TransactionKey}");
}
else
{
Console.WriteLine($"Withdrawal failed: {result.Message}");
}

JavaScript/TypeScript Example

interface InitiateWithdrawalRequest {
commandName: string;
data: {
accountEncodedKey: string;
channelCode: string;
amount: number;
transactionType: number;
notes?: string;
serviceId?: string;
serviceDescription?: string;
isBackDated?: boolean;
backDateValueDate?: string;
};
}

interface WithdrawalResponse {
isSuccessful: boolean;
statusCode: string;
message: string;
data?: {
transactionKey: string;
accountNumber: string;
accountOfficerEncodedKey: string;
branchEncodedKey: string;
clientEncodedKey: string;
depositEncodedKey: string;
};
}

async function initiateWithdrawal(
accountEncodedKey: string,
channelCode: string,
amount: number,
notes?: string
): Promise<WithdrawalResponse> {
const request: InitiateWithdrawalRequest = {
commandName: 'InitiateWithdrawalCommand',
data: {
accountEncodedKey,
channelCode,
amount,
transactionType: 2,
notes,
},
};

const response = await fetch('https://api.banklingo.com/api/bpm/cmd', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_ACCESS_TOKEN}`,
},
body: JSON.stringify(request),
});

const result: WithdrawalResponse = await response.json();
return result;
}

// Usage
const result = await initiateWithdrawal(
'8a8e87e87d1234567890abcd',
'TELLER',
25000.00,
'Counter withdrawal - verified with ID'
);

if (result.isSuccessful) {
console.log(`Withdrawal successful! Transaction: ${result.data?.transactionKey}`);
} else {
console.error(`Withdrawal failed: ${result.message}`);
}

Python Example

import requests
import json
from typing import Optional, Dict, Any
from datetime import datetime

class WithdrawalService:
def __init__(self, base_url: str, access_token: str):
self.base_url = base_url
self.access_token = access_token
self.headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}'
}

def initiate_withdrawal(
self,
account_encoded_key: str,
channel_code: str,
amount: float,
notes: Optional[str] = None,
service_id: Optional[str] = None,
is_backdated: bool = False,
backdate_value_date: Optional[datetime] = None
) -> Dict[str, Any]:
"""
Initiate a withdrawal transaction from a deposit account.

Args:
account_encoded_key: Account identifier (encoded key or account number)
channel_code: Transaction channel code (e.g., 'ATM', 'TELLER')
amount: Withdrawal amount (must be positive)
notes: Optional transaction notes
service_id: Optional service identifier
is_backdated: Whether transaction is backdated
backdate_value_date: Value date for backdated transaction

Returns:
Dictionary containing response with transaction details
"""
payload = {
'commandName': 'InitiateWithdrawalCommand',
'data': {
'accountEncodedKey': account_encoded_key,
'channelCode': channel_code,
'amount': amount,
'transactionType': 2,
}
}

# Add optional fields
if notes:
payload['data']['notes'] = notes
if service_id:
payload['data']['serviceId'] = service_id
if is_backdated:
payload['data']['isBackDated'] = True
if backdate_value_date:
payload['data']['backDateValueDate'] = backdate_value_date.isoformat()

response = requests.post(
f'{self.base_url}/api/bpm/cmd',
json=payload,
headers=self.headers
)

return response.json()

# Usage
withdrawal_service = WithdrawalService(
base_url='https://api.banklingo.com',
access_token='your-access-token-here'
)

result = withdrawal_service.initiate_withdrawal(
account_encoded_key='8a8e87e87d1234567890abcd',
channel_code='ATM',
amount=5000.00,
notes='ATM withdrawal - Branch A ATM'
)

if result['isSuccessful']:
print(f"Withdrawal successful!")
print(f"Transaction Key: {result['data']['transactionKey']}")
print(f"Account Number: {result['data']['accountNumber']}")
else:
print(f"Withdrawal failed: {result['message']}")
print(f"Status Code: {result['statusCode']}")

Response Codes

CodeDescriptionResolution
00SuccessWithdrawal processed successfully
CBS_400Bad Request / Account Locked or FrozenCheck account status, ensure account is not frozen, locked, or dormant
CBS_404Account or Channel Not FoundVerify account encoded key and channel code
CBS_425Withdrawal Limit ExceededCheck account tier limits, wait for next period, or request tier upgrade
CBS_426Insufficient BalanceVerify account balance, check for holds, review overdraft facility
CBS_427Invalid AmountEnsure amount is positive and properly formatted
CBS_428Daily/Monthly Limit ExceededCheck transaction breakdown, inform customer of limits, process next period

Business Rules

Validation Rules

  1. Account Encoded Key - Must correspond to an existing, active deposit account; can be either the encoded key or account number
  2. Channel Code - Must be a valid, active transaction channel configured for withdrawal operations with associated GL account
  3. Amount - Must be a positive decimal value with up to 2 decimal places; zero or negative amounts are rejected
  4. Transaction Type - Must be valid CoreTransactionType enum value; defaults to 2 (Withdrawal)
  5. Backdated Transactions - If isBackDated is true, backDateValueDate must be provided and must be in the past
  6. Booking Date - If isBookingDate is true, bookingDate must be provided
  7. Account Status - Account must not be frozen (IsOnFreeze = false), locked, or dormant
  8. Balance Sufficiency - Account balance (plus any active overdraft) must be sufficient for withdrawal amount plus minimum opening balance requirement

Operational Rules

  1. Withdrawals debit account balance immediately for settled transactions, or create hold amount (debit lock) for pending transactions requiring approval
  2. Transaction limits are enforced based on account tier configuration (single transaction limit, daily amount limit, monthly amount limit, daily count limit, monthly count limit)
  3. Minimum opening balance must be maintained after withdrawal, even when overdraft facility is used
  4. Overdraft facilities are validated for active status (expiry date must be in the future) before being applied to available balance calculations
  5. If withdrawal exceeds configured limits and PND (Post No Debit) is not already active, system automatically activates PND to prevent further unauthorized debits
  6. Fees are calculated automatically based on product configuration and applied according to fee trigger rules (OnWithdrawal)
  7. Narrations are generated from configurable templates using transaction context (account, channel, amount, etc.)
  8. All withdrawal transactions create corresponding accounting entries: debit to customer account, credit to channel/GL account
  9. Pending transactions (requiring approval) create amount lock transactions with DEBIT_LOCKED state until approved or rejected
  10. Transaction keys are generated using configurable templates and sequence numbers to ensure uniqueness
  11. Date handling supports backdating (for corrections) and custom booking dates with proper validation
  12. All withdrawals are recorded in audit trail with complete transaction context including user, timestamp, IP address, and device information

Changelog

Version 1.0.0 - December 17, 2025

  • Initial documentation
  • Comprehensive field documentation with business rules
  • Multiple code examples (C#, JavaScript, Python)
  • Detailed business logic and transaction flow
  • Troubleshooting guide with common scenarios
  • Complete API specification with sample requests/responses
  • Overdraft handling documentation
  • PND activation rules

Last Updated: December 17, 2025

API Version: 1.0

Document Version: 1.0.0