Warning: get_post_meta() returned empty on order #4821 : ce message, ou son équivalent silencieux sous forme de champ vide sur une facture imprimée, apparaît sur certains projets quelques semaines après la bascule vers le stockage des commandes à haute performance (HPOS) de WooCommerce, activé mi-2022. Les commandes existent bien, les données sont là, mais le template d’impression de facture codé à la main pour ce projet n’affiche plus les informations attendues.
Le symptôme touche spécifiquement les templates personnalisés qui interrogent directement les métadonnées de commande avec les fonctions génériques de WordPress, plutôt qu’avec les méthodes dédiées fournies par l’objet commande de WooCommerce.
Symptôme
Une facture générée pour une commande passée après la bascule HPOS affiche des champs vides : adresse de facturation manquante, numéro de TVA absent, alors que ces informations sont bien visibles et correctes dans l’écran d’administration de la commande. Le problème ne touche que les commandes créées ou modifiées après le passage au nouveau mode de stockage ; les commandes plus anciennes, elles, continuent de s’afficher correctement.
Diagnostic
Le template d’impression de facture, écrit sur mesure pour ce projet avant la généralisation de HPOS, interrogeait directement les métadonnées de commande avec la fonction générique get_post_meta(), en traitant l’identifiant de commande comme un identifiant d’article classique :
$numero_tva = get_post_meta( $commande_id, '_numero_tva_client', true );

Avant HPOS, les commandes WooCommerce étaient stockées comme des articles classiques dans la table wp_posts, avec leurs métadonnées dans wp_postmeta. Ce code fonctionnait alors parfaitement, puisque get_post_meta() interroge précisément cette table. Après activation du stockage HPOS, les commandes sont enregistrées dans des tables dédiées, distinctes de wp_posts, et leurs métadonnées ne transitent plus systématiquement par wp_postmeta. La fonction get_post_meta() continue de s’exécuter sans erreur PHP, mais elle ne trouve tout simplement rien à l’endroit où elle cherche, d’où un champ vide sans message d’erreur explicite.
Correctif
La correction consiste à remplacer chaque appel à get_post_meta() concernant une commande par l’utilisation de l’objet commande WooCommerce lui-même, via wc_get_order(), puis sa méthode get_meta(), compatible quel que soit le mode de stockage actif, HPOS ou tables historiques :
$commande = wc_get_order( $commande_id );
$numero_tva = $commande ? $commande->get_meta( '_numero_tva_client' ) : '';
Cette méthode interroge la bonne source de données de façon transparente, sans que le template n’ait à connaître le mode de stockage réellement actif sur l’installation. C’est précisément l’objectif de la compatibilité HPOS annoncée par l’équipe WooCommerce : les développeurs qui utilisent les méthodes de l’objet commande plutôt que les fonctions génériques de WordPress n’ont rien à changer lors de la bascule.
Auditer l’ensemble du template
Ce correctif ponctuel a révélé la nécessité d’un audit complet du template d’impression de facture, écrit plusieurs années avant la bascule HPOS et jamais revu depuis :
- Chaque appel à
get_post_meta()concernant une commande a été recherché et remplacé - Les accès directs à des propriétés de l’objet
WP_Postde la commande ont également été vérifiés - Les requêtes SQL personnalisées, si elles existaient, auraient nécessité une réécriture bien plus lourde
- Le fichier a été retesté sur une commande créée après la bascule, pas seulement sur une commande antérieure encore en cache
Une donnée qui n’a jamais été perdue
Point important pour rassurer l’équipe cliente au moment du diagnostic : aucune donnée n’avait été perdue lors de la bascule HPOS. Les informations de facturation existaient bien, correctement enregistrées dans les nouvelles tables dédiées aux commandes. Seul le template d’impression, resté figé sur une méthode d’accès obsolète, lisait la mauvaise source. Ce point mérite d’être clairement communiqué : le problème est un bug d’affichage, pas une perte de données.
Après toute bascule HPOS, la meilleure méthode reste de rechercher systématiquement, dans l’ensemble du code personnalisé du projet, toute occurrence de
get_post_meta,get_postou de requêtes SQL directes portant sur une commande. Un template qui semblait fonctionner parfaitement peut cacher une dépendance silencieuse à l’ancien mode de stockage.
En résumé
Un template de facture codé à la main, qui interroge les métadonnées de commande via get_post_meta() plutôt que via les méthodes de l’objet commande WooCommerce, cesse de fonctionner correctement après la bascule vers le stockage HPOS. Le correctif reste simple une fois le diagnostic posé : passer par wc_get_order() et sa méthode get_meta(), compatible quel que soit le mode de stockage réellement actif sur l’installation.