Skip to main content
Les webhooks envoient des requêtes HTTP POST à l’URL configurée dans Paramètres → Intégrations → Webhooks. Leur secret de signature est distinct des clés API. Aucun jeton Bearer ni scope WEBHOOKS_WRITE n’est requis pour les recevoir ; aucune route publique v1 ne gère leur configuration.

Événements et couverture

Une configuration active reçoit uniquement les événements sélectionnés. Une annulation change le statut, sans supprimer la réservation : recherchez CANCELED_BY_USER ou CANCELED_BY_RESTAURANT dans une modification si le parcours concerné en émet une. Il n’existe pas d’événement d’annulation distinct.
Ces événements ne couvrent pas toutes les modifications. Certains parcours des équipes sur les réservations et les tables, ainsi que des changements automatiques de statut ou d’affectation, en émettent. Les écritures par API partenaire et les parcours du portail de réservation n’émettent pas directement ces webhooks. Une modification automatique ultérieure peut produire un événement sans création préalable. N’en faites pas l’unique source d’une synchronisation exhaustive.

En-têtes

Ne remplacez pas ces en-têtes dans la configuration personnalisée. La signature porte sur le corps brut uniquement, sans préfixer le timestamp de l’en-tête.

Payload

Exemple de création avec des identifiants et dates illustratifs :
La réservation contient toujours id, restaurantId, status, group_size, reservation_date, reservation_time, created_at, updated_at, source, tags et metadata (qui peut valoir null). Ce format diffère de l’API partenaire : group_size et date/heure séparées remplacent party_size et start_at. reservation_date représente le jour de service du restaurant, normalement sérialisé à minuit ISO. Conservez sa partie YYYY-MM-DD ; ne convertissez pas ce minuit UTC vers un autre fuseau pour en déduire le jour. reservation_time est une heure locale HH:mm. Ne traitez pas cette paire comme un instant UTC. created_at, updated_at et timestamp sont des instants UTC. Les champs facultatifs dépendent de la réservation :
  • customer : identifiant, external_id nullable, nom et coordonnées/langue disponibles.
  • tables : objets id et name, sans salle imbriquée.
  • room : id et name multilingue, pas une simple chaîne.
  • waiter : id et name.
  • payments : id, amount, currency, status, provider, provider_id facultatif et created_at.
  • custom_message, allergies et total_amount_paid : omis lorsqu’ils sont vides ou à zéro par le transformateur actuel. Une absence ne signifie pas « inchangé ».
  • shift : peut apparaître dans le test ; les événements ordinaires l’omettent actuellement. N’exigez pas ce champ.
Les messages peuvent contenir des données personnelles et de paiement, quels que soient les scopes d’une clé API. Limitez l’accès aux corps et aux secrets, et évitez la journalisation des payloads complets.

Vérifier la signature

Calculez HMAC-SHA256 sur les octets exacts reçus, avec le secret du webhook. Rejetez une signature absente ou malformée, puis comparez les condensats en temps constant. Décodez le JSON uniquement après vérification : le reconstruire peut modifier les espaces ou l’ordre des champs et invalider une signature légitime.

Exemple de récepteur Express

Enregistrez la fonction Node.js dans verify-signature.js. Déclarez la route avec corps brut avant tout middleware express.json(). Cet exemple vérifie et journalise uniquement les identifiants : remplacez ce traitement de démonstration par votre traitement métier avant d’acquitter un événement en production. Chargez le secret depuis un stockage serveur sécurisé, sans le committer.

Livraison et reprises

  • Renvoyez 2xx dans le délai configuré après traitement réussi ou prise en charge durable. Le délai vaut 5 000 ms par défaut, réglable de 1 000 à 30 000 ms.
  • Une erreur réseau ou un timeout qui lève une exception déclenche la politique de reprise : 5 tentatives au total au maximum, délai exponentiel de facteur 2, borné entre 1 et 10 secondes. Ces réglages ne garantissent pas un horaire précis.
  • Les réponses HTTP 4xx et 5xx ne déclenchent actuellement pas ces reprises. Elles sont retournées comme résultat en échec sans lever d’erreur de tâche.
  • L’ordre et l’unicité de livraison ne sont pas garantis. Une reprise conserve le corps et l’id ; plusieurs destinataires peuvent recevoir ce même identifiant. Utilisez (restaurant_id, id) pour repérer un événement déjà traité, par intégration si plusieurs destinations sont traitées indépendamment.
  • Les paramètres n’offrent ni journal de livraison ni commande de rejeu. Il n’existe pas d’API publique de rejeu.
Une réponse perdue peut provoquer une reprise après votre traitement. Évitez de répéter une action métier pour un identifiant déjà traité. La signature authentifie le corps ; elle ne protège pas à elle seule contre le rejeu.

Tester et diagnostiquer

Tester envoie réellement et de façon synchrone un RESERVATION_CREATED fictif, sans créer de réservation. L’exemple utilise une date de service fixe (2025-12-25, sans heure) et inclut un shift, contrairement aux événements ordinaires. Il ne teste ni la tâche d’arrière-plan ni ses reprises. En cas de signature invalide, contrôlez le secret, les octets bruts, l’ordre des middlewares et les en-têtes personnalisés. Après régénération du secret, mettez à jour le récepteur. Des envois déjà programmés peuvent encore utiliser l’ancien. Pour un événement absent, contrôlez activation, sélection, couverture des parcours, URL, statut HTTP et délai d’attente. Transmettez au support le restaurant, le nom du webhook, l’identifiant d’événement si disponible, l’heure et le statut HTTP, jamais le secret.