Wallgent
Guides

Real-Time Events

Stream live payment and wallet events over WebSocket for dashboards and reactive agents.

Overview

Wallgent provides two delivery mechanisms for events:

WebSocket (Realtime)Webhooks
Best forReal-time dashboards, reactive UI, live agent monitoringServer-to-server processing, durable event handling
DeliveryPushed to connected client immediatelyHTTP POST to your endpoint
AuthAPI key passed in connection URLSignature verification on each request
ReconnectAutomatic exponential backoffN/A — your endpoint must be reachable
Missed eventsNot replayed after disconnectRetried by Wallgent on failure

Use WebSockets when you need sub-second latency in a connected client. Use webhooks for reliable server-side event processing.


Connecting

The WallgentRealtime class is exported from the SDK alongside the main client.

import { WallgentRealtime } from '@wallgent/sdk'

const rt = new WallgentRealtime(
  process.env.WALLGENT_API_KEY!,
  'https://api.wallgent.com',          // Automatically converted to wss://
)

await rt.connect()
console.log('Connected to Wallgent real-time stream')

The constructor converts https:// to wss:// and http:// to ws:// automatically, so you can pass the same base URL used for REST calls.


Listening for Events

Specific Events

rt.on('payment.completed', (data) => {
  console.log(`Payment ${data.transactionId} completed for ${data.amount} ${data.currency}`)
})

rt.on('approval.created', (data) => {
  console.log(`New approval pending: ${data.approvalId}`)
  // Notify your review team
})

The on() method returns an unsubscribe function:

const off = rt.on('wallet.funded', (data) => {
  console.log('Wallet funded:', data)
})

// Later, when you no longer need this listener:
off()

Wildcard Listener

Listen to all events at once. The _event field on the data payload tells you which event fired.

rt.on('*', (data) => {
  const eventType = data._event as string
  console.log(`[${eventType}]`, data)
})

Available Events

EventDescription
payment.completedA payment finished processing
payment.pendingA payment is queued (awaiting settlement)
payment.failedA payment attempt failed
payment.reversedA payment was reversed
wallet.fundedA wallet received a deposit
wallet.frozenA wallet was frozen
policy.deniedA payment was blocked by a policy rule
approval.createdA payment is held pending human review
approval.approvedA held payment was approved and executed
approval.rejectedA held payment was rejected
limit.approachingA spend limit is near its threshold

Event Payload Structure

Event payloads use the same structure as webhook events:

{
  type: 'payment.completed',      // Event type
  timestamp: '2026-03-01T14:32:00.000Z',
  data: {
    transactionId: 'txn_01J...',
    amount: '150.00',
    currency: 'USD',
    fromWalletId: 'wal_01J...',
    toWalletId: 'wal_01J...',
    status: 'COMPLETED',
  }
}

For wildcard listeners, the _event field is added to the data object so you can identify which event fired.


Disconnecting

rt.disconnect()

Disconnect closes the WebSocket, clears all listeners, and stops the auto-reconnect logic.


Auto-Reconnect

WallgentRealtime reconnects automatically if the connection drops. The reconnect strategy uses exponential backoff:

  • Attempt 1: wait 1s
  • Attempt 2: wait 2s
  • Attempt 3: wait 4s
  • ...up to a maximum delay of 30 seconds
  • Maximum 10 reconnect attempts before giving up

If the initial connect() call fails (not a reconnect), the promise rejects immediately.


React Example

Use WallgentRealtime inside a useEffect with a cleanup function to properly manage the connection lifecycle.

import { useEffect, useState } from 'react'
import { WallgentRealtime } from '@wallgent/sdk'

interface WalletEvent {
  transactionId: string
  amount: string
  currency: string
}

function LivePaymentFeed({ walletId }: { walletId: string }) {
  const [events, setEvents] = useState<WalletEvent[]>([])

  useEffect(() => {
    const rt = new WallgentRealtime(
      process.env.NEXT_PUBLIC_WALLGENT_API_KEY!,
      'https://api.wallgent.com',
    )

    rt.on('payment.completed', (data) => {
      setEvents((prev) => [data as unknown as WalletEvent, ...prev].slice(0, 20))
    })

    rt.connect().catch(console.error)

    // Cleanup on unmount
    return () => {
      rt.disconnect()
    }
  }, [walletId])

  return (
    <ul>
      {events.map((e) => (
        <li key={e.transactionId}>
          {e.amount} {e.currency} — {e.transactionId}
        </li>
      ))}
    </ul>
  )
}

WebSocket Endpoint

The WebSocket endpoint used internally:

wss://api.wallgent.com/v1/ws?token=<api-key>

The API key is passed as a query parameter on the initial connection. Once authenticated, events for your organization are streamed as JSON messages.

On this page