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

# Verify webhooks

> Verify signed Lynq webhook events and process them safely.

# Verify webhooks

In **Dashboard → Webhooks**, add a public HTTPS endpoint for test or live mode and store its signing secret in server-side secret storage.

Lynq sends:

| Header           | Use                        |
| ---------------- | -------------------------- |
| `Lynq-Event-Id`  | Deduplicate deliveries.    |
| `Lynq-Signature` | Verify the HMAC signature. |

The signature is `HMAC-SHA256(<timestamp>.<raw request body>)`, using the endpoint signing secret. The header format is `t=<unix timestamp>,v1=<signature>`.

```ts theme={null}
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody: string, timestamp: string, received: string, secret: string) {
  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(received, "hex");
  const b = Buffer.from(expected, "hex");
  return a.length === b.length && timingSafeEqual(a, b);
}
```

Verify the raw request body before parsing JSON. Store processed event IDs, then fulfil an order only from a verified `payment_intent.succeeded` event.

Temporary network failures, `408`, `429`, and `5xx` responses are retried with exponential backoff and jitter for up to 72 hours. Return `2xx` after processing; other `4xx` responses are not retried.


## Related topics

- [Quickstart](/start/quickstart.md)
- [Idram](/payment-methods/idram.md)
- [Lynq overview](/index.md)
- [Go-live checklist](/go-live/checklist.md)
- [Test your integration](/go-live/testing.md)
