# Recevoir les webhooks

Vérifier la signature, dédoublonner les livraisons et gérer les reprises.

## Créer un abonnement

L'administrateur configure l'abonnement dans les réglages ou une app utilise les routes `webhook-subscriptions` avec `webhooks:manage`. Conservez le secret `whsec_` à la création : il n'est présenté qu'une fois.

Choisissez les événements nécessaires et une URL HTTPS publiquement accessible. Les redirections ne sont pas suivies. Testez avec le ping de l'écran et vérifiez le journal de livraison.

## Vérifier avant de traiter

Les en-têtes incluent `X-Cercla-Event`, `X-Cercla-Delivery` et `X-Cercla-Signature`. La signature a la forme `t=<secondes>,v1=<hex>`. Elle couvre l'horodatage suivi d'un point et du corps brut, avec HMAC-SHA256 et le secret de l'abonnement.

```js
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verify(secret, rawBody, header, now = Date.now()) {
  const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? '');
  if (!secret || !match) return false;
  const timestamp = Number(match[1]);
  if (!Number.isSafeInteger(timestamp) || Math.abs(now / 1000 - timestamp) > 300) return false;
  const expected = createHmac('sha256', secret)
    .update(match[1] + '.')
    .update(rawBody)
    .digest();
  const received = Buffer.from(match[2], 'hex');
  return received.length === expected.length && timingSafeEqual(received, expected);
}
```

Passez un Buffer contenant les octets reçus, avant tout parseur JSON. Une sérialisation après `JSON.parse` peut changer ces octets. Limitez aussi la taille reçue et gérez les corps invalides dans votre serveur HTTP.

## Acquitter et traiter

1. Vérifiez la signature et la fenêtre temporelle de cinq minutes.
2. Validez la forme de l'événement et son type.
3. Inscrivez durablement la livraison dans votre file ou transaction, avec son identifiant unique.
4. Répondez rapidement avec un statut 2xx.
5. Traitez la livraison avec une contrainte d'unicité sur `X-Cercla-Delivery`.

Acquitter avant toute persistance peut perdre un événement si votre processus s'arrête. La signature ne remplace pas le dédoublonnage : une livraison valide peut être rejouée.

## Échecs, ordre et rejeu

Le timeout de livraison est de cinq secondes. Après un échec, le budget courant est de cinq tentatives, espacées par des délais croissants. Dix échecs consécutifs peuvent désactiver l'abonnement. Le journal et le rejeu permettent de reprendre après correction.

L'ordre n'est pas garanti entre livraisons. Utilisez les dates métier ou relisez la ressource actuelle pour éviter d'appliquer un état ancien après un état récent. Un événement `ping` est un contrôle du canal, pas un objet métier à créer.
