## Goal

Ingest Stripe events with signature verification, event-level deduplication, and controlled replay for incident recovery.

## Primary endpoints

| Endpoint | Usage | Security |
| --- | --- | --- |
| `POST /api/webhooks/stripe?org={slug}&mode={test\|live}` | general Stripe event intake and technical deduplication | Stripe signature required |
| `POST /api/webhooks/stripe/billing?org={slug}&mode={test\|live}` | billing/subscription-specific events | Stripe signature required |
| `POST /api/billing/webhooks/{webhookEventId}/replay?org={slug}&mode={test\|live}` | manual replay of a stored webhook | Beacon bearer token + `OWNER`/`ADMIN` |

## Processing model

<Steps>
  <Step title="1) Receive event">Validate signature and minimum payload shape.</Step>
  <Step title="2) Deduplicate">Use provider `event.id` as the logical deduplication key; duplicates return `duplicate: true`.</Step>
  <Step title="3) Persist and process">Store internal `webhookEventId` and run async handlers safely.</Step>
  <Step title="4) Confirm state">Update business state and delivery metrics; billing can upsert subscriptions.</Step>
</Steps>

## Canonical URLs by environment

- `test`: `https://test.beacon.pt/api/webhooks/stripe?org=<organization_slug>&mode=test`
- `live`: `https://app.beacon.pt/api/webhooks/stripe?org=<organization_slug>&mode=live`
- If you use the dedicated billing endpoint, keep the same convention on `/api/webhooks/stripe/billing`.

## Retry and replay policy

- Automatic retries must preserve original event context.
- Manual replay uses the internal `webhookEventId`, not Stripe `event.id`.
- Avoid broad replay operations without impact prioritization and explicit validation criteria.

## General endpoint response example

```json
{
  "ok": true,
  "webhookEventId": "whevt_123",
  "eventId": "evt_123",
  "mode": "test",
  "duplicate": false
}
```

## Manual replay example

```bash
curl -X POST "https://test.beacon.pt/api/billing/webhooks/whevt_123/replay?org=acme&mode=test" \
  -H "Authorization: Bearer <beacon_session_token>"
```

## Operational signals

| Signal | Meaning | Action |
| --- | --- | --- |
| rising `4xx` | signature/payload mismatch | rotate secret if needed and revalidate contract |
| growing backlog | slow or blocked consumer | increase throughput and prioritize critical events |
| duplicated side effects | incomplete deduplication | harden dedupe key by `event.id` + organization |

<Warning title="Replay">Replay operations must be auditable and reversible before execution at scale.</Warning>
