transaction.completed — delivered when a transaction that was not declined has posted: a
originalTransactionNo pointing at the transaction being reversed.
transaction.refunded / transaction.reversed, once the funds
PURCHASE, ATM_WITHDRAWAL and CARD_ISSUE, totalDebitAmount is the amount debited from
billingAmount.| Field | Type | Description |
|---|---|---|
eventId | string | Unique per event. Deduplicate on this value |
eventType | string | Always transaction.completed |
version | string | Payload schema version. Additive changes do not bump it |
occurredAt | string | When the event happened, not when it was delivered (ISO 8601) |
data | object | The transaction, see below |
dataGET /api/v1/issuing/transaction/{transactionNo}, so
| Field | Type | Description |
|---|---|---|
transactionNo | string | PIK transaction number |
cardNo | string | PIK card number |
cardholderNo | string | PIK cardholder number |
type | string | PURCHASE / REFUND / REVERSAL / ATM_WITHDRAWAL / VERIFICATION / SETTLEMENT_ADJUST / CARD_ISSUE. CARD_ISSUE is the record for a card issuance fee |
status | string | Usually COMPLETED. data reflects the transaction's current state when the event is delivered, so this can be REVERSED if the transaction has already been reversed by then — for example when a posting update arrives after the reversal |
originalTransactionNo | string | Set on refunds and reversals, otherwise null |
transactionAmount | string | Amount in the merchant's currency. null on CARD_ISSUE records |
transactionCurrency | string | Merchant currency, ISO 4217. null on CARD_ISSUE records |
billingAmount | string | Amount posted in the card's settlement currency |
billingCurrency | string | Settlement currency, ISO 4217 |
fx | object | Foreign exchange details, see below |
fees | array | Itemised fee breakdown, see below |
totalFeeAmount | string | Sum of all fee amounts |
totalDebitAmount | string | billingAmount + totalFeeAmount |
merchant | object | name / mcc / city / country. null on CARD_ISSUE records and when no merchant details were supplied |
transactionTime | string | Time the transaction occurred |
postedTime | string | Time the transaction was posted |
declineReason | string | null for this event |
fx| Field | Type | Description |
|---|---|---|
isCrossCurrency | boolean | Whether the transaction currency differs from the billing currency |
rate | string | Rate applied to your account, billing currency per unit of transaction currency. 1 when both are the same currency. Not the raw interbank rate |
fees[]| Field | Type | Description |
|---|---|---|
feeCode | string | CARD_TRANSACTION_FEE / CARD_ATM_FEE / CARD_FX_CONVERSION_FEE / CARD_ISSUE_FEE. ATM withdrawals are charged CARD_ATM_FEE only, never both |
feeName | string | Human-readable fee name |
amount | string | Fee amount |
currency | string | Fee currency |
baseAmount | string | The amount the fee was calculated on, equal to billingAmount. null for fixed fees |
calcMode | string | PERCENT / FIXED |
rate | string | Rate applied in PERCENT mode, as a decimal (0.015 means 1.5%) |
fixedAmount | string | Fixed amount applied in FIXED mode |
minFee / maxFee | string | Bounds applied, null when unbounded |
ruleNo | string | Identifies the exact pricing rule applied, for reconciliation. The parameters above are a snapshot taken when the transaction was processed |
What baseAmountis calculated on. Percentage fees are calculated onbillingAmount—
the amount charged to you in the card's settlement currency, before any fees. SobaseAmount
equalsbillingAmounton every percentage-based item. Fixed fees such asCARD_ISSUE_FEE
have no base and leave itnull.
{
"eventId": "evt_01J9X8ZQ4T3P",
"eventType": "transaction.completed",
"version": "1.0",
"occurredAt": "2026-08-11T02:20:18Z",
"data": {
"transactionNo": "TX260811K3M5N1",
"cardNo": "CD260811X9Y8Z7",
"cardholderNo": "CH260811A1B2C3",
"type": "PURCHASE",
"status": "COMPLETED",
"originalTransactionNo": null,
"transactionAmount": "40.00",
"transactionCurrency": "USD",
"billingAmount": "40.00",
"billingCurrency": "USD",
"fx": {
"isCrossCurrency": false,
"rate": "1.00000000"
},
"fees": [
{
"feeCode": "CARD_TRANSACTION_FEE",
"feeName": "Transaction fee",
"amount": "0.60",
"currency": "USD",
"baseAmount": "40.00",
"calcMode": "PERCENT",
"rate": "0.015",
"fixedAmount": null,
"minFee": "0.50",
"maxFee": null,
"ruleNo": "FR20260814I01"
}
],
"totalFeeAmount": "0.60",
"totalDebitAmount": "40.60",
"merchant": {
"name": "STEAM PURCHASE",
"mcc": "5734",
"city": "Singapore",
"country": "SG"
},
"transactionTime": "2026-08-11T02:20:15Z",
"postedTime": "2026-08-11T02:20:18Z",
"declineReason": null
}
}{
"eventId": "evt_01J9X8ZQ4T4R",
"eventType": "transaction.completed",
"version": "1.0",
"occurredAt": "2026-08-12T01:02:11Z",
"data": {
"transactionNo": "TX260812P7Q2R8",
"cardNo": "CD260811X9Y8Z7",
"cardholderNo": "CH260811A1B2C3",
"type": "REFUND",
"status": "COMPLETED",
"originalTransactionNo": "TX260811K3M5N1",
"transactionAmount": "40.00",
"transactionCurrency": "USD",
"billingAmount": "40.00",
"billingCurrency": "USD",
"fx": {
"isCrossCurrency": false,
"rate": "1.00000000"
},
"fees": [],
"totalFeeAmount": "0.00",
"totalDebitAmount": "40.00",
"merchant": {
"name": "STEAM PURCHASE",
"mcc": "5734",
"city": "Singapore",
"country": "SG"
},
"transactionTime": "2026-08-12T01:02:08Z",
"postedTime": "2026-08-12T01:02:11Z",
"declineReason": null
}
}| Header | Value |
|---|---|
X-Webhook-Event | Event category, always ISSUING for this event |
X-Webhook-Event-Type | The specific event type, see above |
X-Webhook-Signature | HMAC-SHA256 signature, lowercase hex |
X-Webhook-Signature = hex_lower( HMAC_SHA256( appSecret, rawBody ) )appSecret — there is no separate webhook secret.eventId is mandatory, not optional.eventId.occurredAt to decide which version is newer.transactionNo as the business key; a transaction can generate several events.