Un tableau de bord personnalisé affiche 340 commandes ce mois-ci. La table wp_wc_orders — ou wp_posts selon que HPOS est activé ou non — en contient visiblement plus quand on les compte directement en base. Cet écart, souvent découvert par hasard en croisant deux sources de données, a presque toujours la même origine : un appel à wc_get_orders() sans paramètre status explicite, qui applique un filtre implicite bien plus restrictif qu’on ne l’imagine. Ce billet n’explique pas la configuration du HPOS, déjà traitée ailleurs, mais se concentre sur ce piège précis de comptage.
Le comportement par défaut de wc_get_orders()
Quand aucun paramètre status n’est fourni à wc_get_orders(), la fonction n’utilise pas automatiquement tous les statuts existants : elle applique le filtre wc_get_is_paid_statuses() ou une liste réduite selon le contexte d’appel, ce qui exclut de fait les commandes en statut pending, failed, ou cancelled. Un code qui suppose implicitement récupérer « toutes les commandes » se retrouve donc à ne compter qu’un sous-ensemble, sans qu’aucune erreur ne le signale.
// Piège fréquent : suppose récupérer toutes les commandes
$commandes = wc_get_orders( array(
'limit' => -1,
'date_created' => '>' . strtotime( '-30 days' ),
) );
// En réalité, seuls certains statuts sont inclus par défaut
Diagnostiquer l’écart

Pour confirmer cette hypothèse, il suffit de comparer un comptage explicite avec tous les statuts à un comptage sans paramètre de statut :
$avec_tous_statuts = wc_get_orders( array(
'limit' => -1,
'status' => array_keys( wc_get_order_statuses() ),
'return' => 'ids',
) );
$sans_statut_explicite = wc_get_orders( array(
'limit' => -1,
'return' => 'ids',
) );
error_log( sprintf(
'Avec tous les statuts : %d — sans statut explicite : %d',
count( $avec_tous_statuts ),
count( $sans_statut_explicite )
) );
Un écart significatif entre les deux résultats confirme que le filtre implicite est en cause, et non un problème de synchronisation de données ou un souci lié au HPOS.
Le cas des statuts personnalisés
Une deuxième source d’écart, plus insidieuse, vient des statuts personnalisés ajoutés par une extension tierce — une extension de livraison qui introduit un statut « expédié en attente de retour », par exemple. Même en listant explicitement wc_get_order_statuses(), ce statut personnalisé n’apparaît que s’il a été correctement enregistré via wc_register_order_status() et ajouté à la liste des statuts visibles avec le filtre wc_order_statuses. Un statut mal enregistré reste invisible à tout comptage global, même explicite.
add_filter( 'wc_order_statuses', function( $statuts ) {
$statuts['wc-expedie-attente-retour'] = 'Expédié, en attente de retour';
return $statuts;
} );
Écrire un comptage fiable
La bonne pratique consiste à toujours expliciter l’intention exacte du comptage plutôt que de s’appuyer sur un comportement par défaut : compter « toutes les commandes créées » n’est pas la même chose que compter « toutes les commandes payées », et le code doit refléter clairement laquelle de ces deux questions il répond réellement.
- Ne jamais omettre le paramètre
statusquand un comptage global est attendu. - Vérifier la liste complète des statuts, y compris personnalisés, via
wc_get_order_statuses()avant tout comptage de référence. - Documenter dans le code lui-même quelle définition de « commande » est utilisée, pour éviter que le prochain développeur ne retombe dans le même piège.
Vérification rapide en ligne de commande
wp eval 'foreach ( wc_get_order_statuses() as $cle => $libelle ) {
$n = wc_get_orders( array( "status" => $cle, "limit" => -1, "return" => "ids" ) );
echo $libelle . " : " . count( $n ) . "\n";
}'
Un tableau de bord qui affiche un total de commandes sans préciser quels statuts sont inclus finit toujours par être remis en question par un comptable qui compare avec ses propres chiffres.
En résumé
Un écart de comptage sur wc_get_orders() vient presque toujours d’un filtre de statut implicite, jamais d’une perte réelle de données. Expliciter systématiquement le paramètre status, et vérifier que les statuts personnalisés sont bien enregistrés dans la liste globale, suffit à éliminer ce piège classique et à obtenir des totaux cohérents entre tous les outils de reporting de la boutique.