Description
Purpose and use
The transactions manual covers legacy transaction workflows that prepare, approve, sign, monitor, and complete customer money movements. It remains relevant where customer transaction endpoints still create drafts, final transactions, inward payments, status history, and manual FX overrides.
Who uses this. Payment operations, customer support, compliance reviewers, and implementation teams use this manual when investigating older transaction flows or client integrations that have not moved to the modern transfers flow.
How it works. A transaction can begin as a draft, move through approval and signing, pass compliance checks, and then settle into posted ledger movements. Status history and journal-entry lookup provide the audit trail for each step.
What users do. Users create or update drafts, finalize a transaction, sign or cancel when allowed, review status changes, resolve exceptions, and trace the transaction into ledger entries.
Outcomes and side effects. Finalized transactions can create fees, FX conversions, compliance checks, notifications, and ledger postings. Canceled or failed transactions remain in history for audit and customer-service review.
Related manuals: Modern Transfers, Ledgers & Balance Management, KYT, FX.
Overview
The Transactions API provides comprehensive functionality for managing financial transactions:
- Draft and final transaction creation and management
- Multi-currency support with automatic conversion
- Fee and tax calculation
- Transaction signing and approval workflows
- Transaction status tracking and history
- Compliance validation with ComplyAdvantage
- Automated transaction processing
- Recurring transaction support
- Inward transfer (IWT) processing
Core Concepts
Transaction Types
iwt: Inward transfer (from external to internal account)owt: Outward transfer (from internal to external account)int: Internal transfer (between different customers within the same institution)own: Own account transfer (between accounts of the same customer)
Transaction Statuses
incomplete: Partially created transactiondraft: Draft transaction being preparedwaiting-for-signature: Awaiting digital signaturepending: Ready for processingin-progress: Currently being processedcompleted: Successfully completedcancelled: Cancelled by userfailed: Failed to processsuspended: Temporarily suspended (e.g., compliance review)
Account Types
recipient: External recipientaccount: Internal accountsender: External sender (for inward transfers)
Endpoints
Draft Transaction Management
Create Draft Transaction
POST /v1/customers/{customer_id}/transaction/draft
Create a draft transaction that can be modified before final submission.
Update Draft Transaction
PUT /v1/customers/{customer_id}/transaction/{transaction_id}/draft
Update an existing draft transaction.
Delete Draft Transaction
DELETE /v1/transaction/{transaction_id}
Delete a draft transaction.
Transaction Creation
Create Fast Transaction
POST /v1/customers/{customer_id}/transaction
Create and immediately submit a transaction for processing.
Request Body:
{
"sender": {
"account": {
"id": "uuid"
}
},
"recipient": {
"type": "recipient",
"recipient": {
"id": "uuid"
}
},
"original_amount": {
"currency": "EUR",
"amount": 100.00
},
"channel": "api",
"description": "Payment for services",
"is_recurring": false,
"recurring_period": "1m"
}Response:
{
"id": "uuid",
"sender": {
"name": "John Doe Company",
"iban": "CH1234567890123456789",
"amount": {
"currency": "CHF",
"amount": 105.50
},
"fee": {
"currency": "CHF",
"amount": 2.50
}
},
"recipient": {
"name": "Acme Corp",
"iban": "DE89370400440532013000",
"amount": {
"currency": "EUR",
"amount": 100.00
},
"fee": {
"currency": "EUR",
"amount": 1.00
}
},
"amount": {
"currency": "EUR",
"amount": 100.00
},
"status": "waiting-for-signature",
"channel": "api",
"task_id": "uuid",
"type": "owt",
"direction": "outgoing",
"value_date": "2024-03-21T10:00:00Z",
"created_at": "2024-03-21T10:00:00Z",
"modified_at": "2024-03-21T10:00:00Z"
}Create Final Transaction
PUT /v1/customers/{customer_id}/transaction/{transaction_id}/final
Convert a draft transaction to final status for processing.
Create Inward Transaction
POST /v1/transactions/iwt
Process an inward transfer from external source.
Request Body:
{
"sender": {
"name": "External Bank",
"iban": "GB29NWBK60161331926819",
"bic": "NWBKGB2L",
"country": "GB"
},
"recipient": {
"iban": "CH1234567890123456789",
"bic": "CHASUS33",
"bank": "Swiss Bank",
"country": "CH"
},
"amount": 1000.00,
"currency": "EUR",
"channel": "swift",
"description": "Invoice payment",
"value_date": "2024-03-21T10:00:00Z"
}Transaction Actions
Sign Transaction
POST /v1/transaction/{transaction_id}/sign
Digitally sign a transaction to authorize processing.
Cancel Transaction
PATCH /v1/transaction/{transaction_id}/cancel
Cancel a transaction that is waiting for signature.
Resolve Transaction
PATCH /v1/transactions/{transaction_id}/resolve
Resolve a suspended transaction (e.g., after compliance review).
Set Manual FX Rate
PATCH /v2/transactions/{transaction_id}/fx-rate
Override the automatically calculated FX rate for a draft, pending, or waiting-for-signature transaction. The override is stored on the participant metadata, short-circuits automatic conversion, and zeroes the conversion fee so downstream calculations stay consistent.
Request Body:
{
"fx_rate": 1.0523,
"reason": "Manual rate entry by operator"
}Behavior Notes:
- Allowed statuses:
draft,pending,waiting-for-signature reasonis optional but recommended for audit history- Response returns the sanitized
CustomerTransactionAPIpayload reflecting the updated amounts
Transaction Queries
Get Transactions
GET /v1/transactions
List transactions with optional filtering and pagination.
Query Parameters:
status: Filter by transaction statustype: Filter by transaction typecustomer_id.eq: Filter by customer IDsender__account__id.eq: Filter by sender accountlimit: Number of results per pageoffset: Pagination offsetsort: Sort order (e.g.,-created_at)stack: Group results by field (e.g.,created_at[YYYY-MM])
Get Transfers
GET /v1/transfers
List transfers with filtering, sorting, and pagination support. Uses RBAC-aware query system with JSON-based search and sort parameters.
Query Parameters:
search.status: Filter by transfer status (e.g.,pending,draft,completed,failed,cancelled)search.type: Filter by transfer type (e.g.,crypto_deposit,crypto_withdrawal,sepa,internal,wire)search.ori_customer_id: Filter by originator customer ID (UUID)search.ben_customer_id: Filter by beneficiary customer ID (UUID)search.customer_id: Deprecated - usesearch.ori_customer_idinstead. Filter by originator customer ID (UUID)search.product_id: Filter by product ID (UUID)search.product_code: Filter by product code (e.g.,CRD)search.txn_ccy: Filter by currency code (e.g.,EUR,USD,USDC)sort: Sort field (prefix with-for descending). Example:-created_atorcreated_atlimit: Number of items per page (default: 20, max: 100)offset: Starting position for pagination (default: 0)
Example Request:
GET {{base_url}}/v1/transfers?limit=20&offset=0&search.status=pending&sort=-created_atResponse:
{
"data": [
{
"id": "uuid",
"product_id": "uuid",
"product_code": "CRD",
"ori_customer_id": "uuid",
"ben_customer_id": "uuid",
"ori_account_id": "uuid",
"ben_account_id": "uuid",
"type": "crypto_deposit",
"status": "pending",
"txn_amt": "1000.00",
"txn_ccy": "USDC",
"txn_paymentPurpose": "Crypto deposit from external wallet",
"ori_name": "John Doe",
"ori_iban": "CH9300762011623852957",
"ori_bic": "UBSWCHZH80A",
"ben_name": "Beneficiary Name",
"ben_iban": "",
"ben_bic": "",
"ori_walletAddress": "0x1234567890abcdef1234567890abcdef12345678",
"ben_walletAddress": "0xabcdef1234567890abcdef1234567890abcdef12",
"bc_network": "ERC20",
"token": "USDC",
"bc_txHash": "",
"txn_netAmt": "99.50",
"txn_feeAmt": "0.50",
"direction": "inbound",
"created_at": "2024-03-21T10:00:00Z",
"updated_at": "2024-03-21T10:00:00Z"
}
],
"total": 1,
"total_unfiltered": 1,
"has_more": false
}Get Transaction
GET /v1/customers/{customer_id}/transactions/{transaction_id}
Get detailed transaction information.
Get Transaction Status History
GET /v1/transactions/{transaction_id}/status-history
Get the complete status change history for a transaction.
Response:
{
"data": [
{
"id": "uuid",
"status": "draft",
"date": "2024-03-21T09:00:00Z"
},
{
"id": "uuid",
"status": "waiting-for-signature",
"date": "2024-03-21T09:30:00Z"
},
{
"id": "uuid",
"status": "pending",
"date": "2024-03-21T10:00:00Z"
}
],
"total": 3,
"has_more": false
}Get Journal Entries by Transaction ID
GET /v1/ledgers/entries
Query journal entries (ledger entries) for a specific transaction. Use this endpoint to view all journal entries associated with a transaction ID.
Query Parameters:
transaction_id.eq: Filter by transaction ID (UUID) - Use this to search for entries by transaction IDledger_id.eq: Filter by ledger IDledger_code.eq: Filter by ledger codetype.eq: Filter by entry type (debitorcredit)event.eq: Filter by event namelimit: Number of results per page (default: 50, max: 100)offset: Pagination offsetsort: Sort order (e.g.,-created_at,amount)
Example Request:
GET /v1/ledgers/entries?transaction_id.eq=550e8400-e29b-41d4-a716-446655440000Response:
{
"data": [
{
"id": "uuid",
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"ledger_id": "uuid",
"ledger_code": "4022",
"amount": 1000000,
"type": "debit",
"currency_code": "CHF",
"event": "before-kyt",
"description": "Suspense Crypto (ERC USDC)",
"value_date": "2024-03-21T10:00:00Z",
"created_at": "2024-03-21T10:00:01Z"
},
{
"id": "uuid",
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"ledger_id": "uuid",
"ledger_code": "20212",
"amount": 1000000,
"type": "credit",
"currency_code": "CHF",
"event": "before-kyt",
"description": "Customer Crypto Deposits (ERC USDC)",
"value_date": "2024-03-21T10:00:00Z",
"created_at": "2024-03-21T10:00:01Z"
}
],
"total": 2,
"has_more": false
}Usage:
To view all journal entries for a specific transaction, use the search parameter transaction_id.eq with the transaction UUID. This is useful for:
- Auditing transaction entries
- Verifying journal entry balances
- Reviewing all ledger movements for a transaction
- Debugging transaction processing
Compliance & Webhooks
ComplyAdvantage Webhook
POST /v1/comply_advantage/webhook
Receive compliance validation results from ComplyAdvantage.
Get ComplyAdvantage Responses
GET /v1/comply_advantage
List ComplyAdvantage compliance validation responses.
Get ComplyAdvantage Response
GET /v1/comply_advantage/{transaction_id}
Get ComplyAdvantage compliance data for a specific transaction.
Special Features
Currency Conversion
The system automatically handles currency conversion between sender and recipient currencies using real-time exchange rates and customer-specific tariffs.
Recurring Transactions
Transactions can be set as recurring with patterns:
1d,2d, etc. - Daily recurring1w,2w, etc. - Weekly recurring1m,2m, etc. - Monthly recurring
Fee Calculation
Transaction fees are automatically calculated based on:
- Customer tariff settings
- Transaction amount and currency
- Channel used (API, web, mobile)
- Transaction type
Compliance Integration
All transactions are automatically validated against:
- ComplyAdvantage sanctions screening
- Customer risk levels
- Transaction limits and patterns
- KYT (Know Your Transaction) requirements
Error Codes
Transaction Errors
| Code | Description |
|---|---|
| transactions_m.invalid_matches_len | Invalid expression matches length |
| transactions_m.variable_not_found | Variable not found in expression |
| transactions_m.invalid_constant_value | Invalid constant value in expression |
| transactions_m.unknown_operation | Unknown operation in expression |
| transactions_m.invalid_transaction_id | Invalid transaction ID |
| transactions_m.failed_to_sign_transaction | Failed to sign transaction |
| transactions_m.task_is_not_waiting_for_signatories | Task not in signing state |
| transactions_m.transaction_cannot_be_cancelled | Transaction cannot be cancelled |
| transactions_m.transaction_cannot_be_run | Transaction cannot be run |
| transactions_m.failed_to_update_balance | Failed to update balance |
| transactions_m.failed_to_create_transaction | Failed to create transaction |
| transactions_m.invalid_transaction_type | Invalid transaction type |
| transactions_m.sender_id_is_required | Sender ID is required |
| transactions_m.recipient_account_id_is_required | Recipient account ID is required |
| transactions_m.invalid_fx_rate | Provided FX rate violates validation limits |
| transactions_m.transaction_not_found_for_fx_rate | Transaction not found for manual FX override |
| transactions_m.transaction_status_not_allow_fx_rate | Transaction status does not allow manual FX override |
This table lists the most common user-facing errors. A full multilingual set is defined in config/samples/transactions_m.