lomi.

Fiabilité des webhooks

Nouvelles tentatives, idempotence, journaux de livraison et traitement sûr des doublons.

Les intégrations de production doivent supposer une livraison au moins une fois : le même événement logique peut arriver plusieurs fois. Ce guide complète Recevoir les webhooks sur le plan opérationnel.

Répondre vite, traiter en asynchrone

Les webhooks sont de simples requêtes HTTP `POST`. Dans le chemin critique, votre handler a un rôle étroit : vérifier la charge (signature), enregistrer ou mettre en file le minimum pour ne rien perdre, puis répondre un succès HTTP à lomi sans attendre le reste du flux métier.

Renvoyez un 2xx tout de suite après vérification de la signature et après la persistance minimale qui vous garantit de pouvoir traiter l’événement ensuite. Le travail lourd passe par votre file d’attente. Si vous bloquez sur des API tierces, de grosses transactions SQL ou des règles séquentielles avant de répondre, vous risquez de dépasser le délai de lecture HTTP sortant de lomi (environ quatre secondes par tentative, voir ci-dessous). Viser une réponse HTTP courante nettement sous une seconde laisse une marge pour les pics et les démarrages à froid.

Traitement idempotent

Servez-vous d’un identifiant d’enveloppe d’événement stable ou d’un couple (type d’événement, identifiant métier canonique) pour détecter les doublons :

  • Si l’événement est déjà appliqué, ignorez ou faites un no-op.
  • Sans stockage des identifiants traités, n’assumez pas une livraison « exactement une fois ».

Cela reflète les schémas côté serveur où les métadonnées sont fusionnées et les soldes vérifient des drapeaux déjà traités.

Nouvelles tentatives et journaux

Pour le débogage opérationnel, on commence presque toujours par ce que lomi a observé sur le fil. Le code de réponse visible par lomi, un extrait du corps et les durées sont consignés dans les journaux de livraison webhook (tableau de bord ou API Webhooks). Servez-vous‑en pour :

  • confirmer un code non 2xx
  • analyser latence et taille du corps
  • déboguer signature ou parsing

Des tentatives répétées en 401 Unauthorized (corps du type « Authentication required ») signifient souvent que votre serveur ou CDN a refusé le POST avant le code webhook — les livraisons sortantes n’incluent pas d’auth Bearer / clé API ; voir Secret de signature et Authorization.

Délais, nouvelles tentatives et erreurs client

Les sous-sections qui suivent résument le comportement actuel du client webhook NestJS (WebhookSenderService, `apps/api/src/webhooks/webhook-sender.service.ts`). Elles permettent aux intégrateurs de raisonner sur délais, relances et erreurs client non renouvelables sans lire le code source. Le comportement produit peut évoluer ; en cas de doute, les journaux de livraison et une consommation idempotente font foi.

Délai d’attente HTTP par tentative

Le client webhook de lomi attend environ 4 secondes (`timeout: 4000` ms par requête) la fin de la réponse HTTP de votre serveur.

  • Envoyez 200 / 204 tout de suite après vérification de `X-Lomi-Signature` (nettement sous ~1 s), puis faites suivre la logique métier par votre file.
  • Au-delà de ~4 s, la tentative échoue côté lomi (timeout) et peut faire l’objet d’une relance selon les règles ci-dessous.

Relances ou pas

Résumé des cas (`sendWebhookWithContext` côté API) :

RésultatNouvel essai HTTP ?
2xxNon — livré
Erreurs client 4xx (400499, y compris 401)Non (« erreur client non renouvelable ») pour ce flux
5xx ou erreurs transitoires / réseauOui — sous plafonds et backoff exponentiel

En pratique : corrigez configuration et auth (souvent visibles en 4xx) avant d’attendre une guérison automatique — lomi ne force pas indéfiniment une URL mal réglée.

Deux chemins de livraison → deux plafonds

  1. Livraison synchrone groupée (`notifyOrganization` → boucle `sendWebhook` traditionnelle) : jusqu’à quatre envois HTTP en cas d’échecs réessayables, délai exponentiel depuis environ 3 secondes.
  2. File d’attente (worker BullMQ, outbox / liste d’organisations via variables d’environnement) : jusqu’à cinq tentatives par job, backoff exponentiel avec délai initial de 5 secondes entre deux exécutions du job.

Les drapeaux opérationnels (`WEBHOOK_OUTBOX_ENABLED`, `WEBHOOK_OUTBOX_CANARY_ORG_IDS`) basculent certaines organisations vers le pipeline dispatch/outbox ; les deux chemins gardent environ 4 secondes maximum par POST HTTP.

Vous n’avez pas à distinguer ces chemins dans votre handler : acceptez toujours les livraisons de façon idempotente. Connaître la différence aide surtout lors de la lecture des journaux ou pour estimer combien de temps une panne transitoire peut générer de nouvelles tentatives.

Enveloppe JSON (`lomi_environment`)

Le champ lomi_environment reprend NODE_ENV de l’hôte qui envoie (`production`, `development`, etc.) — ce n’est pas un indicateur produit bac à sable / live distinct du couple URL + clés que vous utilisez vous-même.

Vérification de signature

Utilisez les octets bruts du corps. Un JSON resérialisé peut casser le HMAC. Détails : Recevoir les webhooks et Intégration API.

Test et live

Secrets et URLs webhook sont propres à l’environnement. Faites monter vos configurations progressivement pour qu’aucun secret ou URL de test ne reçoive du trafic live.

Référence API associée

Sur cette page