Webhooks

Receive real-time event notifications at your server without polling.

View as Markdown

Transak uses webhooks to push real-time event notifications to your server. Instead of polling the API for updates, Transak sends event data directly to a URL you provide to ensure faster updates and fewer unnecessary API calls.

Supported Webhook Types

Add or Update Webhook

1

Contact & Submit your webhook request

Webhook URLs can only be added or updated after KYB approval in the production environment.

Follow the steps in the Need help in Integration section. Provide the following details:

FieldDescription
Order Webhook URLYour HTTPS endpoint for order events
KYC Webhook URLYour HTTPS endpoint for KYC events
EnvironmentSTAGING or PRODUCTION

Both Order and KYC webhook URLs must use HTTPS and be publicly accessible before they can be registered.

2

Await confirmation

Our team will review your request and notify you once the webhook URL has been successfully added or updated.

Order Webhooks

Notify the partner’s backend in real time when an order’s status changes. These events allow partners to track order creation, status updates, completion, and failures.

Events

ScreenWebhook Event CodeStatusDescriptionResponse JSON
ORDER_CREATEDAWAITING_PAYMENT_FROM_USERWhen the order is created, but the payment has not been received yet.{ webhookData: { id: '37969614-...', ... }, eventID: 'ORDER_CREATED' }
ORDER_PAYMENT_VERIFYINGPAYMENT_DONE_MARKED_BY_USERWhen the user marks the payment as done but it is not received by us yet.
ORDER_PROCESSINGPROCESSINGOrders in the PROCESSING state have passed the checks and the user’s payment information has been validated.{ webhookData: { id: 'e0d9f47a-...', ... }, eventID: 'ORDER_PROCESSING' }
ORDER_PROCESSINGPENDING_DELIVERY_FROM_TRANSAKWhen the payment is received and is being exchanged & transferred via us or our liquidity partner.{ webhookData: { id: 'e0d9f47a-...', ... }, eventID: 'ORDER_PROCESSING' }
ORDER_COMPLETEDCOMPLETEDWhen we have received the payment and the crypto is sent successfully to the user.{ webhookData: { id: 'e0d9f47a-...', ... }, eventID: 'ORDER_COMPLETED' }
ORDER_FAILEDCANCELLEDWhen the user cancels the order.{ webhookData: { id: '08c570cf-...', ... }, eventID: 'ORDER_FAILED' }
ORDER_FAILEDFAILEDWhen the order failed because of a card decline.{ webhookData: { id: '08c570cf-...', ... }, eventID: 'ORDER_FAILED' }
ORDER_REFUNDEDREFUNDEDWhen fiat payment received from the user is refunded back to their payment instrument as cryptocurrency could not be fulfilled due to some reason.{ webhookData: { id: '08c570cf-...', ... }, eventID: 'ORDER_REFUNDED' }
ORDER_FAILEDEXPIREDWhen the user failed to make the payment within the timeframe.{ webhookData: { id: '08c570cf-...', ... }, eventID: 'ORDER_EXPIRED' }

Decrypting the Webhook Payload

The webhook data field is a JWT encrypted using your Access Token. Use the code samples below to verify and decode it. You can generate an Access Token using this guide.

1

Install the dependency

NPM Package: jsonwebtoken

$npm install jsonwebtoken
2

Verify and decode the webhook payload

1import jwt from "jsonwebtoken";
2
3// JWT token received from the webhook response's data field
4const webhookData = "eyJhbGciOiJIU.eyJ3ZWJob29-rRGF0.W07q-JG6jlyzid4";
5
6// Your Access Token — used as the signing secret
7const accessToken = "ACCESS_TOKEN";
8
9// Verify and decode the JWT token
10const decodedData = jwt.verify(webhookData, accessToken);
11
12console.log(decodedData);

Sample Decrypted Payload

1{
2 "webhookData": {
3 "id": "181b6159-2192-4f68-8647-f48e6e8f58c7",
4 "walletAddress": "0xD902d7eBF7bcE",
5 "createdAt": "2024-08-23T10:33:09.426Z",
6 "status": "COMPLETED",
7 "fiatCurrency": "EUR",
8 "userId": "243a8ce2-9cc6-41a9-aaeb-b0deeb09a3",
9 "cryptoCurrency": "ETH",
10 "isBuyOrSell": "BUY",
11 "fiatAmount": 32,
12 "ipAddress": "35.177.158.9",
13 "amountPaid": 32,
14 "paymentOptionId": "sepa_bank_transfer",
15 "walletLink": "https://sepolia.etherscan.io/address/0xD902d7eBF7bcE",
16 "quoteId": "0b9edf4d-2de1-4f2e-bdb6-07bc61c380f5",
17 "orderProcessingType": "NORMAL",
18 "addressAdditionalData": false,
19 "network": "ethereum",
20 "conversionPrice": 0.00041416655266757863,
21 "cryptoAmount": 0.01211023,
22 "totalFeeInFiat": 2.76,
23 "fiatAmountInUsd": 35.57,
24 "countryCode": "IN",
25 "stateCode": "Karnataka",
26 "orderChannelType": "WIDGET",
27 "userKycType": "STANDARD",
28 "cardPaymentData": {
29 "orderId": "181b6159-2192-4f68-8647-f48e6e8f58c7",
30 "paymentId": "66c8656bb38a7908fadc77db",
31 "pgData": {
32 "paymentOptions": [
33 {
34 "currency": "EUR",
35 "id": "sepa_bank_transfer",
36 "name": "Bank Transfer Details",
37 "fields": [
38 { "name": "Bank Name", "value": "Transak Limited" },
39 { "name": "IBAN", "value": "GB69MOCK00000003743944" },
40 { "name": "Bank Name", "value": "Modulr" },
41 { "name": "Bank Address", "value": "Scale Space, 58 Wood Lane, London, W12 7RZ" }
42 ]
43 }
44 ],
45 "liquidityProvider": "MODULR",
46 "status": "CREATED"
47 },
48 "liquidityProvider": "MODULR",
49 "updatedAt": "2024-08-23T10:33:58.753Z",
50 "status": "CAPTURED",
51 "processedOn": "2024-08-23T10:33:57.000Z"
52 },
53 "statusHistories": [
54 {
55 "status": "PENDING_DELIVERY_FROM_TRANSAK",
56 "createdAt": "2024-08-23T10:33:59.408Z",
57 "message": "💸 Payment reconciled successfully. Received 32 EUR",
58 "isEmailSentToUser": false,
59 "partnerEventId": "ORDER_PROCESSING"
60 }
61 ],
62 "isFirstOrder": false,
63 "updatedAt": "2024-08-23T10:34:06.371Z",
64 "completedAt": "2024-08-23T10:34:39.412Z",
65 "transactionHash": "DUMMY_TX_ID",
66 "transactionLink": "https://sepolia.etherscan.io/tx/DUMMY_TX_ID",
67 "conversionPriceData": {
68 "id": "139474c7-99c5-4232-9a05-c6ccd6a973ed",
69 "createdAt": "2024-08-23T10:34:06.352Z",
70 "fiatCurrency": "EUR",
71 "cryptoCurrency": "ETH",
72 "paymentMethod": "sepa_bank_transfer",
73 "fiatAmount": 32,
74 "network": "ethereum",
75 "cryptoAmount": 0.01211023,
76 "isBuyOrSell": "BUY",
77 "conversionPrice": 0.00041416641727771563,
78 "marketConversionPrice": 0.00041628949369556297,
79 "slippage": 0.51,
80 "cryptoLiquidityProvider": "transak",
81 "fiatLiquidityProvider": "coinbase",
82 "partnerApiKey": "d79671a4-b021-4a4f-a444-6862a680a94b",
83 "sourceTokenAmount": 0.012110226041200406,
84 "sourceToken": "ETH",
85 "notes": [],
86 "fiatFeeAmount": 2.76,
87 "feeDecimal": 0.08625,
88 "swaps": [
89 {
90 "sourceCurrency": "EUR",
91 "destinationCurrency": "USDT",
92 "sourceAmount": 32,
93 "destinationAmount": 35.57563545494966,
94 "paymentMethod": "sepa_bank_transfer",
95 "liquidityProvider": "coinbase",
96 "conversionPrice": 1.111738607967177,
97 "feeInSourceAmount": 0,
98 "networkFeeInSourceAmount": 0,
99 "marketConversionPrice": 1.111738607967177,
100 "isNonCustodial": false,
101 "isFiatliquidityProvider": true,
102 "isFiatPartnerDirectCryptoDeposit": false,
103 "isFiatPartnerAccountWalletDeposit": false,
104 "liquidityProviderData": false,
105 "originalDestinationAmount": 35.57563545494966
106 },
107 {
108 "sourceCurrency": "USDT",
109 "destinationCurrency": "ETH",
110 "sourceAmount": 35.57563545494966,
111 "destinationAmount": 0.0132533253528869,
112 "liquidityProvider": "transak",
113 "conversionPrice": 0.0003725393849863884,
114 "networkFeeInSourceAmount": 0,
115 "networkFeeInDestinationAmount": 0,
116 "marketConversionPrice": 0.0003725393849863884,
117 "liquidityProviderData": false,
118 "isNonCustodial": false
119 },
120 {
121 "sourceCurrency": "ETH",
122 "destinationCurrency": "ETH",
123 "sourceAmount": 0.0132533253528869,
124 "destinationAmount": 0.0132533253528869,
125 "liquidityProvider": "transak",
126 "conversionPrice": 1,
127 "isCryptoliquidityProvider": true,
128 "networkFeeInSourceAmount": 0.000067651170404,
129 "networkFeeInDestinationAmount": 0.000067651170404,
130 "marketConversionPrice": 1,
131 "liquidityProviderData": false,
132 "isFiatPartnerAccountWalletDeposit": false
133 }
134 ],
135 "fees": [
136 {
137 "name": "Transak fee",
138 "value": 2.6,
139 "id": "transak_fee",
140 "ids": ["transak_fee", "partner_fee"]
141 },
142 {
143 "name": "Network/Exchange fee",
144 "value": 0.16,
145 "id": "network_fee",
146 "ids": ["network_fee"]
147 }
148 ],
149 "fiatAmountInUsd": 35.57,
150 "internalFees": [
151 { "name": "Network/Exchange fee", "id": "network_fee", "value": 0.16 },
152 { "name": "Transak fee", "id": "transak_fee", "value": 1 },
153 { "name": "Transak fee", "id": "partner_fee", "value": 1.6 }
154 ],
155 "cost": {
156 "ethPriceInLocalCurrency": 2402.17448469,
157 "gasCostinLocalCurrency": 0.16334786495892,
158 "transakMinimumFee": 1,
159 "transakFeeAmount": 1,
160 "fiatLiquidityProviderFee": 0,
161 "gasCostinLocalCurrencyByFiatPartner": 0,
162 "gasCostinLocalCurrencyByCryptoPartner": 0,
163 "partnerFeeDecimal": 0.05,
164 "partnerFeeInLocalCurrency": 1.6,
165 "totalFeeDecimal": 0.08625,
166 "totalFeeAmount": 2.76,
167 "gasCurrency": "ETH",
168 "gasInNativeToken": 0.000068,
169 "gasCurrencyRateInUsd": 0.0003744603090795391,
170 "totalAmountChargedByTransak": 2.76334786495892
171 }
172 },
173 "partnerFeeInLocalCurrency": 1.6
174 },
175 "eventID": "ORDER_COMPLETED",
176 "createdAt": "2024-08-23T10:34:40.070Z"
177}

KYC Webhooks

Notify partner’s backend in real-time when a user’s KYC verification status changes. These events allow to track KYC submissions, approvals and rejections.

Events

The following Event IDs are triggered during the KYC lifecycle and sent via webhook

Event IDKYC StatusDescription
KYC_SUBMITTED

SUBMITTED

Triggered when a user submits their KYC details

KYC_APPROVED

APPROVED

Triggered when the user’s KYC verification is approved

KYC_REJECTED

REJECTED

Triggered when the user’s KYC verification is rejected

Webhook Response

Schema

kycStatus
stringRequired

The KYC verification status (SUBMITTED, APPROVED, or REJECTED)

eventID
stringRequired

The event identifier (KYC_SUBMITTED, KYC_APPROVED, or KYC_REJECTED)

partnerUserId
stringRequired

The unique identifier for the user in the partner’s system

Response Schema
1{
2 "data": {
3 "kycStatus": "string",
4 "eventID": "string",
5 "partnerUserId": "string",
6 "partnerCustomerId": "string" //Optional
7 }
8}

Sample Response

KYC_SUBMITTED
1{
2 "data": {
3 "kycStatus": "SUBMITTED",
4 "eventID": "KYC_SUBMITTED",
5 "partnerUserId": "0870c29f-75a8-4091-a068-775fa4577172",
6 "partnerCustomerId": "12345"
7 }
8}
1{
2 "data": {
3 "kycStatus": "APPROVED",
4 "eventID": "KYC_APPROVED",
5 "partnerUserId": "0870c29f-75a8-4091-a068-775fa4577172",
6 "partnerCustomerId": "12345"
7 }
8}
1{
2 "data": {
3 "kycStatus": "REJECTED",
4 "eventID": "KYC_REJECTED",
5 "partnerUserId": "0870c29f-75a8-4091-a068-775fa4577172",
6 "partnerCustomerId": "12345"
7 }
8}