Automatisation

Webhooks : signature, idempotence et reprise sur erreur

Mis à jour le

Recevoir un webhook correctement tient à trois règles : vérifier la signature avant de lire le contenu, répondre rapidement par un code 2xx, et traiter chaque événement de manière idempotente, car il peut arriver plusieurs fois ou dans le désordre.

Vérifier la signature sur le corps brut

Un point d'entrée de webhook est une URL publique : n'importe qui peut y envoyer une requête. Le fournisseur signe donc chaque envoi, le plus souvent par un HMAC calculé sur le corps de la requête avec un secret partagé.

La vérification se fait sur le corps brut, octet pour octet : le reparser en JSON puis le resérialiser change la chaîne signée et fait échouer le contrôle. La comparaison doit s'effectuer en temps constant, et un horodatage signé permet de rejeter une requête ancienne rejouée par un tiers.

Acquitter vite, traiter ensuite

Le fournisseur attend une réponse en quelques secondes. Un code 2xx signifie « bien reçu » ; tout autre code, ou un délai dépassé, déclenche en général de nouvelles tentatives espacées dans le temps.

Répondez 400 à une signature invalide, 2xx dès que l'événement est authentifié et enregistré. Distinguez ensuite l'erreur passagère, pour laquelle une nouvelle tentative du fournisseur est utile, de l'erreur définitive : redemander un événement que vous ne saurez pas mieux traiter au deuxième essai ne fait que remplir les journaux.

Idempotence : le même événement arrivera deux fois

La livraison est garantie « au moins une fois », pas « exactement une fois ». Chaque événement porte un identifiant unique : conservez ceux déjà traités et ignorez les doublons, sinon un client recevra deux fois le même e-mail ou la même livraison.

L'ordre n'est pas garanti non plus. Plutôt que de se fier à la séquence d'arrivée, relisez l'état courant de la ressource auprès de l'API du fournisseur lorsque la décision en dépend.

En bref

Comment vérifier la signature d'un webhook ?

En recalculant le HMAC du corps brut de la requête avec le secret partagé, puis en le comparant en temps constant à la signature reçue en en-tête. Si elles diffèrent, la requête est rejetée sans être traitée.

Quel code HTTP renvoyer à un webhook ?

Un code 2xx dès que l'événement est authentifié et pris en charge. Un code d'erreur ou une absence de réponse amène généralement le fournisseur à renvoyer l'événement plus tard.

Pourquoi un webhook est-il reçu plusieurs fois ?

Parce que la livraison est garantie au moins une fois : si votre réponse se perd ou arrive trop tard, l'événement est renvoyé. Le traitement doit donc dédoublonner à partir de l'identifiant de l'événement.

Poursuivre dans le Lab