Skip to main content

Seize Lock Amount

Convert a locked amount to an actual debit, permanently removing the funds from the account for legal seizure or final payment settlement.

Overview

The SeizeDepositLockAmountCommand converts an amount lock into an actual debit transaction. Unlike DeleteDepositLockAmountCommand which releases funds back to the account, this command permanently debits the locked amount. This is used for legal seizures, court orders, final settlement of card transactions, or when a hold must be converted to a permanent charge.

Key Capabilities

  • Lock Conversion: Converts lock to actual debit
  • Permanent Debit: Funds permanently removed from account
  • Transaction Creation: Creates seizure transaction for audit
  • Channel Integration: Links to transaction channel
  • Service Categorization: Supports service ID and description
  • Atomic Operation: Uses database transaction for consistency
  • Audit Trail: Complete record of seizure with reason

API Endpoint

POST /api/bpm/cmd


Request Structure

{
"commandName": "SeizeDepositLockAmountCommand",
"data": {
"accountEncodedKey": "string",
"blockReference": "string",
"channelEncodedKey": "string",
"transactionExternalReference": "string",
"serviceId": "string",
"serviceDescription": "string",
"remarks": "string",
"serviceCommision": "decimal"
}
}

Request Fields

FieldTypeRequiredDescription
accountEncodedKeystringYesAccount number or encoded key
blockReferencestringYesUnique reference from original lock
channelEncodedKeystringYesTransaction channel identifier
transactionExternalReferencestringNoExternal system reference
serviceIdstringNoService identifier for categorization
serviceDescriptionstringNoHuman-readable service description
remarksstringNoAdditional notes/reason for seizure
serviceCommisiondecimalNoOptional commission amount

Response Structure

Success Response

{
"isSuccessful": true,
"message": "Locked amount has been seized successfully.",
"statusCode": "00",
"data": {
"transactionKey": "8A3F2D1E9B5C4F7A6E8D2C1B3A9F5E7D",
"amount": 2500.00
}
}

Error Response

{
"isSuccessful": false,
"message": "There is no existing amount lock with the specified reference",
"statusCode": "Client_Not_Found"
}

Sample Requests

{
"commandName": "SeizeDepositLockAmountCommand",
"data": {
"accountEncodedKey": "ACC001234567",
"blockReference": "LEGAL-HOLD-2024-123",
"channelEncodedKey": "BRANCH-CHANNEL",
"serviceId": "LEGAL_SEIZURE",
"serviceDescription": "Court Order Seizure",
"remarks": "Court order #CO-2024-5678 - Final seizure"
}
}

2. Seize Card Transaction

{
"commandName": "SeizeDepositLockAmountCommand",
"data": {
"accountEncodedKey": "SAV987654321",
"blockReference": "CARD-AUTH-20241217-001",
"channelEncodedKey": "CARD-CHANNEL",
"transactionExternalReference": "VISA-TXN-456789",
"serviceId": "CARD_SETTLEMENT",
"serviceDescription": "Card Transaction Settlement",
"remarks": "Final settlement of card purchase",
"serviceCommision": 25.00
}
}

3. Seize Hotel Charges

{
"commandName": "SeizeDepositLockAmountCommand",
"data": {
"accountEncodedKey": "8A3F2D1E9B5C4F7A6E8D2C1B3A9F5E7D",
"blockReference": "HOTEL-HOLD-5678",
"channelEncodedKey": "MERCHANT-CHANNEL",
"serviceId": "HOTEL_PAYMENT",
"serviceDescription": "Hotel Room Charges",
"remarks": "Final hotel bill - Room damages"
}
}

Business Logic

Processing Workflow

Validation Steps

  1. Extract Fields: Get all request parameters
  2. Account Query: Load account with Client, Product, Currency relationships
  3. Account Validation: Verify account exists
  4. Channel Query: Validate transaction channel
  5. Channel Validation: Verify channel is valid and active
  6. Lock Query: Find lock with matching blockReference and LOCKED state
  7. Lock Validation: Verify lock exists and transaction is in HOLD state
  8. Transaction Begin: Start database transaction
  9. Transaction Key: Generate unique GUID-based key
  10. State Updates:
    • Set lock transaction to SETTLED
    • Set lock state to SEIZED
    • Decrease BlockedAmount (not AccountBalance - already blocked)
  11. Seizure Transaction Creation:
    • Create CBSTransaction with SETTLED state
    • Create DepositTransaction with DEBIT entry
    • Link to GL account from product
    • Set narration with block reference
  12. Persist Changes: Update lock, account, and transactions
  13. Commit: Commit database transaction
  14. Success Response: Return transaction key and amount

Balance Impact

Before Seize:

AccountBalance: 10,000.00 (already reduced when lock was created)
BlockedAmount: 2,000.00
Available: 8,000.00

After Seize (2,000 lock converted):

AccountBalance: 10,000.00 (unchanged - was already debited)
BlockedAmount: 0.00 (lock removed)
Available: 10,000.00
Net Effect: 2,000 permanently removed

Error Responses

Error CodeMessageScenarioResolution
Client_Not_Found"Account not valid"Invalid account identifierVerify account number/key
INVALID_REQUEST"Channel not valid"Invalid or inactive channelVerify channelEncodedKey
Client_Not_Found"No lock with reference"Lock not found or already processedVerify blockReference

Code Examples

C# Implementation

public async Task<SeizeLockResponse> SeizeLockAmountAsync(
string accountEncodedKey,
string blockReference,
string channelEncodedKey,
string serviceId = null,
string serviceDescription = null,
string remarks = null,
string transactionExternalReference = null,
decimal? serviceCommision = null)
{
var request = new
{
commandName = "SeizeDepositLockAmountCommand",
data = new
{
accountEncodedKey,
blockReference,
channelEncodedKey,
transactionExternalReference,
serviceId,
serviceDescription,
remarks,
serviceCommision
}
};

var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{_baseUrl}/api/bpm/cmd", content);

return JsonSerializer.Deserialize<SeizeLockResponse>(
await response.Content.ReadAsStringAsync());
}

JavaScript Implementation

async seizeLockAmount(
accountEncodedKey,
blockReference,
channelEncodedKey,
options = {}
) {
const request = {
commandName: 'SeizeDepositLockAmountCommand',
data: {
accountEncodedKey,
blockReference,
channelEncodedKey,
transactionExternalReference: options.externalRef,
serviceId: options.serviceId,
serviceDescription: options.serviceDescription,
remarks: options.remarks,
serviceCommision: options.commission
}
};

const response = await fetch(`${this.baseUrl}/api/bpm/cmd`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.accessToken}`,
'X-Tenant-ID': this.tenantId
},
body: JSON.stringify(request)
});

return await response.json();
}

Python Implementation

def seize_lock_amount(
self,
account_encoded_key: str,
block_reference: str,
channel_encoded_key: str,
transaction_external_reference: Optional[str] = None,
service_id: Optional[str] = None,
service_description: Optional[str] = None,
remarks: Optional[str] = None,
service_commision: Optional[float] = None
) -> SeizeLockResponse:
request_data = {
'commandName': 'SeizeDepositLockAmountCommand',
'data': {
'accountEncodedKey': account_encoded_key,
'blockReference': block_reference,
'channelEncodedKey': channel_encoded_key,
'transactionExternalReference': transaction_external_reference,
'serviceId': service_id,
'serviceDescription': service_description,
'remarks': remarks,
'serviceCommision': service_commision
}
}

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

result = response.json()
return SeizeLockResponse(
is_successful=result.get('isSuccessful', False),
message=result.get('message', ''),
status_code=result.get('statusCode', ''),
transaction_key=result.get('data', {}).get('transactionKey'),
amount=result.get('data', {}).get('amount')
)

Business Rules

Validation Rules

  1. Account Required: accountEncodedKey must be provided
  2. Block Reference Required: blockReference must match existing lock
  3. Channel Required: channelEncodedKey must be valid transaction channel
  4. Account Must Exist: Account must be in system
  5. Channel Must Exist: Channel must be valid and active
  6. Lock Must Exist: Lock with blockReference must exist
  7. Lock Must Be Active: Lock state must be LOCKED (not UNLOCKED or SEIZED)
  8. Transaction Hold State: Lock transaction must be in HOLD state

Operational Rules

  1. Atomic Operation: Uses database transaction for consistency
  2. Permanent Debit: Funds cannot be recovered after seizure
  3. State Changes: Lock → SEIZED, Transaction → SETTLED
  4. Balance Impact: BlockedAmount decreased (balance was already reduced at lock time)
  5. Transaction Creation: New seizure transaction created with unique key
  6. Deposit Transaction: DEBIT entry created for accounting
  7. GL Integration: Links to product's savings control GL account
  8. Narration: Auto-generated with block reference
  9. Methodology: Uses account product's accounting methodology
  10. Rollback on Error: Transaction rolled back if any step fails
  11. Activity Logging: Can be tracked via transaction key
  12. Idempotent: Cannot seize same lock twice
  13. Service Tracking: Optional serviceId for categorization
  14. Commission Support: Optional service commission field
  15. External Reference: Supports external system correlation

  • LockDepositAmountCommand: Create initial amount lock
  • DeleteDepositLockAmountCommand: Release lock instead of seizing
  • GetLockDepositAmountQuery: Query locks before seizing

Troubleshooting

Issue: "Channel not valid"

Symptom: INVALID_REQUEST error with channel message

Solution:

  • Verify channelEncodedKey exists in TransactionChannel table
  • Ensure channel is active
  • Use correct channel for service type (BRANCH, CARD, MERCHANT, etc.)

Issue: Lock Already Seized

Symptom: "No existing amount lock" error

Solution:

  • Lock may already be seized or deleted
  • Use GetLockDepositAmountQuery to check current state
  • Verify blockReference is correct

Support

For technical assistance: api-support@banklingo.com