Transactions
Process financial transactions with proper double-entry accounting and real-time balance updates. Built for high-volume transaction processing with atomic operations and idempotency guarantees.
The transaction model
The transaction model represents financial movements in your ledger, supporting both simple wallet-style transactions and full double-entry accounting with automatic balance updates.
Properties
- Name
id- Type
- string
- Description
Unique identifier for the transaction.
- Name
idempotency_key- Type
- string
- Description
Client-provided key to prevent duplicate transactions.
- Name
description- Type
- string
- Description
Human-readable description of the transaction.
- Name
reference- Type
- string
- Description
Optional external reference (bank transaction ID, etc.).
- Name
status- Type
- string
- Description
Transaction status:
pendingorposted.
- Name
posted_at- Type
- timestamp
- Description
Timestamp when the transaction was posted.
- Name
metadata- Type
- object
- Description
Additional structured data for the transaction.
- Name
created_at- Type
- timestamp
- Description
Timestamp of when the transaction was created.
- Name
lines- Type
- array
- Description
Array of transaction lines (included in detailed responses).
Transaction line properties
- Name
id- Type
- string
- Description
Unique identifier for the transaction line.
- Name
account_id- Type
- string
- Description
ID of the affected account.
- Name
account_code- Type
- string
- Description
Account code for the affected account.
- Name
account_name- Type
- string
- Description
Display name of the affected account.
- Name
amount- Type
- decimal
- Description
Transaction amount (always positive).
- Name
side- Type
- string
- Description
Transaction side:
debitorcredit.
- Name
currency- Type
- string
- Description
Currency code for this transaction line.
- Name
metadata- Type
- object
- Description
Additional structured data for the transaction line.
- Name
created_at- Type
- timestamp
- Description
Timestamp of when the line was created.
Create simple transaction
Create a single-entry transaction for wallet-style operations. Perfect for customer deposits, withdrawals, and simple balance adjustments.
Required attributes
- Name
idempotency_key- Type
- string
- Description
Unique key to prevent duplicate transactions (max 255 chars).
- Name
description- Type
- string
- Description
Description of the transaction (max 500 chars).
- Name
account_code- Type
- string
- Description
Account code to update.
- Name
amount- Type
- decimal
- Description
Transaction amount (must be positive).
- Name
side- Type
- string
- Description
Transaction side:
debitorcredit.
- Name
currency- Type
- string
- Description
Three-letter currency code (e.g., "NGN", "USD").
Optional attributes
- Name
reference- Type
- string
- Description
External reference (max 255 chars).
- Name
metadata- Type
- object
- Description
Additional structured data.
Request
curl -X POST https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "customer_deposit_001",
"description": "Customer wallet funding",
"reference": "BANK_TXN_12345",
"account_code": "2001",
"amount": "10000.00",
"side": "credit",
"currency": "NGN",
"metadata": {
"customer_id": "cust_123",
"channel": "mobile_app"
}
}'
Response
{
"success": true,
"data": {
"id": "txn_01JB2M3N4P5Q6R7S8T9U0V",
"idempotency_key": "customer_deposit_001",
"description": "Customer wallet funding",
"reference": "BANK_TXN_12345",
"status": "posted",
"posted_at": "2025-09-26T10:30:00Z",
"metadata": {
"customer_id": "cust_123",
"channel": "mobile_app"
},
"created_at": "2025-09-26T10:30:00Z",
"lines": [
{
"id": "line_01JB2M3N4P5Q6R7S8T9U0W",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U0X",
"account_code": "2001",
"account_name": "Customer Deposits",
"amount": "10000.00",
"side": "credit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:30:00Z"
}
]
}
}
Create double-entry transaction
Create a balanced double-entry transaction with multiple entries. All debits must equal credits. Perfect for complex financial operations requiring proper accounting.
Required attributes
- Name
idempotency_key- Type
- string
- Description
Unique key to prevent duplicate transactions (max 255 chars).
- Name
description- Type
- string
- Description
Description of the transaction (max 500 chars).
- Name
entries- Type
- array
- Description
Array of transaction entries (minimum 2 entries required).
Entry object
- Name
account_code- Type
- string
- Description
Account code for this entry.
- Name
amount- Type
- decimal
- Description
Entry amount (must be positive).
- Name
side- Type
- string
- Description
Entry side:
debitorcredit.
- Name
currency- Type
- string
- Description
Currency code (all entries must use same currency).
- Name
metadata- Type
- object
- Description
Optional metadata for this specific entry.
Optional attributes
- Name
reference- Type
- string
- Description
External reference (max 255 chars).
- Name
metadata- Type
- object
- Description
Transaction-level metadata.
Request
curl -X POST https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions/double-entry \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "bank_funding_001",
"description": "Customer funding from GTBank",
"reference": "BANK_TXN_12345",
"entries": [
{
"account_code": "1101",
"amount": "10000.00",
"side": "debit",
"currency": "NGN"
},
{
"account_code": "2001",
"amount": "10000.00",
"side": "credit",
"currency": "NGN"
}
],
"metadata": {
"customer_id": "cust_123",
"bank_name": "GTBank"
}
}'
Response
{
"success": true,
"data": {
"id": "txn_01JB2M3N4P5Q6R7S8T9U0Y",
"idempotency_key": "bank_funding_001",
"description": "Customer funding from GTBank",
"reference": "BANK_TXN_12345",
"status": "posted",
"posted_at": "2025-09-26T10:31:00Z",
"metadata": {
"customer_id": "cust_123",
"bank_name": "GTBank"
},
"created_at": "2025-09-26T10:31:00Z",
"lines": [
{
"id": "line_01JB2M3N4P5Q6R7S8T9U0Z",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U10",
"account_code": "1101",
"account_name": "Settlement Account - GTBank",
"amount": "10000.00",
"side": "debit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
},
{
"id": "line_01JB2M3N4P5Q6R7S8T9U11",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U0X",
"account_code": "2001",
"account_name": "Customer Deposits",
"amount": "10000.00",
"side": "credit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
}
]
}
}
List transactions
Retrieve transactions with filtering and pagination. Perfect for building transaction history views and reconciliation processes.
Optional attributes
- Name
limit- Type
- integer
- Description
Number of transactions to return (default: 50, max: 100).
- Name
offset- Type
- integer
- Description
Number of transactions to skip for pagination.
- Name
account_code- Type
- string
- Description
Filter by account code.
- Name
start_date- Type
- string
- Description
Filter transactions after this date (YYYY-MM-DD format).
- Name
end_date- Type
- string
- Description
Filter transactions before this date (YYYY-MM-DD format).
Request
curl -G https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions \
-H "Authorization: Bearer {api_key}" \
-d limit=20 \
-d account_code=2001 \
-d start_date=2025-09-01 \
-d end_date=2025-09-30
Response
{
"success": true,
"data": {
"transactions": [
{
"id": "txn_01JB2M3N4P5Q6R7S8T9U0Y",
"idempotency_key": "bank_funding_001",
"description": "Customer funding from GTBank",
"reference": "BANK_TXN_12345",
"status": "posted",
"posted_at": "2025-09-26T10:31:00Z",
"created_at": "2025-09-26T10:31:00Z"
},
{
"id": "txn_01JB2M3N4P5Q6R7S8T9U0V",
"idempotency_key": "customer_deposit_001",
"description": "Customer wallet funding",
"reference": "BANK_TXN_12345",
"status": "posted",
"posted_at": "2025-09-26T10:30:00Z",
"created_at": "2025-09-26T10:30:00Z"
}
],
"pagination": {
"total": 2,
"limit": 20,
"offset": 0,
"has_more": false
}
}
}
Retrieve a transaction
Retrieve a single transaction by ID with all transaction lines included.
Request
curl https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions/txn_01JB2M3N4P5Q6R7S8T9U0Y \
-H "Authorization: Bearer {api_key}"
Response
{
"success": true,
"data": {
"id": "txn_01JB2M3N4P5Q6R7S8T9U0Y",
"idempotency_key": "bank_funding_001",
"description": "Customer funding from GTBank",
"reference": "BANK_TXN_12345",
"status": "posted",
"posted_at": "2025-09-26T10:31:00Z",
"metadata": {
"customer_id": "cust_123",
"bank_name": "GTBank"
},
"created_at": "2025-09-26T10:31:00Z",
"lines": [
{
"id": "line_01JB2M3N4P5Q6R7S8T9U0Z",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U10",
"account_code": "1101",
"account_name": "Settlement Account - GTBank",
"amount": "10000.00",
"side": "debit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
},
{
"id": "line_01JB2M3N4P5Q6R7S8T9U11",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U0X",
"account_code": "2001",
"account_name": "Customer Deposits",
"amount": "10000.00",
"side": "credit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
}
]
}
}
Retrieve transaction lines
Retrieve only the transaction lines for a specific transaction. Useful when you need detailed line information without the transaction metadata.
Request
curl https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions/txn_01JB2M3N4P5Q6R7S8T9U0Y/lines \
-H "Authorization: Bearer {api_key}"
Response
{
"success": true,
"data": {
"transaction_lines": [
{
"id": "line_01JB2M3N4P5Q6R7S8T9U0Z",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U10",
"account_code": "1101",
"account_name": "Settlement Account - GTBank",
"amount": "10000.00",
"side": "debit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
},
{
"id": "line_01JB2M3N4P5Q6R7S8T9U11",
"account_id": "acc_01JB2M3N4P5Q6R7S8T9U0X",
"account_code": "2001",
"account_name": "Customer Deposits",
"amount": "10000.00",
"side": "credit",
"currency": "NGN",
"metadata": {},
"created_at": "2025-09-26T10:31:00Z"
}
]
}
}
Common use cases
# Simple customer deposit
curl -X POST https://api.sandbox.whocomply.com/v1/tenants/acme-fintech/transactions \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "deposit_cust123_001",
"description": "Customer wallet funding",
"account_code": "2001",
"amount": "50000.00",
"side": "credit",
"currency": "NGN",
"metadata": {"customer_id": "cust_123"}
}'
Error responses
- Name
VALIDATION_ERROR- Type
- 400
- Description
Request validation failed (missing fields, invalid amounts, etc.).
- Name
DUPLICATE_TRANSACTION- Type
- 409
- Description
Transaction with this idempotency key already exists.
- Name
UNBALANCED_TRANSACTION- Type
- 400
- Description
Debits must equal credits for double-entry transactions.
- Name
INVALID_CURRENCY- Type
- 400
- Description
All entries must use the same currency.
- Name
ACCOUNT_NOT_FOUND- Type
- 400
- Description
One or more account codes are invalid.
- Name
TRANSACTION_NOT_FOUND- Type
- 404
- Description
Transaction with the specified ID was not found.
Unbalanced transaction error
{
"success": false,
"error": {
"code": "UNBALANCED_TRANSACTION",
"message": "Debits must equal credits for double-entry transactions",
"details": {
"total_debits": "10000.00",
"total_credits": "9950.00",
"difference": "50.00"
}
}
}
Duplicate transaction error
{
"success": false,
"error": {
"code": "DUPLICATE_TRANSACTION",
"message": "Transaction with this idempotency key already exists",
"details": {
"existing_transaction_id": "txn_01JB2M3N4P5Q6R7S8T9U0V",
"idempotency_key": "customer_deposit_001"
}
}
}