> ## Documentation Index
> Fetch the complete documentation index at: https://docs-alpha.pepay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSockets (commerce)

> Realtime commerce order updates with recovery and filters.

## Overview

Use the commerce WebSocket stream for realtime `commerce.order.*` updates and linked commerce invoice/payment context. It emits the same event types as the commerce webhooks, but with replay and REST backfill for resilience.
Commerce invoices expire after \~30 minutes; include `invoice.*` if you want to capture `invoice.updated` with `status=expired`.

## Authentication

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

## Request

### Mint a `ws_token`

```ts theme={null}
const token = await pepay.ws.token.mint({ scope: 'commerce', ttlSeconds: 60 });
```

### Connect to commerce events

```ts theme={null}
const stream = pepay.ws.connectCommerceEvents({
  token: String(token?.data?.token),
  format: 'event_v1',
  types: 'commerce.order.*'
});

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

### Filters you can pass

* `types`: Comma-separated event types (supports wildcards, e.g. `commerce.order.*`).
* `order_id`: Scope to a single order.
* `invoice_id`: Scope to a linked invoice.
* `customer_id`: Scope to a merchant customer.
* `wallet_address`: Scope to a payer wallet.
* `wallet_network`: Scope to a network (e.g. `solana`, `bsc`).
* `format`: `event_v1` (recommended).

## Response

Example commerce event frame:

```json theme={null}
{
  "id": "evt_1734780000000-456",
  "object": "event",
  "type": "commerce.order.updated",
  "created": 1734780000,
  "data": {
    "object": {
      "object": "commerce_order",
      "id": "order_123",
      "status": "fulfilled",
      "invoice_id": "inv_123"
    }
  }
}
```

## Errors

* Token mint/connect auth failures return `401`/`403`.
* Invalid stream query params return `400`.
* Retry and resume from last `event.id` on transient disconnects.

## Relationship to webhooks

* Webhooks and WebSockets deliver the same `commerce.order.*` event types.
* WebSockets include replay + REST backfill, so they are more resilient for realtime UX.
* Webhooks remain best for server-to-server side effects and audit trails.

## Recovery and delivery

`connectCommerceEvents` returns a `PepayEventStream` that:

1. Replays from `since=<last_event_id>` on reconnect.
2. Backfills missed events via REST (`/api/v1/events`).
3. Buffers WS frames during backfill and emits in order.

Delivery is at-least-once; dedupe by `event.id`.

## Devnet simulator

Devnet order simulation (`commerce.devnet.simulateOrder`) emits the same `commerce.order.updated` events on this stream. See [Orders](/sdk/commerce/orders) for the simulation flow.

## Examples

* Keep the last delivered `event.id` and reconnect with `since=<event_id>` to avoid gaps after restarts.

Next: [Commerce API keys](/sdk/commerce/api-keys)
