vendredi 25 septembre 2026

À propos

Contact

E-commerce

Une commande fantôme en base : déboguer une désynchronisation avec le HPOS

Une commande visible dans la liste WooCommerce renvoie « commande introuvable » à l'ouverture. En cause : un plugin qui écrit encore directement dans wp_posts pendant la phase de compatibilité HPOS.

Par Clément Hadrot • 8 février 2023 • 5 min de lecture • Aucun commentaire
Une commande fantôme en base : déboguer une désynchronisation avec le HPOS

Le projet avait activé, en test depuis quelques semaines, la fonctionnalité bêta de stockage haute performance des commandes (HPOS), avec le mode de compatibilité laissé actif comme recommandé pour cette phase transitoire. Un matin, une gestionnaire de la boutique signale qu’une commande visible dans la liste WooCommerce › Commandes renvoie un message « commande introuvable » dès qu’elle tente de l’ouvrir pour y ajouter une note de suivi.

Ce genre de symptôme, rare mais déstabilisant, pointe presque toujours vers le même endroit lorsque le mode de compatibilité HPOS est actif : une divergence entre les deux stockages que ce mode est censé garder synchronisés.

Symptôme : une commande visible mais inaccessible

La commande apparaissait bien dans le tableau de liste, avec un numéro, un statut et un montant cohérents. Mais le clic sur cette ligne renvoyait une erreur, sans détail exploitable pour une utilisatrice non technique. Le journal de débogage WordPress, une fois activé, affichait un avertissement PHP mentionnant l’absence d’un enregistrement correspondant dans la table historique wp_posts, alors que l’identifiant de commande existait bien dans la table dédiée wp_wc_orders propre au HPOS.

Diagnostic : un contournement du CRUD par un plugin tiers

L'essentiel à retenir : Le mode de compatibilité synchronise deux stockages, pas un seul ; Un plugin qui contourne le CRUD casse la synchronisation silencieusement ; L'outil de resynchronisation des commandes répare l'essentiel des cas

Le mode de compatibilité HPOS, activable depuis WooCommerce › Réglages › Avancé › Fonctionnalités, ne bascule pas simplement le stockage d’un endroit vers un autre : il maintient les deux représentations synchronisées en parallèle, la table historique basée sur wp_posts et les tables dédiées comme wp_wc_orders, précisément pour permettre un retour en arrière sans perte de données pendant que les extensions du site s’adaptent au nouveau modèle.

L’enquête a fini par remonter jusqu’à une extension de fidélité tierce, installée depuis longtemps sur le site, qui créait une commande de test technique via un appel direct à wp_insert_post( array( 'post_type' => 'shop_order', ... ) ), plutôt que par la fonction officielle wc_create_order(). Ce contournement, sans conséquence tant que le stockage historique restait la seule source de vérité, produisait désormais une entrée dans wp_posts sans jamais déclencher la synchronisation attendue vers les tables HPOS, ni l’inverse selon les cas rencontrés sur d’autres commandes.

Confirmer l’hypothèse avec l’outil de vérification intégré

WooCommerce propose, dans ce même écran de réglages, un outil de synchronisation manuelle qui recense précisément les commandes en écart entre les deux stockages. Son exécution a confirmé un peu plus d’une dizaine de commandes concernées sur plusieurs mois, toutes créées par cette même extension de fidélité, jamais par le tunnel de commande standard.

Correctif : resynchroniser puis corriger la source

Deux actions distinctes ont été nécessaires. D’abord, un correctif immédiat pour les commandes déjà en écart, via l’outil « Synchroniser les données de commande » disponible dans les réglages avancés, qui reconstruit la représentation manquante dans le stockage cible à partir de celle qui existe encore.

Ensuite, et surtout, un correctif de fond sur l’extension fautive : son appel direct à wp_insert_post() a été remplacé par la création d’une commande via wc_create_order(), suivie d’un appel à $order->save(), ce qui garantit que tous les hooks de synchronisation attendus par WooCommerce se déclenchent normalement, quel que soit le stockage actif :

// À éviter pendant la phase de compatibilité HPOS
wp_insert_post( array( 'post_type' => 'shop_order', 'post_status' => 'wc-completed' ) );

// Version compatible, quel que soit le stockage actif
$order = wc_create_order();
$order->set_status( 'completed' );
$order->save();

Prévention : traquer les contournements du CRUD avant qu’ils ne coûtent cher

Ce type d’incident touche presque toujours des extensions anciennes, écrites avant la généralisation des classes CRUD de WooCommerce, ou des scripts maison hérités d’un précédent prestataire. Quelques vérifications limitent le risque avant d’activer le mode de compatibilité HPOS sur un site en production :

  • Rechercher, dans le code de toutes les extensions actives, les appels directs à wp_insert_post ou wp_update_post portant sur le type de contenu shop_order.
  • Lancer l’outil de vérification de synchronisation régulièrement pendant toute la phase de test, pas seulement au moment de l’activation initiale.
  • Conserver le mode de compatibilité actif suffisamment longtemps avant d’envisager de le désactiver, précisément parce qu’il agit comme un filet de sécurité pour ce genre de divergence.

Une commande « fantôme » n’est presque jamais un bug du cœur de WooCommerce : c’est le signal qu’une extension, quelque part, parle directement à la base de données au lieu de passer par l’API que le projet lui offre.

En résumé

La désynchronisation observée n’avait rien d’aléatoire : elle reproduisait fidèlement, à chaque exécution de l’extension fautive, le même contournement du CRUD WooCommerce. L’outil de resynchronisation intégré a suffi pour réparer l’historique, mais seule la correction du code source de l’extension a empêché que le problème ne revienne à la prochaine commande de test générée automatiquement.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi