Un développeur qui découvre WooCommerce a tendance à considérer le statut d’une commande comme une simple étiquette informative, modifiable sans grande conséquence. C’est une erreur : chaque statut natif déclenche des comportements précis — décrémentation du stock, notification client, comptabilisation dans les rapports de vente — et un statut mal choisi ou mal enregistré peut fausser silencieusement ces mécanismes. Ce billet détaille le cycle de vie des statuts natifs, puis la marche à suivre pour en enregistrer un nouveau. Il ne traite pas les statuts propres aux abonnements, gérés par une extension à part avec sa propre logique de renouvellement.
Le cycle de vie des statuts natifs
WooCommerce fournit huit statuts de commande en cœur, chacun avec un rôle précis dans le parcours d’une vente :
pending: commande créée, paiement non encore reçu ou non confirmé.on-hold: en attente, typiquement pour un paiement par virement ou chèque à réception.processing: paiement reçu, commande en cours de préparation.completed: commande traitée et livrée, considérée close.cancelled: annulée par le client ou l’administrateur.refunded: intégralement remboursée.failed: paiement échoué ou refusé.checkout-draft: brouillon de commande créé pendant la saisie du panier, avant validation.
Ce que chaque transition déclenche réellement

Le passage de pending ou on-hold vers processing ou completed décrémente le stock, via le hook interne woocommerce_order_status_changed couplé à la logique de wc_maybe_reduce_stock_levels(). À l’inverse, un passage vers cancelled ou refunded restaure le stock si celui-ci avait déjà été décrémenté. Un statut personnalisé mal positionné dans cette logique peut donc, sans le vouloir, laisser un produit en rupture apparente alors qu’il a été remis en stock, ou l’inverse.
Enregistrer un statut personnalisé : la mécanique
Un statut personnalisé s’enregistre en deux temps : d’abord comme statut de publication WordPress standard, via register_post_status(), puis comme statut visible et sélectionnable dans l’interface WooCommerce, via le filtre wc_order_statuses. Prenons l’exemple d’un fabricant qui a besoin d’un statut en-fabrication, distinct de « en cours » :
add_action( 'init', 'atelier_enregistrer_statut_fabrication' );
function atelier_enregistrer_statut_fabrication() {
register_post_status( 'wc-en-fabrication', array(
'label' => _x( 'En fabrication', 'statut de commande', 'atelier' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop(
'En fabrication (%s)',
'En fabrication (%s)',
'atelier'
),
) );
}
add_filter( 'wc_order_statuses', 'atelier_ajouter_statut_dans_liste' );
function atelier_ajouter_statut_dans_liste( $statuts ) {
$nouveau_statut = array();
foreach ( $statuts as $cle => $nom ) {
$nouveau_statut[ $cle ] = $nom;
if ( 'wc-processing' === $cle ) {
$nouveau_statut['wc-en-fabrication'] = _x( 'En fabrication', 'statut de commande', 'atelier' );
}
}
return $nouveau_statut;
}
Le préfixe wc- dans register_post_status() n’est pas cosmétique : c’est la convention que WooCommerce attend pour reconnaître un statut comme lui appartenant, y compris dans ses propres requêtes internes de comptage.
Déclencher le changement de statut proprement
Le nouveau statut se déclenche toujours via set_status() suivi de save(), jamais par une modification directe du post WordPress sous-jacent :
$order = wc_get_order( $order_id );
$order->set_status( 'en-fabrication', 'Pièce transmise à l\'atelier de production.' );
$order->save();
Le second paramètre de set_status() ajoute une note de commande visible dans l’historique, un détail qui facilite grandement le support client quand plusieurs personnes interviennent sur le suivi d’une même commande.
Pièges fréquents avec un statut personnalisé
Un statut personnalisé qui n’apparaît nulle part dans la logique de décompte du chiffre d’affaires des rapports WooCommerce n’est pas un bug : c’est un oubli de configuration. Chaque statut doit explicitement être ajouté à la liste des statuts « payés » via le filtre approprié s’il doit compter dans les revenus.
Il faut également penser à ajouter le nouveau statut à la liste des statuts considérés comme payés, via woocommerce_order_is_paid_statuses, sans quoi certaines extensions tierces (avis produits automatiques, points de fidélité) ignoreront purement et simplement les commandes dans cet état :
add_filter( 'woocommerce_order_is_paid_statuses', function( $statuts_payes ) {
$statuts_payes[] = 'en-fabrication';
return $statuts_payes;
} );
Notion clé à retenir
Un statut de commande WooCommerce n’est jamais une simple étiquette : c’est un point d’ancrage pour le stock, la comptabilité et de nombreuses extensions tierces qui observent silencieusement ces transitions. Avant d’introduire un statut métier personnalisé, il vaut mieux cartographier précisément où il doit s’insérer dans le cycle de vie existant plutôt que de l’ajouter isolément, au risque de casser des comportements qui semblaient acquis.