# Webhook events

A live event listener that monitors webhook events for your current session in real time as payment statuses change, plus a session-scoped webhook URL you can copy for use in your integration.

## What this page covers
- Your session-scoped webhook URL, automatically included in payment intents created during the session
- A real-time event list showing each event's type, payment id, status, and timestamp, with an expandable raw JSON payload
- Connection status (Connected / Reconnecting) and a Clear All control
- How webhooks work conceptually and the common event types

## Key concepts / events / endpoints

### Endpoints (server-side)
- `POST /api/webhooks/session/{sessionId}` — receives an inbound webhook (Hyperswitch format), stores it, and emits it to SSE subscribers. Returns `{ received: true, eventId }`.
- `GET /api/webhooks/session/{sessionId}` — polls stored events; optional `?since=<ISO timestamp>` returns only newer events.
- `DELETE /api/webhooks/session/{sessionId}` — clears stored events for the session.
- `GET /api/webhooks/session/{sessionId}/stream` — Server-Sent Events (SSE) stream. The page listens on this for live updates.

### SSE event names (transport, from the stream endpoint)
- `connected` — sent on connect with `{ sessionId, timestamp }`
- `initial` — all existing stored events sent once on connect, as `{ events: [...] }`
- `webhook` — a new webhook event as it arrives
- `heartbeat` — keep-alive sent every 30 seconds

### Inbound payload parsing
The handler derives fields from the Hyperswitch webhook body:
- `eventType` from `payload.event_type` (falls back to `payload.type`, else `"unknown"`)
- `paymentId` from `payload.content.payment_id` / `payload.content.object.payment_id` / `payload.payment_id`
- `status` from `payload.content.status` / `payload.content.object.status` / `payload.status`
- The full `payload` is stored and shown as expandable JSON.

### Event types
Event type names are read directly from the incoming payload's `event_type`, so any Hyperswitch event type may appear. The page's "About webhooks" section documents these common examples:
- `payment_succeeded` — payment completed successfully
- `payment_failed` — payment attempt failed
- `payment_processing` — payment is being processed
- `refund_succeeded` — refund was processed

Event badges are colour-coded by matching substrings in the event type: `succeeded`/`success` → success, `failed`/`failure` → error, `pending`/`processing` → warning, otherwise default.

### Storage and limits
Events are stored per session (in-memory in development, Redis/Valkey in production when `REDIS_URL` is set), capped at 100 events per session with a 1-hour session expiry.

## Related
- [Gateway agnostic recurring payments](/gateway-agnostic.md): MIT charges that emit payment webhook events
- [Migrating from S2S to Orchestration](/migration-s2s.md): status classification replaces parsing S2S `result.code`
- [Glossary](/glossary.md): definitions for payment status values and event terms

---

Interactive version: https://playground.peachpayments.com/webhooks
