---
title: "Transaction Events"
method: POST
path: "transaction.events"
tags: ["Webhooks"]
---

# Transaction Events

`POST transaction.events` (webhook)

Afriex sends real-time webhook notifications to your configured URL whenever a transaction is **created** or **updated**.

- `TRANSACTION.CREATED`: Fired when a new transaction is initiated.
- `TRANSACTION.UPDATED`: Fired when the transaction status or other fields change (most commonly `status` and `updatedAt`).

The payload structure is **identical** for both events. Only the `event` field and potentially `status` + `updatedAt` differ.

**Security**: Every request includes an `x-webhook-signature` header and an `x-afriex-business-id` header carrying your business id. You **must** verify this signature using Afriex's public key before processing. The key is an elliptic-curve (secp384r1 / P-384) key, not RSA. The signature is ECDSA with SHA-256, DER-encoded and then base64-encoded, computed over the exact raw request body, so verify it before parsing or re-serialising the JSON. See the [Webhooks Overview & Security](https://docs.afriex.com/api-reference/endpoint/webhooks/introduction) section for verification instructions.

## Payload

- object
  - `id` string, uuid, required: Unique ID of this event. Every delivery attempt of the same event carries the same `id`, so use it to ignore a delivery you have already processed.
  - `event` 'TRANSACTION.CREATED' | 'TRANSACTION.UPDATED', required: Identifies which transaction event occurred
  - `createdAt` string, date-time, required: When Afriex created the event. Retries keep this value, and the signature covers it, so you can reject a delivery that is older than you expect.
  - `data` object, required: Details of the transaction
    - `status` 'PENDING' | 'PROCESSING' | 'SUCCESS' | 'FAILED' | 'CANCELLED' | 'REFUNDED' | 'RETRY' | 'UNKNOWN' | 'SCHEDULED' | 'CUSTOMER_ACTION_REQUIRED' | 'REJECTED' | 'IN_REVIEW' | 'RFI_REQUESTED' | 'DISPUTED' | 'DISPUTE_RESOLVED' | 'DISPUTE_WON' | 'DISPUTE_LOST' | 'DISPUTE_EVIDENCE_SUBMITTED', required: The current status of the transaction. `IN_REVIEW` and `RFI_REQUESTED` are review states: the transaction is still in flight and is waiting on a review, not on you. Treat them as non-terminal and keep polling or listening for `TRANSACTION.UPDATED`. `RFI_REQUESTED` may result in someone contacting you for more information about the transfer.
    - `type` 'DEPOSIT' | 'WITHDRAW' | 'SWAP', required: Type/direction of the transaction
    - `channel` 'BANK_ACCOUNT' | 'SWIFT' | 'MOBILE_MONEY' | 'UPI' | 'INTERAC' | 'WE_CHAT' | 'CARD' | 'CRYPTO' | 'VIRTUAL_BANK_ACCOUNT' | 'POOL_ACCOUNT' | 'ACH_BANK_ACCOUNT' | 'PAYBILL_TILL' | 'RFP' | 'VIRTUAL_CARD' | 'ALIPAY' | 'WALLET' | 'PAYMENT_LINQ' | 'ADMIN': Payment channel of the transaction. `ADMIN` marks an adjustment Afriex made to your wallet; `PAYMENT_LINQ` a payment made through a payment link.
    - `sourceAmount` string, required: Amount in source currency (string for precision)
    - `sourceCurrency` string, required: ISO 4217 source currency code
    - `destinationAmount` string, required: Amount in destination currency (string)
    - `destinationCurrency` string, required: ISO 4217 destination currency code
    - `sourceId` string: ID of the source payment method (e.g. for deposits)
    - `destinationId` string: ID of the destination (e.g. payment method ID for withdraws)
    - `customerId` string, required: ID of the customer who owns this transaction
    - `transactionId` string, required: Unique identifier of the transaction
    - `merchantReference` string: The merchant-supplied reference (mirrors meta.reference from the create request).
    - `rate` string: The realized source-to-destination exchange rate, expressed as `1 sourceCurrency = rate destinationCurrency`. Same field as on the Transaction response.
    - `fee` string: The fee charged, denominated in `sourceCurrency`. Omitted when no fee applied.
    - `createdAt` string, date-time, required: ISO 8601 timestamp when the transaction was created
    - `updatedAt` string, date-time, required: ISO 8601 timestamp of the last update

## Acknowledgement `200`

Acknowledge receipt. Return any 2xx status code quickly. Response body is ignored.

## Other responses

- `400`: Bad Request, malformed payload, invalid/missing signature, etc. Afriex will retry delivery.
- `401`: Unauthorized, signature verification failed.

---

[API](https://skmtc.dev/afriex/apis/afriex-business-api.md) - [All operations](https://skmtc.dev/afriex/apis/afriex-business-api/llms.txt) - [OpenAPI document](https://skmtc.dev/afriex/apis/afriex-business-api/revisions/d94198b6c256?raw)
