Configurer et sécuriser les webhooks

Configurer les webhooks dans la PSB : topics, sécurisation HMAC SHA256 et IP-whitelisting.

Les webhooks sont le moyen principal de recevoir des notifications en temps réel de la PSB. Lors de chaque événement pertinent (une facture reçue, un changement de statut, une confirmation de livraison), la PSB envoie une requête HTTP POST vers votre endpoint avec les détails de l'événement.

Comment fonctionnent les webhooks dans la PSB ?

Vous enregistrez un webhook (un "hook") dans la PSB avec une URL et un topic. La PSB envoie ensuite tous les événements de ce topic vers votre URL. Chaque événement contient les données pertinentes sous forme de payload JSON.

Créer un webhook

Pas d'interface disponible : il n'est actuellement pas possible de configurer un hook via l'interface utilisateur de la plateforme. Les hooks sont configurés via l'API ou via le support eConnect. Une interface self-service pour les hooks est prévue dans la feuille de route (planifiée pour le T4 2026) et fera partie de Control (Platform 2.0) : les utilisateurs pourront alors créer, modifier et supprimer des hooks eux-mêmes. D'ici là, aucun article pas-à-pas pour la configuration manuelle des hooks via l'API n'est prévu.

Enregistrez un hook via l'API :

POST /api/v1/hook

Les principaux éléments de configuration :

ChampDescriptionurlL'endpoint HTTPS vers lequel la PSB envoie les événementstopicLe type d'événement que vous souhaitez écouter (par ex. InvoiceReceived)secretUne clé secrète pour la vérification de signature HMAC

Attention : évitez de supprimer et recréer rapidement des hooks pour le même partyId et le même topic. En raison de race conditions dans le traitement des tâches, il peut arriver que temporairement aucun hook actif n'existe, ce qui empêche la livraison des événements. Attendez un instant après la suppression d'un hook avant d'en créer un nouveau, ou utilisez une mise à jour au lieu de supprimer puis recréer.

Ajouter un topic à un hook existant

Vous souhaitez ajouter un topic supplémentaire (par ex. InvoiceReceived) à un hook existant ? Mettez à jour la configuration webhook existante via l'API /hook habituelle afin que le topic souhaité figure dans le tableau topics :

{
  "topics": ["InvoiceReceived"]
}

Mettez à jour le hook existant plutôt que de le supprimer et de le recréer. Supprimer et recréer introduit une race condition où les événements peuvent ne pas être livrés temporairement (voir l'avertissement ci-dessus).

Pas en libre-service pour les clients non techniques. L'ajout d'un topic à un hook existant est une opération technique : la personne qui l'effectue doit savoir où le webhook doit pointer (l'URL de l'endpoint) et comprendre ce qu'est un webhook. Un client non technique ne peut généralement pas le faire de manière autonome. Faites appel à quelqu'un ayant des connaissances techniques (l'IT du client ou le support eConnect).

Topics fréquemment utilisés
TopicQuandInvoiceReceivedUne facture d'achat a été reçueInvoiceSentUne facture de vente a été envoyée avec succèsInvoiceSentErrorUne facture de vente n'a pas pu être livréeInvoiceSentRetryUne tentative de renvoi a été lancéeInvoiceResponseReceivedUne Invoice Response (messages de statut) a été reçueMessageLevelStatusReceivedUn message de statut MLS a été reçu de la partie expéditriceMessageLevelStatusSentUn message de statut MLS a été envoyé avec succèsOrderReceivedUn bon de commande a été reçu
Message Level Status (MLS)

Le MLS (Message Level Status) est le successeur de l'ancien MLR et fournit à la partie expéditrice un retour sur la réception et le traitement d'un document. Le MLS n'est pas activé par défaut et doit être configuré par party via la capability reviews dans la configuration SMP. Une fois le MLS activé, la PSB le gère automatiquement : en tant que Service Provider récepteur, la PSB renvoie un message MLS à l'expéditeur après réception et livraison.

Lorsque vous envoyez vous-même des documents via la PSB, vous recevez le retour MLS de la partie réceptrice sous forme d'événement webhook sur le topic MessageLevelStatusReceived. Le payload contient entre autres :

ChampDescriptiondocumentIdIdentifiant unique du message MLSrefToDocumentIdIdentifiant du document originaldetails.statusCodeStatut Peppol : AP (accepted), RE (rejected), AB (acknowledged)details.descriptionExplication du récepteur

Pour recevoir des messages MLS, le hook Peppol doit contenir le champ mlsType. Les valeurs possibles sont ALWAYS_SEND (toujours renvoyer un MLS) et FAILURE_ONLY (uniquement en cas de rejet).

Conseil : vous pouvez récupérer le document MLS complet via GET /api/v1-beta/{partyId}/generic/{documentId}/download, mais le payload du webhook contient généralement suffisamment d'informations.

Sécuriser les webhooks avec HMAC

La PSB sécurise toutes les livraisons de webhooks avec des signatures HMAC SHA256. À chaque requête, la PSB envoie le header :

X-EConnect-Signature: sha256={handtekening}
Implémenter la vérification

Pour vérifier la signature :

  1. Prenez le payload JSON brut de la requête.
  2. Calculez le hash HMAC SHA256 avec votre clé secrète (la même que celle spécifiée lors de la création du hook).
  3. Comparez votre hash calculé avec la valeur du header X-EConnect-Signature.
  4. S'ils correspondent, la requête est authentique.
Prévention des replay attacks

Vérifiez également le champ sentOn dans le payload. Si ce timestamp est antérieur de plus de 5 minutes, rejetez la requête. Cela prévient les replay attacks où une requête interceptée est rejouée ultérieurement.

Options de sécurité supplémentaires

En plus de la vérification HMAC, la PSB propose des couches de sécurité supplémentaires :

  • IP-whitelisting : limitez les requêtes entrantes aux IP de production de la PSB (104.40.188.59 et 104.47.148.207)
  • Authentification OAuth webhook : la PSB peut s'authentifier auprès de votre endpoint avec des credentials OAuth2
  • Mutual SSL : utilisez des certificats clients pour une authentification TLS mutuelle
Ordre de priorité

Si vous avez configuré plusieurs hooks, la PSB détermine quel hook utiliser selon :

  1. Les hooks au niveau PartyId ont priorité sur les hooks au niveau environment
  2. Les topics spécifiques ont priorité sur les wildcards
  3. Si plusieurs hooks avec des filtres correspondent au même topic : le filtre le plus long (en nombre de caractères) gagne -- par exemple, un filtre avec une clause && supplémentaire gagne sur un filtre plus court sans cette clause. Cela évite une double livraison sans obliger les filtres à s'exclure mutuellement.
  4. En cas de priorité égale : le hook-id sert de critère de départage
Résolution des problèmes

Voici les problèmes courants avec les webhooks et comment les résoudre.

SymptômeCauseSolutionLes webhooks n'arrivent pasEndpoint inaccessible (délai 100 sec.)HTTPS + certificat SSL valide requis ; désactiver la protection CSRF sur l'endpoint webhookWebhook rejeté comme non sécuriséLa validation X-EConnect-Signature échoueVérifier le calcul HMAC SHA256 : payload × secret → chaîne hexadécimale avec le préfixe sha256=Attaque par rejeu bloquéeLe champ sentOn est plus ancien que 5 minutesL'endpoint traite trop lentement ou l'horloge est mal réglée« No such host is known » (erreur DNS)Le nom d'hôte de l'endpoint webhook n'est plus résolvable, p. ex. après le renommage de l'environnement ERP ou l'expiration d'un enregistrement DNSVérifier et restaurer l'enregistrement DNS du domaine de l'endpoint ; puis récupérer les événements manqués via le endpoint batchHookSentError (échec définitif)Le PSB a réessayé pendant 5 jours sans réponse 2xxVérifier les journaux de l'endpoint ; surveiller le topic HookSentError (voir ci-dessous) ; récupérer les événements manqués via le endpoint batchAnciennes factures relivréesL'API ne renvoie pas 2xx à la première réceptionL'endpoint doit toujours renvoyer 2xx, même pour le traitement asynchroneTraitement en double lors d'un renouvellementPas de vérification d'idempotenceUtiliser le header X-EConnect-Delivery (UUID unique) pour la déduplication
Surveiller et récupérer depuis HookSentError

Le PSB envoie des événements webhook (p. ex. InvoiceReceived lors de la réception d'une facture électronique) à l'endpoint configuré. Si cet endpoint est inaccessible - en raison d'un délai d'attente, d'une erreur SSL ou d'une erreur DNS comme No such host is known - le PSB réessaie avec un recul exponentiel pendant 5 jours (délai 100 sec. par tentative). Chaque tentative génère un événement HookSentRetry ; après 5 jours sans réponse 2xx, HookSentError est émis comme statut final et le PSB cesse de réessayer.

Conséquence : une facture électronique reçue ne sera pas livrée au client tant que l'endpoint est inaccessible, sans que le client s'en aperçoive directement. Actions recommandées :

  • Mettre en place une surveillance : abonner un hook (p. ex. un mail-hook) au topic HookSentError afin qu'un échec de livraison définitif soit signalé activement plutôt que de passer inaperçu. Envisager également HookSentRetry pour une détection précoce.
  • Corriger la cause racine : en cas d'erreur DNS, vérifier et restaurer l'enregistrement DNS du domaine de l'endpoint ; en cas de délais, faire répondre l'endpoint plus rapidement (2xx en 100 sec., traitement lourd de manière asynchrone).
  • Récupérer les événements manqués : les événements échoués pendant l'interruption peuvent être récupérés via le endpoint batch. La fenêtre de 5 jours signifie qu'une réparation rapide dans ce délai peut encore rattraper la livraison normale.
Bonnes pratiques
  • Utilisez toujours HTTPS pour votre endpoint webhook
  • Implémentez un traitement idempotent : dans de rares cas, la PSB peut livrer un événement plusieurs fois
  • Retournez rapidement un code de statut 2xx : la PSB considère toute réponse non-2xx comme une erreur et réessaiera l'événement
  • Journalisez tous les événements reçus pour le débogage et l'audit
  • Utilisez un système de file d'attente (queue) de votre côté si le traitement prend du temps ; confirmez d'abord la réception, puis traitez ensuite
Questions fréquentes
Comment vérifier un webhook entrant avec HMAC SHA256 ?

Prenez le corps JSON brut de la requête, calculez le hash HMAC SHA256 avec le secret que vous avez indiqué lors de la création du hook et comparez-le avec la valeur dans le header X-EConnect-Signature (après le préfixe sha256=). Si les valeurs correspondent, vous savez que la requête provient de la PSB et n'a pas été modifiée en transit.

Pourquoi faut-il vérifier le champ sentOn dans le payload ?

Vérifiez que sentOn n'a pas plus de 5 minutes. Si l'horodatage est trop ancien, refusez la requête. Cela empêche les attaques par rejeu, où une requête interceptée est soumise à nouveau ultérieurement, même si la signature est techniquement valide.

Comment éviter les problèmes de traitement idempotent et de retries ?

Implémentez un traitement idempotent de votre côté, car la PSB peut dans de rares cas livrer un événement plusieurs fois. Retournez également rapidement un statut HTTP 2xx : toute autre réponse est considérée comme une erreur et déclenche un nouvel essai. Pour un traitement lourd, confirmez d'abord la réception, puis traitez via une file d'attente.


Vous préférez récupérer les documents en masse ? Consultez le batch hook.

Voir les endpoints webhook

En lien
Articles associés