Transaction Webhook
Business clients receive real-time notifications when transaction status changes occur. This webhook provides comprehensive information about all transaction types including deposits, withdrawals, exchanges, direct exchanges, and transfers.
When is this webhook sent?
The transaction webhook is sent when:
- A transaction status changes (e.g., from
PENDINGtoCOMPLETED,PROCESSINGtoFAILED) - The transaction belongs to a user associated with your business
- Your business API key has a webhook URL configured
Payload Schema
The transaction webhook uses a unified payload structure that works for all transaction types and currencies:
{
"event_type": "transaction",
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"transaction_type": "DEPOSIT",
"status": "COMPLETED",
"reference": "TXN-123456789",
"user_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"created_at": "2024-01-15T10:30:00Z",
"timestamp": "2024-01-15T10:35:00Z",
"origin_reference": "550e8400-e29b-41d4-a716-446655440001",
"source_currency": "CAD",
"source_amount": "100.00",
"target_currency": "USD",
"target_amount": "75.00",
"amount_with_fees": "105.00",
"fee": "5.00",
"fee_currency": "CAD",
"exchange_rate": "0.75",
"sender": {
"email": "sender@example.com",
"account_number": "1234567890",
"account_name": "John Doe",
"bank_name": "Example Bank",
"beneficiary_id": "550e8400-e29b-41d4-a716-446655440002"
},
"recipient": {
"email": "recipient@example.com",
"account_number": "9876543210",
"account_name": "Jane Smith",
"bank_name": "Another Bank",
"beneficiary_id": "550e8400-e29b-41d4-a716-446655440003"
}
}Payload Fields
Core Fields
| Field | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | Always "transaction" for this webhook type |
transaction_id | string | Yes | Unique identifier for the transaction (UUID format) |
transaction_type | string | Yes | Type of transaction: DEPOSIT, WITHDRAWAL, EXCHANGE, DIRECT_EXCHANGE, TRANSFER |
status | string | Yes | Current transaction status: PENDING, PROCESSING, COMPLETED, SUCCESSFUL, FAILED, CANCELLED |
reference | string | Yes | Transaction reference you can use to reconcile |
user_id | string | Yes | Unique identifier for the user who owns the transaction (UUID format) |
created_at | string | Yes | RFC3339 timestamp indicating when the transaction was created (UTC) |
timestamp | string | Yes | RFC3339 timestamp indicating when the webhook was generated (UTC) |
origin_reference | string | Yes | Origin reference UUID associated with the transaction |
Currency and Amount Fields
| Field | Type | Required | Description |
|---|---|---|---|
source_currency | string | Yes | Currency code of the source currency (e.g., CAD, USD, EUR, GBP) |
source_amount | string | Yes | Amount in source currency (decimal string) |
target_currency | string | Yes | Currency code of the target currency (e.g., CAD, USD, EUR, GBP) |
target_amount | string | Yes | Amount in target currency (decimal string) |
amount_with_fees | string | Yes | Total amount including fees (decimal string) |
fee | string | No | Total fee amount (decimal string, omitted if zero) |
fee_currency | string | No | Currency of the fee (omitted if no fee) |
exchange_rate | string | No | Exchange rate used for cross-currency transactions (omitted for same-currency transactions) |
Party Information
| Field | Type | Required | Description |
|---|---|---|---|
sender | object | No | Sender information (structure varies by transaction type) |
recipient | object | No | Recipient information (structure varies by transaction type) |
Sender and Recipient Fields
The sender and recipient objects contain party details. Fields are included based on availability and transaction type:
| Field | Type | Description |
|---|---|---|
email | string | Email address of the party |
account_number | string | Bank account number or payment address |
account_name | string | Name associated with the account |
bank_name | string | Name of the bank or financial institution |
beneficiary_id | string | Unique identifier for the beneficiary (UUID format, if applicable) |
Transaction Types
DEPOSIT
A deposit transaction represents funds being sent from an external party to your user.
- Sender: External party (may include payment sender name, email, or account number)
- Recipient: Your user (may include beneficiary account details if deposit is to a beneficiary account)
Example:
{
"event_type": "transaction",
"transaction_type": "DEPOSIT",
"status": "COMPLETED",
"sender": {
"email": "external@example.com",
"account_name": "External Sender"
},
"recipient": {
"email": "user@example.com",
"account_name": "John Doe",
"account_number": "1234567890",
"bank_name": "User Bank",
"beneficiary_id": "550e8400-e29b-41d4-a716-446655440002"
}
}WITHDRAWAL
A withdrawal transaction represents funds being sent from your user to an external beneficiary.
- Sender: Your user
- Recipient: External beneficiary
Example:
{
"event_type": "transaction",
"transaction_type": "WITHDRAWAL",
"status": "COMPLETED",
"sender": {
"email": "user@example.com",
"account_name": "John Doe"
},
"recipient": {
"email": "beneficiary@example.com",
"account_number": "9876543210",
"account_name": "Jane Smith",
"bank_name": "Beneficiary Bank",
"beneficiary_id": "550e8400-e29b-41d4-a716-446655440003"
}
}EXCHANGE
An exchange transaction represents currency conversion within your user's account.
- Sender: Your user
- Recipient: Your user (same user, different currency)
Example:
{
"event_type": "transaction",
"transaction_type": "EXCHANGE",
"status": "COMPLETED",
"source_currency": "CAD",
"source_amount": "100.00",
"target_currency": "USD",
"target_amount": "75.00",
"exchange_rate": "0.75",
"sender": {
"email": "user@example.com",
"account_name": "John Doe"
},
"recipient": {
"email": "user@example.com",
"account_name": "John Doe"
}
}DIRECT_EXCHANGE
A direct exchange transaction represents a deposit that is immediately converted to a different currency.
- Sender: External party (deposit sender)
- Recipient: Your user (in target currency)
Example:
{
"event_type": "transaction",
"transaction_type": "DIRECT_EXCHANGE",
"status": "COMPLETED",
"source_currency": "CAD",
"source_amount": "100.00",
"target_currency": "USD",
"target_amount": "75.00",
"exchange_rate": "0.75",
"sender": {
"email": "external@example.com",
"account_name": "External Sender"
},
"recipient": {
"email": "user@example.com",
"account_name": "John Doe"
}
}TRANSFER
A transfer transaction represents funds being sent from your user to another user or beneficiary.
- Sender: Your user
- Recipient: Another user or beneficiary
Example:
{
"event_type": "transaction",
"transaction_type": "TRANSFER",
"status": "COMPLETED",
"sender": {
"email": "user@example.com",
"account_name": "John Doe"
},
"recipient": {
"email": "recipient@example.com",
"account_number": "9876543210",
"account_name": "Jane Smith",
"bank_name": "Recipient Bank",
"beneficiary_id": "550e8400-e29b-41d4-a716-446655440003"
}
}Transaction Status Values
| Status | Description |
|---|---|
PENDING | Transaction has been created but not yet processed |
PROCESSING | Transaction is currently being processed |
COMPLETED | Transaction has been successfully completed |
SUCCESSFUL | Transaction completed successfully (alternative to COMPLETED) |
FAILED | Transaction failed to complete |
CANCELLED | Transaction was cancelled |
Example Payloads
Example 1: Completed Deposit
{
"event_type": "transaction",
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"transaction_type": "DEPOSIT",
"status": "COMPLETED",
"reference": "TXN-123456789",
"user_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"created_at": "2024-01-15T10:30:00Z",
"timestamp": "2024-01-15T10:35:00Z",
"origin_reference": "550e8400-e29b-41d4-a716-446655440001",
"source_currency": "CAD",
"source_amount": "100.00",
"target_currency": "CAD",
"target_amount": "100.00",
"amount_with_fees": "100.00",
"sender": {
"email": "sender@example.com",
"account_name": "External Sender"
},
"recipient": {
"email": "user@example.com",
"account_name": "John Doe"
}
}Example 2: Failed Withdrawal
{
"event_type": "transaction",
"transaction_id": "660e8400-e29b-41d4-a716-446655440001",
"transaction_type": "WITHDRAWAL",
"status": "FAILED",
"reference": "TXN-987654321",
"user_id": "7ba7b810-9dad-11d1-80b4-00c04fd430c9",
"created_at": "2024-01-15T11:00:00Z",
"timestamp": "2024-01-15T11:05:00Z",
"origin_reference": "660e8400-e29b-41d4-a716-446655440002",
"source_currency": "USD",
"source_amount": "50.00",
"target_currency": "NGN",
"target_amount": "40000.00",
"amount_with_fees": "52.50",
"fee": "2.50",
"fee_currency": "USD",
"exchange_rate": "800.00",
"sender": {
"email": "user@example.com",
"account_name": "Jane Smith"
},
"recipient": {
"account_number": "1234567890",
"account_name": "Beneficiary Name",
"bank_name": "Beneficiary Bank",
"beneficiary_id": "770e8400-e29b-41d4-a716-446655440003"
}
}Example 3: Processing Exchange
{
"event_type": "transaction",
"transaction_id": "770e8400-e29b-41d4-a716-446655440002",
"transaction_type": "EXCHANGE",
"status": "PROCESSING",
"reference": "TXN-456789123",
"user_id": "8ba7b810-9dad-11d1-80b4-00c04fd430c0",
"created_at": "2024-01-15T12:00:00Z",
"timestamp": "2024-01-15T12:01:00Z",
"origin_reference": "770e8400-e29b-41d4-a716-446655440004",
"source_currency": "EUR",
"source_amount": "200.00",
"target_currency": "GBP",
"target_amount": "170.00",
"amount_with_fees": "202.00",
"fee": "2.00",
"fee_currency": "EUR",
"exchange_rate": "0.85",
"sender": {
"email": "user@example.com",
"account_name": "Bob Johnson"
},
"recipient": {
"email": "user@example.com",
"account_name": "Bob Johnson"
}
}Important Notes
-
Status Changes: This webhook is sent whenever a transaction status changes. You may receive multiple webhooks for the same transaction as it progresses through different statuses.
-
Idempotency: Implement idempotency handling in your webhook receiver. Use the
transaction_idto deduplicate events, as the same transaction status change may trigger multiple webhook deliveries if retries occur. -
Party Information: The
senderandrecipientfields are populated based on the transaction type. Some fields may be omitted if the information is not available. -
Exchange Rate: The
exchange_ratefield is only included for cross-currency transactions. For same-currency transactions (e.g., CAD to CAD), this field is omitted. -
Fees: The
feeandfee_currencyfields are omitted if there are no fees associated with the transaction. -
Webhook Security: This webhook uses the same security mechanism as other business webhooks:
- Signed with HMAC-SHA256 using your API key's secret
- Includes
X-Transfaar-Signatureheader for verification - Same retry logic applies (up to 10 attempts with exponential backoff, only retries if response is not 200 OK)