Fiabilité des API et webhooks

Webhook WooCommerce déclenché plusieurs fois : empêcher les traitements en double sans perdre de véritables événements

Lorsqu’un webhook WooCommerce semble se déclencher deux fois, établissez d’abord ce qui s’est réellement répété. Protégez ensuite l’opération métier en aval par une idempotence atomique, un état durable et un rapprochement.

Un webhook WooCommerce atteint votre application.

Le récepteur crée une expédition, insère une fiche CRM, envoie un message au client ou lance l’exécution de la commande. Peu après, quelque chose qui ressemble au même événement arrive à nouveau.

Il y a désormais deux expéditions, deux fiches ou deux exécutions d’une opération qui ne devait avoir lieu qu’une fois.

Il est facile de parler de webhook en double. Cette description peut être correcte, mais ce n’est pas encore un diagnostic.

La commande a pu changer deux fois. Deux configurations actives peuvent viser le même point de terminaison. Une autre couche a pu rejouer une requête. Deux workers ont pu entrer en concurrence pour réserver la même opération. Le récepteur peut aussi avoir accepté correctement un webhook, puis dupliqué le travail dans sa propre file.

Avant de supprimer quoi que ce soit, identifiez la frontière où une opération prévue est devenue deux opérations.

La réponse courte

Ne dédupliquez pas les traitements de webhooks WooCommerce uniquement par identifiant de commande. Une commande peut connaître de nombreuses mises à jour légitimes.

X-WC-Webhook-Delivery-ID aide à suivre une livraison, mais n’identifie pas automatiquement l’opération métier que votre intégration doit protéger.

Un récepteur plus sûr remplit correctement quatre fonctions :

  • authentifier le webhook entrant
  • conserver assez d’éléments pour corréler les livraisons
  • déduire une clé d’idempotence de l’opération métier
  • réserver et suivre durablement l’opération avant de répéter un travail irréversible

Si l’issue de l’effet de bord externe est incertaine, effectuez un rapprochement avant de réessayer.

L’objectif pratique est simple :

Une livraison répétée ne doit pas répéter une opération métier irréversible, tandis que les véritables changements ultérieurs doivent toujours atteindre le système en aval.

Établir d’abord ce qui s’est réellement répété

Prenons un webhook order.updated pour la commande 18452.

Une minute plus tard, une autre requête order.updated arrive pour la même commande.

Cela ne prouve pas que WooCommerce a livré un doublon. La commande a pu changer deux fois.

La seconde mise à jour pourrait refléter :

  • un changement d’état du paiement
  • une modification de l’adresse de livraison
  • des métadonnées d’exécution de commande
  • une mise à jour du suivi
  • une transition d’état
  • des métadonnées d’intégration personnalisées
  • une autre extension qui écrit dans la commande

L’identifiant de ressource indique quelle commande a changé. Il ne dit pas si la même opération métier est à nouveau demandée.

Abordez d’abord les traitements en double comme un problème de corrélation.

Le cœur WooCommerce supprime certains doublons dans un périmètre limité

Le cœur actuel de WooCommerce évite déjà certaines planifications répétées.

Dans WooCommerce 11.0.1, chaque instance WC_Webhook garde la liste des arguments de ressource traités pendant la requête PHP courante. Si plusieurs hooks du même webhook et de la même ressource se déclenchent dans cette requête, l’instance ne traite pas à nouveau cet argument.

Le parcours de mise en file asynchrone possède une autre protection limitée. Avant d’ajouter woocommerce_deliver_webhook_async, WooCommerce cherche, dans sa fenêtre de compatibilité, une action planifiée avec le même identifiant de webhook et le même argument de ressource.

Ces protections répondent à des cas précis de planification WooCommerce.

Elles n’établissent pas une identité d’événement immuable commune à toutes les requêtes, tous les workers et tous les systèmes en aval.

Elles ne répondent pas non plus à la question essentielle de l’intégration :

Quelle opération métier doit être protégée contre une double exécution ?

Ne pas supposer que chaque requête répétée est une nouvelle tentative du cœur WooCommerce

Le guide public actuel des webhooks WooCommerce décrit leur désactivation après des échecs de livraison répétés.

Le code publié du cœur est plus utile pour comprendre précisément ce comportement. Le résultat de livraison actualise un compteur d’échecs consécutifs et peut désactiver le webhook lorsque le seuil configuré est dépassé. Ce parcours d’échec ne montre pas, à lui seul, une replanification de la même livraison HTTP échouée.

Des discussions d’ingénierie WooCommerce ont également présenté les nouvelles tentatives et les relectures automatiques comme des fonctions de fiabilité manquantes dans le cœur et proposé de les ajouter.

Lorsque deux requêtes similaires atteignent votre récepteur, ne qualifiez donc pas la seconde de nouvelle tentative WooCommerce sans éléments à l’appui.

Une nouvelle tentative peut provenir :

  • de code WooCommerce personnalisé
  • d’une file chez le récepteur
  • d’une infrastructure de webhooks SaaS
  • d’une plateforme de workflows
  • d’une relecture manuelle
  • d’une autre couche d’intégration

Déterminez d’abord qui a créé la seconde tentative.

Établir une fiche caractéristique du webhook

Recueillez au moins deux exemples impliqués dans l’incident.

Une fiche utile comprend :

Élément observé Pourquoi il compte
Horodatage exact de réception Permet de corréler les journaux WooCommerce, du récepteur et des systèmes en aval
X-WC-Webhook-ID Identifie la configuration du webhook WooCommerce
X-WC-Webhook-Delivery-ID Permet de corréler une tentative de livraison précise
Sujet et événement Indique la catégorie de changement WooCommerce
Identifiant de ressource Identifie la commande, le produit ou le client
Empreinte de la charge utile Indique si les corps bruts sont identiques octet par octet
État métier pertinent Explique ce que représentait la ressource à cet instant
Identifiant de requête chez le récepteur Suit la requête dans votre application
Clé d’opération Identifie l’action métier protégée
Identifiant en aval Relie l’opération à une expédition, un paiement ou un enregistrement externe
Réponse HTTP Indique ce que WooCommerce a reçu du point de terminaison
Durée de traitement Aide à repérer les schémas de dépassement de délai et de concurrence

Ne journalisez pas de données client sans rapport avec l’investigation.

L’objectif est la corrélation, pas un problème supplémentaire de conservation des données.

Schéma du traitement idempotent des webhooks

Protéger l’opération derrière la livraison

Authentifier et corréler d’abord le transport. Déduire ensuite l’opération métier et la réserver atomiquement avant qu’un effet de bord irréversible puisse être répété.

Layer 1

Identité de transport

  1. 01
    Changement de ressource WooCommerce
    L’état d’une commande, d’un produit ou d’un client change
    Nouvelle mise à jour légitime de la ressource
  2. 02
    Webhook planifié et livré
    Un point de terminaison configuré reçoit la requête
    Configuration de webhook en double
  3. 03
    Vérifier la signature
    Authentifier le corps brut de la requête
  4. 04
    Corréler les éléments du transport
    Identifiant de webhook, de livraison, ressource et charge utile
    Relecture ou concurrence chez le récepteur

Layer 2

Identité de l’opération métier

  1. 05
    Identifier l’opération métier
    Définir l’effet de bord à ne pas répéter
  2. 06
    Réservation atomique de l’opération
    Une clé durable, un seul propriétaire du traitement

Layer 3 and 4

Résultat de la réservation et traitement sûr

  • Déjà réussie
    Charger le résultat enregistré

    1. Répondre sans risque
    2. Ne pas répéter l’effet de bord
  • Nouvelle opération
    Ce worker détient la clé

    1. Persister et traiter
    2. Effet de bord externe
    3. Enregistrer l’identifiant externe
    4. Marquer comme réussie

    Duplication par un worker en aval ou lors de la reprise après défaillance

  • Échouée ou incertaine
    L’issue externe n’est pas connue avec certitude

    1. Rapprocher d’abord
    2. Réessayer seulement lorsque c’est sûr

Protéger l’opération métier, pas seulement la requête HTTP.

L’identité de transport aide à suivre une livraison. L’identité de l’opération métier, sa réservation atomique et le rapprochement empêchent le travail répété en aval sans perdre les véritables changements futurs.

Catégorie 1 : deux configurations de webhooks envoient au même récepteur

Une boutique peut accumuler d’anciennes inscriptions de webhooks.

Une ancienne intégration reste active. Un webhook de remplacement est ajouté plus tard. Les deux utilisent order.updated et visent le même récepteur.

Le système en aval reçoit deux requêtes pour un seul changement de commande.

Comparez X-WC-Webhook-ID.

Si les requêtes proviennent d’identifiants de webhook différents, examinez la configuration WooCommerce avant de modifier la logique du récepteur. Deux inscriptions actives peuvent être à l’origine du problème.

Le récepteur doit toujours protéger les opérations irréversibles, mais un webhook obsolète ne doit pas rester actif simplement parce que la déduplication en aval peut le masquer.

Catégorie 2 : la ressource a légitimement changé à nouveau

C’est ici que la déduplication par identifiant de commande devient dommageable.

Imaginez un récepteur qui stocke :

processed_order = 18452

Tous les futurs webhooks de cette commande sont désormais ignorés.

Le premier événement pouvait représenter une commande payée. Le suivant peut contenir un changement de livraison. Une mise à jour ultérieure peut apporter un suivi ou une annulation.

Une même ressource peut participer à plusieurs opérations métier légitimes.

Un identifiant de commande est généralement une identité de ressource.

Il constitue rarement une identité d’idempotence complète.

Catégorie 3 : la même opération métier est à nouveau tentée

Supposons qu’une intégration crée une expédition lorsqu’une commande devient prête à être exécutée.

Le récepteur crée l’expédition SHIP-987. Le processus échoue avant que l’application locale n’enregistre ce résultat.

L’opération d’exécution est tentée à nouveau plus tard.

Si le code sait seulement que le webhook est à nouveau traité, il peut appeler l’API d’expédition une seconde fois.

L’identité importante n’est pas celle de la requête webhook.

C’est celle de l’opération métier :

créer l’expédition pour ce périmètre d’exécution

Cette opération nécessite une clé stable qui résiste aux nouvelles tentatives, aux redémarrages de processus et aux workers concurrents.

Par exemple :

shipment:create:{order_id}:{fulfilment_scope}

Si une commande peut légitimement donner lieu à plusieurs expéditions, le périmètre d’exécution doit les distinguer.

Pour les parcours de production où la synchronisation des expéditions et la protection contre les doublons comptent, ces mêmes principes sont illustrés ici : étude de cas DevFluxr sur l’intégration de livraison WooCommerce.

Catégorie 4 : deux workers se disputent la réservation de l’opération

Un récepteur peut vérifier l’absence de doublons et néanmoins en créer.

Considérons deux requêtes arrivant presque simultanément :

Request A: operation exists? no
Request B: operation exists? no

Request A: create shipment
Request B: create shipment

La faiblesse se situe entre la vérification et la réservation.

Une conception plus robuste laisse la base de données imposer un seul propriétaire de la clé d’opération.

Sur le plan conceptuel :

CREATE TABLE integration_operations (
    operation_key varchar(191) NOT NULL,
    status varchar(32) NOT NULL,
    external_id varchar(191) NULL,
    created_at datetime NOT NULL,
    updated_at datetime NOT NULL,
    PRIMARY KEY  (operation_key)
);

Le traitement se comporte alors ainsi :

attempt to insert operation_key

insert succeeds:
    this worker owns the operation

duplicate-key result:
    load existing operation state
    do not start a second irreversible operation

La propriété essentielle est la contrainte PRIMARY KEY ou UNIQUE. Deux workers concurrents ne peuvent pas insérer tous les deux avec succès la même clé d’opération.

C’est plus robuste qu’un indicateur de cache ou qu’une requête séparée de vérification préalable.

Une réservation atomique n’élimine pas la fenêtre de défaillance externe

C’est l’aspect que de nombreux exemples d’idempotence omettent.

Supposons que la ligne locale de l’opération ait été réservée avec succès.

Le worker appelle l’API d’expédition.

L’API d’expédition crée SHIP-987.

Puis PHP s’arrête avant que l’application n’enregistre SHIP-987 localement.

La réservation en base a empêché deux workers de travailler simultanément, mais l’issue externe reste incertaine.

Un worker ultérieur ne peut pas supposer sans risque que :

rien ne s’est passé

ou que :

l’opération est terminée

La reprise dépend du système en aval.

Si l’API externe accepte une clé d’idempotence, réutilisez-y la clé d’opération stable.

Si elle propose une recherche fiable ou un point de rapprochement, vérifiez si l’expédition existe déjà avant d’en créer une autre.

Si aucune de ces possibilités n’existe, l’opération peut nécessiter un état terminal « uncertain » en vue d’un rapprochement humain ou contrôlé.

C’est pourquoi idempotence et rapprochement doivent être conçus ensemble.

Pour les travaux d’implémentation plus larges à cette frontière, consultez : ingénierie DevFluxr des intégrations API et webhooks WooCommerce.

Identité de livraison et identité métier répondent à des questions différentes

WooCommerce inclut notamment les en-têtes :

  • X-WC-Webhook-ID
  • X-WC-Webhook-Delivery-ID
  • X-WC-Webhook-Topic
  • X-WC-Webhook-Resource
  • X-WC-Webhook-Event
  • X-WC-Webhook-Signature

Ils sont utiles, mais remplissent des fonctions différentes.

Identifiant du webhook

Quelle configuration de webhook WooCommerce a envoyé cette requête ?

Utile pour retrouver des inscriptions en double ou obsolètes.

Identifiant de livraison

De quelle tentative de livraison s’agit-il ?

Utile pour corréler les journaux WooCommerce et ceux du récepteur.

Identifiant de ressource

Quelle commande, quel produit ou quel client est concerné ?

Utile pour charger l’état métier pertinent.

Clé d’opération

Quelle action métier ne doit pas s’exécuter deux fois ?

Cette identité relève généralement du domaine de votre intégration, et non des métadonnées de transport WooCommerce.

Cette distinction est au cœur d’une conception sûre.

Construire la clé d’idempotence autour de l’effet de bord

Il n’existe pas de clé d’idempotence WooCommerce universelle.

Choisissez l’identité en fonction de l’opération à protéger.

Création d’une expédition

shipment:create:{order_id}:{fulfilment_scope}

Application d’une transaction de paiement

Utilisez une identité de transaction stable du prestataire de paiement lorsque sa sémantique le permet.

Import d’un événement ERP

Un identifiant externe stable d’événement ou de version peut être la bonne clé.

Application d’une transition précise

Une identité utile peut combiner :

resource + intended transition + external operation identity

La clé doit décrire l’effet de bord assez précisément pour qu’une opération future légitime reçoive une identité différente.

Les empreintes de charge utile sont des éléments de corrélation, pas une clé d’idempotence universelle

Calculer l’empreinte du corps brut d’un webhook est utile pour comparer des livraisons suspectes.

Si deux empreintes correspondent, les corps de requête étaient identiques.

Cela ne prouve toujours pas que l’opération métier doit être supprimée indéfiniment.

Deux charges utiles pour une même opération prévue peuvent aussi différer parce que :

  • des métadonnées sans rapport ont changé
  • un horodatage a changé
  • l’ordre des champs ou la sérialisation a changé
  • une autre extension a ajouté des données
  • WooCommerce a construit la charge utile à partir d’un état plus récent de la ressource

Utilisez l’empreinte comme élément de corrélation, à moins que la sémantique de votre intégration n’en fasse une identité d’opération fiable.

Vérifier la signature avant de faire confiance à l’événement

L’idempotence n’est pas l’authentification.

WooCommerce signe les charges utiles avec le secret configuré. Par défaut, le cœur actuel produit une signature HMAC-SHA256 encodée en Base64 sur le corps encodé de la requête et l’envoie dans X-WC-Webhook-Signature.

Effectuez la validation sur le corps brut de la requête.

Sur le plan conceptuel :

$expected = base64_encode(
    hash_hmac( 'sha256', $raw_body, $secret, true )
);

if ( ! hash_equals( $expected, $provided_signature ) ) {
    // Reject the request.
}

Ne décodez pas le JSON pour le réencoder avant la vérification. Une représentation différente des octets peut produire une signature différente.

La vérification de signature détermine si la requête est digne de confiance.

L’idempotence détermine si un traitement de confiance peut répéter dangereusement une opération métier.

Les deux sont nécessaires.

Séparer l’acceptation persistée des traitements lourds

Un point de terminaison webhook devient souvent plus sûr lorsqu’il effectue moins de travail synchrone.

Un parcours utile côté récepteur est :

receive
→ verify signature
→ validate
→ derive operation identity
→ durably record/claim
→ enqueue controlled work
→ acknowledge

Le worker réalise ensuite l’opération d’intégration coûteuse et enregistre le résultat.

N’acquittez pas une requête comme acceptée en toute sécurité si rien n’est persisté et qu’une perte du processus ferait perdre l’opération.

La conception inverse présente son propre risque. Si le point de terminaison attend une API externe lente, l’effet de bord peut réussir alors que la requête HTTP expire ou que le processus s’arrête avant l’enregistrement du résultat.

Si votre récepteur utilise les traitements en arrière-plan WooCommerce/WordPress, gardez la file observable. Si les tâches s’accumulent, le modèle de diagnostic des retards d’actions planifiées WooCommerce s’applique à cette frontière de traitement interne.

Suivre l’état de l’opération, pas un simple indicateur de réception

Un enregistrement durable de l’opération doit expliquer ce qui s’est passé après l’acceptation de la requête.

Les états utiles peuvent comprendre :

received
La requête a été authentifiée et son acceptation persistée.
processing
Un worker détient actuellement l’opération.
succeeded
L’effet de bord prévu a abouti et l’identité externe a été enregistrée.
retryable_failed
L’opération a échoué d’une manière pour laquelle la politique de reprise autorise une nouvelle tentative.
terminal_failed
Le traitement automatique s’est arrêté ; un rapprochement ou une intervention humaine est nécessaire.

Une opération peut aussi nécessiter un état explicite « uncertain » lorsque le système en aval a pu réussir sans que le résultat local ait été persisté en toute sécurité.

Cet état est plus sûr que la répétition aveugle d’un appel irréversible.

Conserver les identifiants en aval

Après un appel externe réussi, conservez l’identité renvoyée par le système en aval.

Pour une expédition, cela peut comprendre :

  • clé d’opération
  • identifiant de commande WooCommerce
  • périmètre d’exécution
  • identifiant externe de l’expédition
  • heure d’achèvement
  • état de l’intégration

Une requête ultérieure peut désormais établir :

SHIP-987 représente déjà cette opération d’exécution

C’est un élément plus solide que :

nous avons déjà vu un webhook pour la commande 18452

Réponse HTTP et résultat métier sont des états distincts

WooCommerce enregistre la réponse HTTP du récepteur comme élément de preuve de livraison.

Une réponse réussie signifie que le point de terminaison a accepté l’échange HTTP selon son contrat. Elle ne prouve pas qu’un enregistrement ERP, une expédition, une mise à jour CRM ou un rapprochement de stock a abouti ensuite.

Inversement, une opération externe peut réussir même si le récepteur renvoie finalement une erreur.

Gardez ces états distincts :

delivery accepted
business operation succeeded

Cette séparation rend possible la reprise après incident.

Ne renvoyez pas de succès pour une signature invalide, une requête mal formée ou une requête dont l’acceptation n’a pas été persistée.

Ne renvoyez pas d’erreur après la réussite d’un effet de bord irréversible, à moins que votre modèle de reprise puisse identifier cet état de manière sûre.

Examiner les éléments WooCommerce avant de modifier la logique du récepteur

Le code actuel de livraison des webhooks WooCommerce 11.x expose, via la journalisation WooCommerce, des métadonnées utiles de requête et de réponse, la durée de livraison et un identifiant de livraison.

Comparez les requêtes suspectes côte à côte.

Une investigation ciblée pose les questions suivantes :

  • Provenaient-elles du même identifiant de webhook ?
  • Avaient-elles le même identifiant de livraison ?
  • Avaient-elles le même sujet et le même événement ?
  • Concernaient-elles la même ressource ?
  • Les charges utiles brutes étaient-elles identiques ?
  • Le récepteur a-t-il attribué la même clé d’opération ?
  • Les deux workers ont-ils atteint l’API en aval ?
  • Le système en aval a-t-il créé un ou deux résultats ?
  • Quelle réponse WooCommerce a-t-il reçue ?

Ces éléments indiquent où la duplication a réellement commencé.

Évitez les verrous temporaires qui ignorent les doublons pendant dix minutes, sauf si l’opération métier possède elle-même une identité de dix minutes. Une fenêtre temporelle peut masquer un symptôme tout en perdant une mise à jour légitime.

Le doublon peut apparaître en aval de WooCommerce

Parfois, WooCommerce envoie une requête et votre point de terminaison en reçoit une, mais deux effets de bord se produisent malgré tout.

Par exemple :

one webhook
→ internal job
→ worker A
→ retry worker B
→ both call fulfilment

Ou :

one webhook
→ create shipment succeeds
→ local persistence fails
→ recovery repeats shipment creation

Si vous examinez seulement la configuration des webhooks WooCommerce, vous ne trouverez jamais cette frontière.

Suivez la chaîne complète :

WooCommerce trigger
→ webhook scheduling
→ HTTP delivery
→ receiver
→ internal queue
→ worker
→ downstream API
→ recorded result

Repérez le premier point où une opération métier prévue devient deux opérations.

Ne pas éliminer les changements d’état légitimes par déduplication

Une déduplication trop agressive crée un échec plus discret, mais plus dangereux.

Supposons qu’un ERP traite uniquement le tout premier webhook reçu pour une commande.

Plus tard, l’adresse de livraison change. La commande est remboursée. Un suivi est ajouté.

Ces changements sont ignorés silencieusement, car l’identifiant de ressource a été marqué comme traité.

Pour la synchronisation d’état, un autre modèle peut être plus sûr :

receive notice that the resource changed
enqueue synchronization
fetch the current authoritative state
reconcile the other system toward that state

Cette approche n’exige pas que chaque notification intermédiaire order.updated représente une commande irréversible.

Les commandes événementielles et la synchronisation d’état nécessitent des garanties différentes

Considérons deux intégrations.

Opération de type commande

Créer une seule expédition pour cette unité d’exécution.

Répéter l’effet de bord externe est dangereux. L’idempotence au niveau métier est essentielle.

Synchronisation d’état

Maintenir le stock ERP aligné avec WooCommerce.

Le résultat important peut être la convergence vers la valeur courante plutôt que la relecture de chaque mise à jour historique.

Les intégrations fiables combinent souvent les deux approches :

idempotent commands
+
state reconciliation

Les webhooks fournissent des notifications rapides.

Le rapprochement offre une voie de reprise lorsque l’historique de livraison ou de traitement devient incertain.

Ajouter des nouvelles tentatives seulement lorsque la répétition est sûre

De nombreuses intégrations réelles disposent de nouvelles tentatives même lorsque le cœur WooCommerce ne rejoue pas automatiquement la même livraison échouée.

Ce mécanisme peut se trouver dans :

  • une extension personnalisée
  • Action Scheduler
  • la file du récepteur
  • une plateforme de webhooks SaaS
  • un moteur de workflows
  • un outil de reprise manuelle

Avant d’introduire ou d’augmenter les nouvelles tentatives, définissez :

  • les erreurs autorisant une nouvelle tentative
  • le délai avant une nouvelle tentative
  • le nombre maximal de tentatives
  • l’ancienneté maximale de l’opération
  • la clé d’idempotence
  • le comportement d’idempotence du système en aval
  • le parcours de rapprochement
  • l’état d’échec terminal

Une réponse distante 429 peut justifier une nouvelle tentative différée.

Une signature invalide ne le justifie pas.

Une opération dont l’issue externe est incertaine doit être rapprochée avant une nouvelle tentative susceptible de créer un effet de bord en double.

Tester délibérément la concurrence et la reprise après défaillance

Un récepteur qui fonctionne avec une requête Postman n’a pas démontré son idempotence.

Testez au moins :

  • deux requêtes concurrentes avec la même clé d’opération
  • une répétition après réussite
  • une défaillance après la réservation, mais avant l’appel externe
  • une défaillance après réussite externe, mais avant persistance locale
  • une mise à jour ultérieure légitime de la même commande WooCommerce
  • une signature invalide
  • une API en aval retardée
  • une réponse distante 429
  • une réponse distante 5xx

La question clé de la vérification est :

Le système produit-il le bon résultat métier lorsque les livraisons sont répétées, retardées ou concurrentes ?

La vérification doit couvrir la sûreté et la vivacité

L’idempotence peut échouer de deux manières.

Défaillance de sûreté

La même opération métier crée des effets de bord en double.

Défaillance de vivacité

Une nouvelle opération légitime est rejetée parce que le récepteur considère la ressource comme déjà traitée.

Vérifiez les deux.

Le traitement répété d’une même clé d’opération ne doit pas produire un autre résultat irréversible.

Une opération véritablement nouvelle sur la même commande doit continuer à être traitée normalement.

C’est pourquoi envoyer deux fois le même webhook et obtenir une seule ligne ne constitue pas une vérification complète.

Une séquence pratique d’investigation

Pour les traitements de webhooks WooCommerce en double, suivez cet ordre.

  1. Conserver au moins deux exemples

    Relevez les horodatages, identifiants de webhook et de livraison, sujet/événement, identifiant de ressource, éléments de charge utile, réponses et résultats en aval.

  2. Identifier la frontière de duplication

    Classez ce qui s’est produit :

    • configuration de webhook en double
    • nouvelle mise à jour légitime de la ressource
    • livraison répétée ou relecture
    • concurrence chez le récepteur
    • traitement en double en aval
  3. Définir l’opération métier protégée

    Décrivez l’opération en termes métier.

    Par exemple :

    Créer une seule expédition pour cette unité d’exécution de commande.

    La définition de l’opération détermine sa clé d’idempotence.

  4. Réserver l’opération atomiquement

    Utilisez une contrainte de stockage ou une frontière transactionnelle empêchant deux workers de détenir simultanément la même clé.

  5. Persister l’état de traitement

    Suivez le propriétaire, l’achèvement, les échecs autorisant une nouvelle tentative, les échecs terminaux et, si nécessaire, les issues incertaines.

  6. Séparer l’acceptation du travail coûteux

    Persistez l’acceptation de l’opération avant de renvoyer un succès, puis déplacez les traitements coûteux vers des tâches de fond contrôlées lorsque cela convient.

  7. Récupérer avec des nouvelles tentatives bornées

    Ne réessayez que les opérations dont la catégorie d’échec et la sémantique en aval rendent une nouvelle tentative sûre.

  8. Rapprocher l’état en aval

    Lorsque l’issue externe est incertaine, examinez le système en aval avant de répéter l’effet de bord.

  9. Vérifier la mise à jour légitime suivante

    Confirmez que la frontière d’idempotence ne supprime pas une nouvelle opération métier sur la même ressource WooCommerce.

Le critère de réussite

Une intégration de webhooks fiable ne dépend pas de l’arrivée de chaque requête HTTP exactement une fois.

Elle doit préserver ce comportement métier :

Les livraisons répétées ou concurrentes ne peuvent pas répéter involontairement une opération irréversible. Les opérations futures légitimes restent exécutables et les échecs incertains demeurent visibles jusqu’au rapprochement.

C’est cette frontière qu’il faut protéger.

Prévenir le prochain incident de webhook

Pour les intégrations WooCommerce importantes, définissez avant le lancement :

Authentification
Comment le récepteur vérifie-t-il WooCommerce ?
Identité de transport
Comment une livraison est-elle corrélée entre les journaux ?
Identité de l’opération métier
Quelle action ne doit pas avoir lieu deux fois ?
Réservation atomique
Qu’est-ce qui empêche deux workers de la détenir simultanément ?
État du traitement
Comment le système distingue-t-il le travail accepté, en cours, réussi, échoué ou incertain ?
Idempotence en aval
L’API externe peut-elle accepter une clé d’idempotence stable ?
Politique de nouvelle tentative
Quels échecs permettent une nouvelle tentative sans risque ?
Rapprochement
Comment les systèmes reprennent-ils lorsque le résultat est incertain ?
Observabilité
Peut-on suivre un changement WooCommerce jusqu’à un résultat en aval ?
Conservation
Combien de temps les éléments nécessaires au diagnostic sont-ils conservés ?

Une URL de webhook constitue une frontière de transport. La fiabilité de l’intégration dépend de tout ce qui se passe autour.

Quand faire appel à une expertise spécialisée

Une investigation spécialisée est justifiée lorsque :

  • une commande WooCommerce crée plusieurs expéditions ou enregistrements externes
  • order.updated semble se déclencher bien plus souvent que prévu
  • des inscriptions anciennes et nouvelles de webhooks coexistent
  • les traitements en double apparaissent uniquement avec la concurrence de production
  • les tâches de nouvelle tentative répètent des effets de bord externes
  • les journaux WooCommerce et ceux des systèmes en aval ne concordent pas
  • les états ERP, CRM, de stock ou d’exécution des commandes dérivent de WooCommerce
  • une opération de paiement, de stock ou d’expédition ne doit jamais s’exécuter deux fois
  • le code personnalisé du récepteur déduplique seulement par identifiant de commande ou avec un cache de courte durée
  • personne ne peut relier une livraison de webhook à un résultat final en aval

L’investigation doit identifier la frontière de duplication, définir l’opération métier protégée, sécuriser sa réservation en situation de concurrence et prévoir le rapprochement des issues incertaines.

Références techniques

  1. Documentation développeur WooCommerce — Utiliser les webhooksConfiguration, sujets, signatures, état de livraison et points d’entrée du diagnostic et de la journalisation des webhooks.
  2. Documentation développeur WooCommerce — Webhooks de la REST APISujets et en-têtes de transport des webhooks : source, sujet, événement, signature, identifiants de webhook et de livraison.
  3. Cœur WooCommerce 11.0.1 — WC_WebhookSuppression des ressources déjà traitées dans une même requête, génération de l’identifiant de livraison et de la signature, journalisation des livraisons et suivi des échecs dans le cœur publié.
  4. Cœur WooCommerce 11.0.1 — Fonctions de webhookMise en file à l’arrêt de la requête, planification asynchrone de woocommerce_deliver_webhook_async et protection limitée contre la planification répétée d’un même couple webhook/ressource.
  5. Discussion GitHub WooCommerce #44199 — Recueil de retours sur la Web APIDiscussion sur la fiabilité des webhooks à l’échelle de la production, notamment l’absence de nouvelles tentatives automatiques ou manuelles dans le modèle du cœur examiné et les propositions de tentatives, relectures et observabilité améliorée.
  6. Manuel des plugins WordPress — Créer des tables avec des pluginsRecommandations WordPress pour créer des tables MySQL/MariaDB propres à un plugin et maintenir leur schéma.
  7. Manuel de référence MySQL 8.4 — Contraintes d’index PRIMARY KEY et UNIQUEComportement d’unicité en base utilisé pour imposer une seule clé d’opération lors d’insertions concurrentes.