Skip to main content
Subscribe to real-time transaction status updates without polling.

Connection

wss://domain/ws?token=<client_token>&user_id=<partner_user_id>

Query Parameters

ParameterRequiredDescription
tokenYesYour client_token
user_idYesThe partner_user_id whose transactions you want to monitor

Events

tx.update

Fired on every transaction status change for the subscribed user.
{
  "event": "tx.update",
  "merchant_transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "partner_user_id": "user-123",
  "type": "buy",
  "status": "completed",
  "currency": "USDT",
  "fiat_currency": "EUR",
  "fiat_amount": "100.00",
  "crypto_amount": "99.50",
  "occurred_at": "2026-04-01T10:03:45Z"
}

Code Examples

const ws = new WebSocket(
  "wss://domain/ws?token=<client_token>&user_id=user-123"
);

ws.onopen = () => {
  console.log("Connected to Proof WebSocket");
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.event === "tx.update") {
    console.log("Transaction:", msg.merchant_transaction_id);
    console.log("Status:", msg.status);

    if (["completed", "failed", "cancelled"].includes(msg.status)) {
      ws.close();
      handleFinalStatus(msg);
    }
  }
};

ws.onclose = () => {
  // Reconnect with exponential backoff
  setTimeout(reconnect, 2000);
};

ws.onerror = (error) => {
  console.error("WebSocket error:", error);
};

Reconnection

Always implement reconnection with exponential backoff:
let reconnectAttempt = 0;

function connect() {
  const ws = new WebSocket(
    "wss://domain/ws?token=<client_token>&user_id=user-123"
  );

  ws.onopen = () => {
    reconnectAttempt = 0; // Reset on successful connection
  };

  ws.onclose = () => {
    const delay = Math.min(1000 * Math.pow(2, reconnectAttempt), 30000);
    reconnectAttempt++;
    setTimeout(connect, delay);
  };

  ws.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    handleMessage(msg);
  };
}

connect();

Fallback to Polling

If WebSocket is not available (e.g. some network proxies block WebSocket), fall back to polling GET /widget/transactions/{id} every 5–10 seconds.