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

# Signature V2 Migration

> Move webhook verification from legacy body-only signatures to timestamped signatures

Shoppex now sends a timestamped webhook signature for normal event webhooks and dynamic delivery webhooks.
New integrations should verify `X-Shoppex-Signature-V2`.

## New Headers

| Header                             | Description                                               |
| ---------------------------------- | --------------------------------------------------------- |
| `X-Shoppex-Timestamp`              | Unix timestamp in seconds                                 |
| `X-Shoppex-Signature-V2`           | `v1,t=<timestamp>,h=<hex-sha256>`                         |
| `X-Shoppex-Signature-V2-Algorithm` | `HMAC-SHA256`                                             |
| `X-Shoppex-Delivery`               | Unique delivery ID for normal event webhook deduplication |
| `X-Shoppex-Delivery-Id`            | Unique delivery ID for dynamic delivery deduplication     |

`v1` is a version marker, not the signature value.
Verify the hex digest in `h=...`.

## Signed Payload

Build the signed payload like this:

```txt theme={"system"}
<delivery id>.<timestamp>.<raw JSON request body>
```

Simple example:

```txt theme={"system"}
whd_abc123.1773504000.{"event":"order:paid","data":{"uniqid":"inv_1"}}
```

Then compute:

```txt theme={"system"}
HMAC-SHA256(secret, signed_payload)
```

## Verification Rule

1. Read the raw request body before JSON parsing.
2. Read the delivery ID (`X-Shoppex-Delivery` for event webhooks or `X-Shoppex-Delivery-Id` for dynamic delivery), `X-Shoppex-Timestamp`, and `X-Shoppex-Signature-V2`.
3. Parse `X-Shoppex-Signature-V2`.
4. Check that the timestamp in the signature matches `X-Shoppex-Timestamp`.
5. Reject requests older or newer than 5 minutes.
6. Compare the computed HMAC with the `h=` value using constant-time comparison.
7. Store the delivery ID before doing fulfillment work so retries are idempotent.

## Legacy Headers

`X-Shoppex-Signature` is the legacy body-only HMAC-SHA512 signature.
`X-Shoppex-Unescaped-Signature` is a legacy compatibility workaround for clients that normalized escaped slashes before verifying.

Both legacy headers are deprecated. They remain available during the migration period, but new integrations should not depend on them.
