Nous contacter
contact@evolyon.fr
Tel: 04 37 57 38 97

Webhooks WordPress : comment automatiser les échanges avec vos outils ?

Webhooks WordPress

Lorsqu’un événement se produit dans WordPress, une autre application a parfois besoin d’en être informée immédiatement. Une commande vient d’être validée, un contenu est publié, un formulaire reçoit une demande ou une donnée métier change : attendre qu’un système externe interroge régulièrement WordPress crée des échanges inutiles et introduit un délai.

Les webhooks WordPress répondent à cette problématique. Leur principe consiste à déclencher automatiquement une requête HTTP lorsqu’un événement précis survient. WordPress devient alors capable d’avertir un CRM, un ERP, une application métier ou un service externe dès qu’une information mérite d’être transmise.

Cette logique complète naturellement l’API REST et s’inscrit dans de nombreux projets de développement WordPress. Une API répond généralement à une demande ; un webhook prend l’initiative de signaler l’événement. Les deux mécanismes forment ainsi une base efficace pour automatiser les échanges entre WordPress et les outils qui entourent le site.

Comprendre le fonctionnement des webhooks WordPress

Un webhook repose sur une logique événementielle : un événement survient dans WordPress, puis une information est transmise au système concerné. La compréhension du mécanisme commence par sa différence avec une API REST classique et par le rôle des hooks WordPress.

Le principe d’un webhook

Un webhook est une notification HTTP envoyée automatiquement vers une URL lorsqu’un événement défini se produit. Prenons une boutique qui reçoit une nouvelle commande : au lieu qu’un logiciel logistique interroge régulièrement WooCommerce pour vérifier si une commande est apparue, la boutique lui envoie immédiatement une requête contenant les informations nécessaires.

Le fonctionnement suit généralement la même séquence : un événement survient dans WordPress, une fonction prépare les données à transmettre, une requête HTTP est envoyée vers une URL de destination et le serveur distant retourne une réponse indiquant le résultat du traitement. Le webhook transforme ainsi un événement interne en message exploitable par un autre système.

Webhook et API REST : deux mécanismes complémentaires

API REST et webhook interviennent souvent dans la même intégration, mais leur logique de déclenchement diffère. Avec une API REST, le système consommateur initie généralement l’échange : il demande une ressource et WordPress lui répond. Avec un webhook, WordPress initie la communication dès que l’événement attendu se produit.

Cette différence change l’architecture. Une API régulièrement interrogée fonctionne selon une logique de polling : plus l’intervalle entre les requêtes diminue, plus le nombre d’appels augmente, même lorsqu’aucune donnée n’a changé. Le webhook adopte au contraire une logique événementielle et ne déclenche aucun échange tant que rien ne se produit.

Les deux mécanismes restent complémentaires. Un webhook transmet parfois uniquement un identifiant et le type d’événement ; le système destinataire interroge ensuite l’API REST WordPress pour récupérer la ressource complète. Cette séparation devient particulièrement intéressante lorsque les données évoluent souvent ou lorsqu’une synchronisation rapide compte davantage qu’une interrogation périodique.

Le rôle des hooks WordPress

Le cœur de WordPress ne propose pas d’interface générique permettant de créer des webhooks de la même manière que WooCommerce. Il fournit en revanche toutes les briques nécessaires pour en développer : son système de hooks détecte les événements, son API HTTP envoie des requêtes vers des services distants et l’API REST crée des endpoints capables de recevoir des notifications externes.

Les actions WordPress constituent généralement le point de départ d’un webhook sortant. Une action exécute une fonction lorsqu’un événement précis du cycle de WordPress survient. Elle n’est donc pas elle-même un webhook : elle représente l’événement interne auquel le développement rattache l’envoi de la requête externe.

Les événements qui déclenchent un webhook WordPress

Le nombre d’événements disponibles dépend du cœur de WordPress et des extensions installées. Une publication, une modification de contenu, la création d’un utilisateur ou différentes étapes du fonctionnement du CMS exposent des actions auxquelles un développement personnalisé s’abonne avec add_action().

Un plugin ajoute également ses propres hooks. WordPress recommande d’ailleurs aux extensions de fournir des hooks personnalisés lorsque d’autres développements doivent interagir avec leur fonctionnement.

WooCommerce pousse cette logique beaucoup plus loin. Ses webhooks natifs réagissent notamment aux événements liés aux commandes, produits, clients ou coupons. Le choix du déclencheur reste essentiel : un événement trop général provoque des notifications inutiles, tandis qu’un hook précisément aligné sur le besoin réduit les échanges et simplifie le traitement côté destinataire.

Envoyer un webhook depuis WordPress

L’émission d’un webhook commence par un événement WordPress et se concrétise par l’envoi d’un payload vers le service distant. Sa structure et son identifiant conditionnent ensuite la fiabilité du traitement côté destinataire.

Créer et envoyer le webhook

Un webhook personnalisé associe généralement une action WordPress à une requête HTTP. Imaginons un type de contenu project : lorsqu’un projet est publié pour la première fois, WordPress doit prévenir une application externe.

add_action(
	'transition_post_status',
	'evlyn_project_published_webhook',
	10,
	3
);

function evlyn_project_published_webhook(
	$new_status,
	$old_status,
	$post
) {
	if (
		'project' !== $post->post_type ||
		'publish' !== $new_status ||
		'publish' === $old_status
	) {
		return;
	}

	$payload = wp_json_encode(
		array(
			'event'      => 'project.published',
			'project_id' => $post->ID,
			'title'      => get_the_title( $post ),
			'url'        => get_permalink( $post ),
		)
	);

	$response = wp_remote_post(
		EVLYN_WEBHOOK_URL,
		array(
			'headers' => array(
				'Content-Type' => 'application/json',
			),
			'body'    => $payload,
			'timeout' => 5,
		)
	);

	if ( is_wp_error( $response ) ) {
		// Journaliser l’échec.
		return;
	}

	$status_code = wp_remote_retrieve_response_code(
		$response
	);
}

WordPress fournit son HTTP API précisément pour effectuer ce type de requête. wp_remote_post() envoie une requête POST et retourne la réponse distante, tandis que des fonctions dédiées extraient ensuite son code HTTP, son corps ou ses en-têtes. Cette abstraction évite d’introduire directement une dépendance à cURL ou à une autre bibliothèque HTTP.

Construire le payload

Le payload représente les données transmises au destinataire. Une intégration gagne à limiter ce contenu aux informations réellement utiles : envoyer l’intégralité d’un objet WordPress alors que le destinataire n’utilise que son identifiant, son statut et sa date augmente inutilement le volume échangé et expose davantage de données.

{
  "event": "project.published",
  "event_id": "evt_8f32c1",
  "created_at": "2026-08-26T09:30:00+02:00",
  "data": {
    "project_id": 42,
    "title": "Projet exemple"
  }
}

Le champ event indique ce qui vient de se produire, event_id identifie de manière unique la notification et la date facilite la traçabilité. L’objet data contient les informations métier. Cette structure devient particulièrement utile dès qu’un même endpoint reçoit plusieurs types de webhooks.

Identifier chaque événement de manière unique

Une livraison de webhook n’équivaut pas nécessairement à une exécution unique. Un système peut renvoyer une notification lorsque la première tentative échoue ou lorsque sa réponse arrive trop tard. Le destinataire reçoit alors éventuellement plusieurs fois le même événement.

Cette caractéristique introduit une notion fondamentale : l’idempotence. Le traitement d’un même événement deux fois ne doit pas entraîner deux opérations métier lorsque le scénario n’en prévoit qu’une. Un identifiant unique permet au système destinataire de mémoriser les événements déjà traités et d’ignorer les duplications.

Sécuriser et fiabiliser les webhooks sortants

Un webhook sortant fiable exige davantage qu’un simple appel HTTP. La sécurité de l’échange s’appuie sur une signature vérifiable, tandis que l’asynchronisme et les retries renforcent sa robustesse en cas d’échec.

Signer et authentifier les webhooks sortants

Une URL HTTPS protège la connexion pendant le transport, mais elle n’indique pas à elle seule au destinataire qui a réellement envoyé la requête. Une pratique courante consiste à partager un secret entre les deux systèmes et à calculer une signature HMAC à partir du contenu envoyé.

$signature = hash_hmac(
	'sha256',
	$payload,
	EVLYN_WEBHOOK_SECRET
);

$response = wp_remote_post(
	EVLYN_WEBHOOK_URL,
	array(
		'headers' => array(
			'Content-Type'        => 'application/json',
			'X-Webhook-Signature' => $signature,
		),
		'body' => $payload,
	)
);

Le serveur distant recalcule la signature à partir du corps réellement reçu et du même secret. Si les valeurs correspondent, il dispose d’un signal fort indiquant que le message provient du système attendu et que son contenu n’a pas été modifié. WooCommerce utilise cette logique pour ses webhooks, tandis que GitHub documente également la validation HMAC-SHA256 et recommande une comparaison en temps constant.

Choisir entre wp_remote_post() et wp_safe_remote_post()

Les deux fonctions envoient une requête HTTP POST, mais wp_safe_remote_post() ajoute une validation destinée aux URL dont l’origine n’est pas entièrement maîtrisée. WordPress recommande cette variante lorsque la destination provient d’une saisie utilisateur ou d’une valeur potentiellement contrôlée à l’extérieur du code.

La fonction wp_safe_remote_post() valide notamment les URL et leurs redirections afin de réduire le risque de Server-Side Request Forgery, ou SSRF. Une intégration où l’URL de destination est enregistrée dans une interface d’administration mérite donc une attention particulière sur ce point.

Découpler l’envoi de la requête WordPress

Un appel HTTP prend du temps. Si l’envoi intervient directement pendant l’enregistrement d’un contenu ou une action utilisateur, la réponse du service distant influence potentiellement la durée de la requête WordPress. Une destination lente entraîne alors une expérience plus lente côté utilisateur.

Pour une intégration simple et peu fréquente, un timeout court et un service distant fiable restent gérables. Les systèmes plus importants gagnent toutefois à séparer l’événement WordPress de la livraison effective : l’action déclenche la création d’une tâche, puis un traitement en arrière-plan effectue l’appel HTTP et gère les éventuelles nouvelles tentatives.

WooCommerce adopte justement cette logique pour ses propres webhooks : leur livraison est traitée en arrière-plan. Cette séparation améliore la résilience de l’intégration et évite qu’un système externe ralentisse directement une action réalisée dans WordPress.

Gérer les échecs et les retries

Une requête réseau peut échouer pour de nombreuses raisons : serveur temporairement indisponible, timeout, erreur DNS, problème TLS ou réponse applicative incorrecte. Le développement commence donc par distinguer une erreur de transport d’une réponse HTTP valide.

if ( is_wp_error( $response ) ) {
	// Échec réseau.
	return;
}

$status_code = wp_remote_retrieve_response_code(
	$response
);

if ( $status_code < 200 || $status_code >= 300 ) {
	// Le serveur a répondu, mais le traitement
	// n’a pas abouti comme attendu.
}

Il n’existe pas une politique universelle de retry applicable à tous les webhooks. Une intégration personnalisée WordPress définit explicitement son comportement : nombre de tentatives, délai entre les essais, erreurs qui justifient une nouvelle tentative et mécanisme de désactivation lorsqu’une destination reste durablement indisponible.

WooCommerce considère certaines réponses comme des livraisons réussies et désactive un webhook après plusieurs échecs consécutifs. À l’inverse, certains fournisseurs n’effectuent pas automatiquement toutes les nouvelles tentatives. La politique de reprise appartient donc au contrat technique de l’intégration.

Recevoir et valider un webhook dans WordPress

La réception inverse la logique : WordPress devient le point d’entrée d’un événement provenant d’un service externe. Le traitement authentifie alors l’émetteur, écarte les requêtes rejouées et répond rapidement avant de lancer les opérations plus longues.

Créer un point de réception dans WordPress

WordPress fonctionne également comme destinataire. Un CRM, un outil de paiement ou une application métier envoie alors une requête vers une URL WordPress lorsque son propre événement survient. L’API REST fournit une manière naturelle de créer cette URL de réception.

add_action(
	'rest_api_init',
	function () {
		register_rest_route(
			'evolyon/v1',
			'/webhook',
			array(
				'methods'             => 'POST',
				'callback'            => 'evlyn_receive_webhook',
				'permission_callback' => 'evlyn_verify_webhook',
			)
		);
	}
);

L’endpoint devient alors accessible sous une URL du type suivant :

https://example.com/wp-json/evolyon/v1/webhook

WordPress impose aujourd’hui un permission_callback lors de l’enregistrement d’une route REST. La documentation de register_rest_route() détaille cette contrainte. Dans un récepteur de webhook, cette fonction constitue un emplacement pertinent pour vérifier l’autorisation ou l’authenticité de la requête avant le traitement métier.

Vérifier la signature du webhook reçu

La signature doit être calculée sur le corps brut de la requête, avant toute transformation susceptible de modifier son contenu. Prenons un système utilisant un en-tête X-Webhook-Signature et un HMAC SHA-256.

function evlyn_verify_webhook(
	WP_REST_Request $request
) {
	$signature = $request->get_header(
		'x-webhook-signature'
	);

	if ( ! $signature ) {
		return new WP_Error(
			'missing_signature',
			'Signature absente.',
			array( 'status' => 401 )
		);
	}

	$expected = hash_hmac(
		'sha256',
		$request->get_body(),
		EVLYN_WEBHOOK_SECRET
	);

	if ( ! hash_equals( $expected, $signature ) ) {
		return new WP_Error(
			'invalid_signature',
			'Signature invalide.',
			array( 'status' => 401 )
		);
	}

	return true;
}

hash_equals() réalise une comparaison adaptée à ce type de données sensibles. Une fois la signature validée, le callback principal récupère le JSON, applique les validations métier puis retourne rapidement une réponse.

function evlyn_receive_webhook(
	WP_REST_Request $request
) {
	$data = $request->get_json_params();

	// Vérification et traitement métier.

	return rest_ensure_response(
		array(
			'received' => true,
		)
	);
}

Les détails de signature varient selon chaque fournisseur. L’intégration respecte toujours le format exact défini par le système émetteur : nom d’en-tête, algorithme, représentation de la signature et éventuelle inclusion d’un timestamp.

Se protéger contre le rejeu d’un ancien webhook

Une signature valide indique qu’un message a été signé avec la bonne clé. Elle ne garantit pas nécessairement que le message vient d’être envoyé. Un attaquant ayant intercepté une requête valide pourrait tenter de la retransmettre.

Les implémentations les plus robustes associent donc la signature à un timestamp et refusent les messages trop anciens. L’identifiant unique de l’événement complète ce mécanisme en empêchant son traitement répété : le timestamp limite la fenêtre de rejeu et l’idempotence bloque une seconde exécution du même événement.

Accuser réception rapidement et traiter en arrière-plan

Le serveur émetteur attend généralement une réponse rapide. Une opération longue effectuée directement dans le callback augmente le risque de timeout. Le fournisseur croit alors que la livraison a échoué et déclenche éventuellement une nouvelle tentative, alors que WordPress poursuit encore le traitement initial.

Une bonne architecture sépare donc fréquemment réception et traitement métier. WordPress vérifie la signature, valide la structure minimale du payload, enregistre ou programme la tâche nécessaire puis retourne rapidement une réponse de succès. Le traitement lourd s’effectue ensuite en arrière-plan, ce qui facilite également les retries internes et la traçabilité.

Cas d’usage et intégrations

Les webhooks prennent tout leur intérêt lorsqu’un changement dans WordPress déclenche une action immédiate dans un autre outil, ou inversement. Les cas d’usage montrent comment ce modèle s’intègre aux échanges métier et aux fonctionnalités WooCommerce.

Les principaux cas d’usage

Les scénarios se multiplient dès que WordPress fait partie d’un système d’information plus large. Une boutique WooCommerce transmet une nouvelle commande à un logiciel logistique. Un formulaire crée un événement qui rejoint un CRM. Une publication déclenche une purge de cache ou une mise à jour dans un moteur externe. Un outil métier informe WordPress qu’un dossier a changé de statut.

Dans ces situations, le webhook évite une interrogation permanente des systèmes et rapproche la synchronisation du temps réel. Le choix entre API, webhook ou combinaison des deux dépend ensuite du volume de données, de la fréquence des événements et des responsabilités attribuées à chaque application.

Les webhooks WooCommerce

WooCommerce fournit une implémentation complète directement dans son administration. La boutique configure un nom, un statut, un sujet, une URL de livraison et un secret. Les événements standards couvrent notamment la création, la mise à jour ou la suppression de commandes, produits, clients et coupons ; des actions WooCommerce servent également de déclencheurs personnalisés.

WooCommerce journalise aussi les livraisons, ce qui facilite le diagnostic des échanges avec un système externe. Cette fonctionnalité illustre bien la différence entre WordPress et son écosystème : WordPress fournit les primitives techniques, tandis qu’une extension comme WooCommerce construit par-dessus une véritable interface de gestion des webhooks.

Diagnostiquer et superviser les échanges

Une intégration webhook doit rester observable une fois en production. Des logs exploitables et une méthode de diagnostic structurée facilitent l’identification des erreurs de transport, d’authentification ou de traitement.

Diagnostiquer un webhook qui ne fonctionne pas

Le diagnostic gagne à suivre le parcours complet de l’événement. La première question concerne le déclencheur : l’action WordPress attendue s’est-elle réellement produite ? Vient ensuite la construction du payload : les données correspondent-elles au format attendu ?

L’étape suivante examine l’envoi. La requête HTTP est-elle partie et WordPress a-t-il retourné un WP_Error ? Le code HTTP du serveur distant fournit ensuite une indication essentielle : une réponse 2xx traduit généralement une requête acceptée, tandis que les réponses 4xx ou 5xx orientent vers une erreur côté requête ou serveur.

Enfin, les journaux des deux systèmes permettent de rapprocher l’heure, l’identifiant d’événement et la réponse associée. Une intégration destinée à la production mérite donc une journalisation exploitable dès sa conception.

Structurer des logs réellement exploitables

Un journal utile conserve suffisamment d’informations pour reconstituer une livraison sans transformer les logs en copie permanente de données sensibles. L’identifiant de l’événement, son type, la destination, la date, le nombre de tentatives et le code HTTP constituent généralement des informations utiles au diagnostic.

Les secrets, mots de passe, tokens et signatures complètes n’ont aucune raison d’apparaître en clair dans ces journaux. Les payloads contenant des données personnelles méritent également une politique de conservation adaptée au projet.

Choisir la bonne architecture d’intégration

Le webhook constitue une option parmi plusieurs mécanismes d’intégration. Le choix dépend de la fréquence des échanges, du besoin de temps réel et de la capacité des systèmes à gérer les échecs sans créer de doublons.

Webhook ou synchronisation périodique : choisir selon le besoin

Le webhook devient particulièrement pertinent lorsque la donnée doit circuler peu après l’événement et que les périodes sans changement sont fréquentes. Une synchronisation périodique conserve néanmoins son intérêt lorsque le système distant ne sait pas recevoir de notifications, lorsque les données nécessitent régulièrement une réconciliation complète ou lorsqu’un contrôle périodique sert de mécanisme de sécurité.

Les architectures les plus robustes combinent parfois les deux. Le webhook assure la rapidité des échanges courants, tandis qu’une synchronisation planifiée vérifie périodiquement que les systèmes restent cohérents. Cette stratégie évite qu’une notification exceptionnellement perdue crée un écart permanent entre les bases.

Construire des webhooks WordPress fiables

Envoyer une requête POST depuis WordPress tient en quelques lignes de PHP. Construire une intégration exploitable dans la durée demande davantage de réflexion : le déclencheur correspond exactement à l’événement métier, le payload reste explicite et versionnable, chaque livraison reçoit un identifiant et la signature protège l’authenticité du message.

Les erreurs disposent d’une stratégie de reprise et le traitement long quitte le chemin de la requête utilisateur. Lorsqu’il reçoit des webhooks, WordPress applique la même rigueur : validation de la signature, contrôle du payload, idempotence et réponse rapide.

C’est cette logique qui transforme un simple échange HTTP en véritable API & intégration WordPress. Les webhooks deviennent alors une composante fiable du dialogue entre WordPress et les outils qui entourent le site.

Votre site WordPress mérite une évolution maîtrisée

Besoin d'un développement WordPress spécifique ?

Vous souhaitez ajouter une fonctionnalité, adapter un parcours, connecter un outil ou faire évoluer votre site WordPress ? Evolyon vous aide à préciser votre besoin et à identifier la solution technique la plus adaptée.

Prestations de développement WordPress de l'agence Evolyon

Nos conseils pour développer avec WordPress

API et intégration WordPress
API REST WordPress

API REST WordPress : fonctionnement, endpoints et cas d’usage