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

# Webhooks de commande

> Recevez des événements de commande signés et durables avec retries, déduplication et traitement rejouable.

Les webhooks de commande notifient un receiver POS ou un observateur sans polling. Configurez les endpoints pendant l’onboarding de l’intégration ou depuis la page Webhooks du dashboard lorsque cet accès est activé pour votre compte.

## Événements

| Événement              | Payload                                                                                      | Usage typique                     |
| ---------------------- | -------------------------------------------------------------------------------------------- | --------------------------------- |
| `order.created`        | Snapshot public complet et actuel de la commande                                             | Créer la commande dans le POS     |
| `order.status.updated` | Statut actuel, `status_version`, horaires de fulfillment, statut précédent, source et raison | Réconcilier l’état bidirectionnel |

Chataigne persiste l’événement et le changement métier dans la même transaction de base de données avant la mise en file. BullMQ transporte la livraison persistée ; il n’est pas la source de vérité.

## Routage des endpoints

Un endpoint peut être observateur ou receiver primaire des commandes.

* Un endpoint d’établissement est prioritaire sur un endpoint d’organisation pour le même événement.
* En l’absence d’observateur d’établissement abonné, les observateurs d’organisation servent de fallback.
* Le receiver primaire effectif est celui de l’établissement s’il existe, sinon celui de l’organisation.
* Exactement un receiver primaire reçoit chaque événement de commande pour un établissement.
* Une intégration POS synchrone et un receiver API peuvent être actifs simultanément. Chataigne envoie les événements de commande aux deux ; les opérateurs du restaurant doivent configurer leurs systèmes destinataires afin de ne pas créer de commandes opérationnelles en double.
* Des endpoints observateurs peuvent s’abonner en parallèle pour l’analytics et d’autres usages non opérationnels.

## Enveloppe d’événement

```json theme={null}
{
  "id": "evt_01J...",
  "object": "event",
  "type": "order.created",
  "api_version": "v1",
  "created_at": "2026-08-07T10:00:00.000Z",
  "data": {
    "object": {
      "id": "order_01J...",
      "object": "order",
      "short_id": "A-042",
      "status": "received",
      "status_version": 0
    }
  }
}
```

Dédupliquez avec l’`id` de l’événement, pas celui de la commande. Stockez l’identifiant avant d’appliquer vos effets, puis retournez n’importe quelle réponse `2xx`. Une nouvelle livraison du même événement doit être sans effet.

## Vérification de la signature

Chaque requête contient :

* `Chataigne-Event-Id`
* `Chataigne-Timestamp` en secondes Unix
* `Chataigne-Signature: v1=<HMAC hexadécimal>`

Calculez un HMAC-SHA256 avec le secret de l’endpoint sur les octets UTF-8 exacts :

```text theme={null}
Chataigne-Timestamp + "." + raw_request_body
```

Comparez le digest hexadécimal avec une fonction en temps constant. Rejetez les timestamps hors de votre fenêtre anti-rejeu, puis dédupliquez `Chataigne-Event-Id`. Vérifiez toujours le body brut avant de parser le JSON ; une nouvelle sérialisation modifie la signature.

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

export function verifyWebhook({ secret, timestamp, rawBody, signature }) {
  const expected = `v1=${createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')}`;
  const received = Buffer.from(signature);
  const wanted = Buffer.from(expected);
  return received.length === wanted.length && timingSafeEqual(received, wanted);
}
```

<Warning>
  Le secret de signature est affiché une seule fois à la création ou à la rotation. Stockez-le dans
  un gestionnaire de secrets. Une rotation invalide immédiatement le secret précédent.
</Warning>

## Livraison et retries

La livraison est au moins une fois. Chataigne considère tout `2xx` comme un succès. Les réponses HTTP `408`, `425`, `429`, `5xx`, les timeouts et les erreurs réseau sont retentés jusqu’à sept fois avec un backoff exponentiel commençant à cinq secondes. Les autres réponses `4xx` sont terminales.

Le processus durable de récupération remet en file les livraisons en attente et libère les traitements bloqués depuis deux minutes. Un échec terminal apparaît dans le journal de livraison et déclenche une alerte opérationnelle ; il n’annule ni ne rembourse jamais la commande automatiquement.

Utilisez le dashboard pour envoyer un événement de test synthétique, inspecter les tentatives, faire tourner un secret, désactiver un endpoint ou relancer manuellement un échec terminal. Répondre `2xx` signifie « reçu », pas « accepté » ; envoyez séparément un statut lorsque le POS a pris sa décision métier.

## Sécurité et rétention

En production, les URLs doivent utiliser HTTPS. Chataigne ne suit pas les redirects et valide la destination résolue au moment de la connexion afin de rejeter les adresses loopback, link-local, privées, réservées et les réseaux de métadonnées.

Les payloads peuvent contenir les coordonnées et l’adresse du client. Les payloads terminaux sont caviardés après sept jours et les enregistrements d’événements terminaux sont supprimés après 30 jours. Un effacement client caviarde immédiatement les payloads conservés et annule toute livraison qui n’a pas encore été réclamée pour traitement. Ne gardez votre copie que pendant la durée requise par votre contrat et le droit applicable.
