***
title: WebSockets
slug: features/websockets
subtitle: Receive real-time order updates on your server without polling.
-------------------------------------------------------------------------
Transak uses WebSockets to push real-time order updates to your server and sends event data continuously over a live connection to ensure faster updates.
Transak WebSockets are powered by **Pusher Channels**. Use the **Pusher client library** for your platform, as a plain WebSocket client is not compatible.
**Pusher App Key:** `1d9ffac87de599c61283` | **Cluster:** `ap2`
## When to Use?
|
Use Case
|
Channel
|
How to track
|
|
Track a single order in your frontend
|
Public
|
By Order ID
|
|
Track a specific order using your own reference
|
Public
|
By API Key +
partnerOrderId
|
|
Track all orders server-side
|
Private
|
Encrypted, backend only
|
***
## Channels
|
Channel
|
Channel Name
|
Description
|
|
Receive order updates using the order ID
|
{"${END_CUSTOMER_ORDER_ID}"}
|
Public channel
: Track an order by entering the order ID in the channel name.
|
Receive order updates using your API Key and
partnerOrderId
|
{"${API_KEY}_${partnerOrderId}"}
|
Public channel
: Track an order using your API key and your own order reference (
partnerOrderId
). Generate a unique order ID and pass it as the
partnerOrderId
query parameter before opening the widget.
|
|
Receive all order updates using your API Key & Access Token
|
{"${API_KEY}"}
|
Private channel
: Track all orders using your
API_KEY
&
ACCESS_TOKEN
. The payload is encrypted - decrypt it with your
ACCESS_TOKEN
using the
jsonwebtoken
npm library.
|
For the private channel stream, ensure the WebSocket connection is handled by your backend application, as exposing it on the client side may compromise your Access Token.
## Events
|
WebSocket Event Code
|
Status
|
Description
|
|
ORDER_CREATED
|
`AWAITING_PAYMENT_FROM_USER`
|
When the order has been created but the payment has not yet been received.
|
|
ORDER_PAYMENT_VERIFYING
|
`PAYMENT_DONE_MARKED_BY_USER`
|
When the user marks the payment as done but Transak has not yet received it.
|
|
ORDER_PROCESSING
|
`PROCESSING`
|
Orders in the PROCESSING state have passed checks and the user's payment information has been validated.
|
|
ORDER_PROCESSING
|
`PENDING_DELIVERY_FROM_TRANSAK`
|
When the payment is received and being exchanged & transferred via Transak or a liquidity partner.
|
|
ORDER_COMPLETED
|
`COMPLETED`
|
When Transak has received the payment and the crypto has been sent successfully to the user.
|
|
ORDER_FAILED
|
`EXPIRED`
|
When the user failed to make the payment within the timeframe.
|
|
ORDER_FAILED
|
`FAILED`
|
When the order failed because the card was declined.
|
|
ORDER_FAILED
|
`CANCELLED`
|
When the user cancels the order.
|
|
WebSocket Event Code
|
Status
|
Description
|
|
ORDER_CREATED
|
`AWAITING_PAYMENT_FROM_USER`
|
When the order is created but the payment has not yet been received.
|
|
ORDER_PAYMENT_VERIFYING
|
`PAYMENT_DONE_MARKED_BY_USER`
|
When the user marks the payment as done but it has not been received by Transak yet.
|
|
ORDER_PROCESSING
|
`PENDING_DELIVERY_FROM_TRANSAK`
|
When the payment is received and reconciled and Transak has initiated a fiat transfer to the user.
|
|
ORDER_PROCESSING
|
`ON_HOLD_PENDING_DELIVERY_FROM_TRANSAK`
|
When the crypto payment is received & fiat is being transferred via the banking partner but the system is unable to send fiat to the user.
|
|
ORDER_COMPLETED
|
`COMPLETED`
|
When Transak has received the crypto payment and fiat has been sent successfully to the user's bank account.
|
|
ORDER_FAILED
|
`EXPIRED`
|
When the user failed to make the payment within the timeframe.
|
|
ORDER_FAILED
|
`FAILED`
|
Due to third-party failure.
|
|
ORDER_FAILED
|
`CANCELLED`
|
When the user manually cancels the order.
|
***
## Integration
Select your framework, then choose a channel type to get started.
```bash
npm install pusher-js
```
```bash
npm install pusher-js @react-native-community/netinfo
```
```javascript
import { useEffect } from 'react';
import Pusher, { Channel } from 'pusher-js';
function App() {
const transakOrderId: string = 'TRANSAK_ORDER_ID'; // Replace with your Transak Order ID
useEffect(() => {
const pusher: Pusher = new Pusher('1d9ffac87de599c61283', {
cluster: 'ap2',
});
const orderChannel: Channel = pusher.subscribe(transakOrderId);
orderChannel.bind('ORDER_COMPLETED', (data: any) => {
console.log(`${transakOrderId} ORDER_COMPLETED:`, data);
});
return () => {
orderChannel.unbind_all();
pusher.unsubscribe(transakOrderId);
pusher.disconnect();
};
}, []);
return {/* Your UI */}
;
}
export default App;
```
```javascript
import { useEffect } from 'react';
import Pusher, { Channel } from 'pusher-js';
function App() {
const apiKey: string = 'YOUR_API_KEY'; // Replace with your API Key
const partnerOrderId: string = 'PARTNER_ORDER_ID'; // Replace with your Partner Order ID
useEffect(() => {
const pusher: Pusher = new Pusher('1d9ffac87de599c61283', {
cluster: 'ap2',
});
const channelName = `${apiKey}_${partnerOrderId}`;
const partnerOrderChannel: Channel = pusher.subscribe(channelName);
partnerOrderChannel.bind_global((eventId: string, orderData: any) => {
if (eventId !== 'pusher:subscription_succeeded') {
console.log(`${partnerOrderId} ${eventId}:`, orderData);
}
});
return () => {
partnerOrderChannel.unbind_all();
pusher.unsubscribe(channelName);
pusher.disconnect();
};
}, []);
return {/* Your UI */}
;
}
export default App;
```
```javascript
import { useEffect } from 'react';
import Pusher, { Channel } from 'pusher-js';
import { jwtDecode } from 'jwt-decode';
function App() {
const partnerApiKey: string = 'YOUR_API_KEY'; // Replace with your API Key
useEffect(() => {
const pusher: Pusher = new Pusher('1d9ffac87de599c61283', {
cluster: 'ap2',
});
const allOrdersChannel: Channel = pusher.subscribe(partnerApiKey);
allOrdersChannel.bind_global((event: string, data: any) => {
if (event !== 'pusher:subscription_succeeded') {
try {
const decoded = jwtDecode(data);
console.log(`[allOrders] ${event} Decoded:`, decoded);
} catch (err) {
console.warn('Failed to decode JWT. Using raw data.', err);
}
}
});
return () => {
allOrdersChannel.unbind_all();
pusher.unsubscribe(partnerApiKey);
pusher.disconnect();
};
}, []);
return {/* Your UI */}
;
}
export default App;
```
```bash
npm install pusher-js
```
```javascript
const Pusher = require('pusher-js');
const orderId = 'TRANSAK_ORDER_ID'; // Replace with your Transak Order ID
const pusher = new Pusher('1d9ffac87de599c61283', { cluster: 'ap2' });
const orderChannel = pusher.subscribe(orderId);
orderChannel.bind('ORDER_COMPLETED', (data) => {
console.log(`${orderId} ORDER_COMPLETED:`, data);
});
```
```javascript
const Pusher = require('pusher-js');
const apiKey = 'YOUR_API_KEY'; // Replace with your API Key
const partnerOrderId = 'PARTNER_ORDER_ID'; // Replace with your Partner Order ID
const channelName = `${apiKey}_${partnerOrderId}`;
const pusher = new Pusher('1d9ffac87de599c61283', { cluster: 'ap2' });
const partnerOrderChannel = pusher.subscribe(channelName);
partnerOrderChannel.bind_global((eventId, data) => {
if (eventId !== 'pusher:subscription_succeeded') {
console.log(`${partnerOrderId} ${eventId}:`, data);
}
});
```
```javascript
const Pusher = require('pusher-js');
const jwt = require('jsonwebtoken');
const apiKey = 'YOUR_API_KEY'; // Replace with your API Key
const accessToken = 'ACCESS_TOKEN'; // Replace with your Access Token
const pusher = new Pusher('1d9ffac87de599c61283', { cluster: 'ap2' });
const allOrdersChannel = pusher.subscribe(apiKey);
allOrdersChannel.bind_global((eventId, encryptedData) => {
if (eventId !== 'pusher:subscription_succeeded') {
try {
const decoded = jwt.verify(encryptedData, accessToken);
console.log(`${apiKey} ${eventId} Decoded:`, decoded);
} catch (err) {
console.warn('Failed to decode JWT:', err);
}
}
});
```
Add Pusher script to your HTML ``:
```html
```
```html
Transak WebSocket – Order ID
```
```html
Transak WebSocket – Partner Order ID
```
```html
Transak WebSocket – All Orders
```
Follow the official Pusher guides for your mobile platform:
Set up Pusher Channels in your Android app using the Java SDK.
Set up Pusher Channels in your iOS app using the Swift SDK.
Set up Pusher Channels in your Flutter app for cross-platform support.
***
### Sample Response
A typical event payload received on any channel looks like this:
```json
{
"event": "ORDER_CREATED",
"data": {
"id": "aa39d8e1-…-ce7f",
"walletAddress": "0xD902…BEFeE",
"createdAt": "2025-04-04T13:11:47.260Z",
"status": "AWAITING_PAYMENT_FROM_USER",
"fiatCurrency": "EUR",
"userId": "243a8ce2-…-b19a3",
"cryptoCurrency": "ETH",
"isBuyOrSell": "BUY",
"fiatAmount": 30,
"ipAddress": "14.142.***.***",
"amountPaid": 0,
"paymentOptionId": "sepa_bank_transfer",
"walletLink": "https://sepolia.etherscan.io/address/0xD902…BEFeE",
"quoteId": "9291a8bc-…-04e85",
"orderProcessingType": "NORMAL",
"addressAdditionalData": false,
"network": "ethereum",
"conversionPrice": 0.0006130127560164107,
"cryptoAmount": 0.01759347,
"totalFeeInFiat": 1.3,
"fiatAmountInUsd": 33.05,
"countryCode": "IN",
"partnerOrderId": "partner-order-id",
"stateCode": "Karnataka",
"orderChannelType": "WIDGET",
"tokenContractAddress": "0x0000…0000",
"userKycType": "STANDARD",
"updatedAt": "2025-04-04T13:11:48.374Z",
"cardPaymentData": {},
"conversionPriceData": {},
"partnerFeeInLocalCurrency": 0.3,
"statusHistories": []
}
}
```