Skip to main content

Overview

Use merchant WebSockets for realtime invoice and payment updates across your account. These streams emit canonical PepayEvent frames for invoice.* and invoice_payment.*. If you are building commerce order UIs, use the commerce stream to receive commerce.order.* updates. See WebSockets (commerce). For webhook signature validation, see Webhooks (merchant).

Authentication in the SDK

The SDK connects via query params, so use a short-lived ws_token minted server-side. WebSocket headers (for direct x-api-key auth) are supported by the raw endpoint but are not wired into the SDK today.

Request

Mint a ws_token

const token = await pepay.ws.token.mint({ scope: 'merchant', ttlSeconds: 60 });

Connect to merchant events

const stream = pepay.ws.connectMerchantEvents({
  token: String(token?.data?.token),
  format: 'event_v1',
  types: 'invoice.*,invoice_payment.*'
});

stream.on('event', (event) => {
  console.log('event', event.id, event.type);
});

Filters you can pass

  • types: Comma-separated event types (supports wildcards, e.g. invoice.*).
  • invoice_type: Optional invoice type filter.
  • invoice_id: Scope to a single invoice.
  • customer_id: Scope to a merchant customer.
  • environment: devnet or mainnet.
  • format: event_v1 (recommended).

Common use cases

  • Merchant dashboards: types=invoice.*,invoice_payment.* with optional environment filter.
  • Single-invoice UI: pass invoice_id to reduce noise.
  • Commerce order tracking: use the commerce stream with types=commerce.order.* and optional order_id.

Commerce stream (order lifecycle)

Use the commerce stream for commerce.order.* updates and linked invoice/payment context. See WebSockets (commerce) for the full guide.
const token = await pepay.ws.token.mint({ scope: 'commerce', ttlSeconds: 60 });
const stream = pepay.ws.connectCommerceEvents({
  token: String(token?.data?.token),
  format: 'event_v1',
  types: 'commerce.order.*'
});

Response

Example event frame:
{
  "id": "evt_1734780000000-123",
  "object": "event",
  "created": 1734780000,
  "type": "invoice.updated",
  "data": {
    "object": {
      "object": "invoice",
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "paid"
    }
  }
}

Event frames and delivery

  • object=event: business events (PepayEvent).
  • object=ws_control: replay/resync hints (listen via stream.on('control')).
  • object=ws_error: terminal error (connection closes).
  • Delivery is at-least-once; dedupe by event.id.

Relationship to webhooks

  • Merchant WebSockets deliver the same event types as merchant webhooks.
  • The WebSocket stream includes replay + REST backfill, making it more redundant and reliable than webhooks for realtime consumption.
  • Webhooks remain best for server-to-server side effects and audit trails.

Recovery and backfill

connectMerchantEvents and connectCommerceEvents return a PepayEventStream that:
  1. Replays from since=<last_event_id> on reconnect.
  2. Backfills missed events over REST (/api/v1/events).
  3. Buffers WS frames during backfill and emits in order.
Notes:
  • Recovery is disabled if no API key is available. To force it, pass recovery.request.auth with the appropriate key.
  • Use connectMerchantEventsRaw or connectCommerceEventsRaw if you want raw websockets without REST backfill.

SDK configuration

  • webSocketFactory is required outside the browser (use ws in Node).
  • websocketBaseUrl overrides the default ws URL.
  • wsHeartbeatMs, wsIdleTimeoutMs, and wsPingMessage control liveness behavior.
  • retry controls reconnect backoff.

Examples

  • Persist the last seen event.id in durable storage so you can resume after deploys/restarts.
Next: WebSockets (commerce)