Un client spécialisé dans la vente d’accessoires automobiles gérait sa logistique via un WMS (Warehouse Management System) tiers, distinct de WooCommerce, pour piloter la préparation, l’emballage et l’expédition depuis un entrepôt partagé avec d’autres canaux de vente (marketplace, vente en gros). Le défi n’était pas de choisir un WMS, mais de faire dialoguer les deux systèmes sans jamais laisser le stock diverger — le pire scénario pour une boutique en ligne étant de vendre un produit qui n’existe déjà plus en rayon.
Ce type d’intégration revient régulièrement dès qu’une boutique WooCommerce dépasse l’auto-gestion de son propre entrepôt. Voici l’architecture que nous avons mise en place, transposable à la plupart des WMS proposant une API REST ou des webhooks.
Définir un sens de vérité unique pour le stock
La première décision structurante, avant toute ligne de code, est de désigner un système comme source de vérité pour le stock : dans ce projet, le WMS restait maître, puisqu’il consolidait les mouvements de plusieurs canaux de vente simultanément. WooCommerce ne devait donc jamais modifier le stock de sa propre initiative (par exemple via la décrémentation automatique à la commande), mais se contenter de recevoir les mises à jour de stock envoyées par le WMS.
Ce choix a nécessité de désactiver la gestion de stock automatique de WooCommerce à la commande (woocommerce_reduce_stock_levels neutralisé) pour éviter une double décrémentation : une fois côté WooCommerce à la validation de la commande, une seconde fois côté WMS à la préparation réelle du colis.
remove_action( 'woocommerce_reduce_order_stock', 'wc_reduce_stock_levels' );
add_action( 'woocommerce_order_status_completed', function ( $order_id ) {
// Le stock est décrémenté côté WMS, pas ici ; WooCommerce se contente
// de transmettre la commande, pas de gérer le stock localement.
} );
Faire remonter les commandes vers le WMS
Chaque commande passée à un statut « à préparer » (généralement processing) doit être transmise au WMS avec l’ensemble des informations nécessaires à la préparation : références produits, quantités, adresse de livraison, mode de transport choisi. Un hook sur le changement de statut déclenche l’envoi :
add_action( 'woocommerce_order_status_processing', function ( $order_id ) {
$order = wc_get_order( $order_id );
$lignes = [];
foreach ( $order->get_items() as $item ) {
$produit = $item->get_product();
$lignes[] = [
'sku' => $produit->get_sku(),
'quantite' => $item->get_quantity(),
];
}
wp_remote_post( 'https://wms.exemple.fr/api/commandes', [
'headers' => [ 'Authorization' => 'Bearer ' . get_option( 'wms_api_token' ) ],
'body' => wp_json_encode( [
'reference_externe' => $order->get_order_number(),
'adresse_livraison' => $order->get_address( 'shipping' ),
'lignes' => $lignes,
] ),
] );
} );

Recevoir les mises à jour de stock et de suivi via webhook
Plutôt que d’interroger périodiquement le WMS (polling), coûteux et toujours en retard d’un intervalle, la solution retenue expose un point d’entrée WordPress dédié que le WMS appelle à chaque mouvement de stock ou expédition confirmée :
add_action( 'rest_api_init', function () {
register_rest_route( 'integration-wms/v1', '/stock', [
'methods' => 'POST',
'permission_callback' => 'verifier_signature_wms',
'callback' => function ( WP_REST_Request $request ) {
$donnees = $request->get_json_params();
$produit_id = wc_get_product_id_by_sku( $donnees['sku'] );
if ( $produit_id ) {
$produit = wc_get_product( $produit_id );
$produit->set_stock_quantity( $donnees['quantite_disponible'] );
$produit->save();
}
return new WP_REST_Response( [ 'statut' => 'ok' ], 200 );
},
] );
} );
La fonction verifier_signature_wms doit valider une signature ou un jeton partagé avant tout traitement : un point d’entrée de mise à jour de stock non protégé serait une porte ouverte pour manipuler artificiellement les stocks affichés sur la boutique.
Remonter le numéro de suivi au client
Une fois le colis expédié, le WMS envoie le numéro de suivi via un second webhook, qui met à jour la commande et déclenche l’e-mail de notification d’expédition :
$order->update_meta_data( '_numero_suivi_transporteur', $donnees['numero_suivi'] );
$order->update_meta_data( '_transporteur', $donnees['transporteur'] );
$order->update_status( 'completed' );
$order->save();
Un numéro de suivi qui arrive avec plusieurs jours de retard, ou qui n’arrive jamais faute de webhook fiable, ruine complètement la confiance du client dans le suivi de sa commande, même si la livraison elle-même se passe sans accroc. C’est un point que nous avons particulièrement surveillé lors des tests de charge, avec un système de relance automatique si aucune confirmation n’était reçue sous 48 heures.
Superviser l’intégration dans la durée
- Journaliser chaque appel entrant et sortant entre WooCommerce et le WMS, avec horodatage et code de réponse, pour diagnostiquer rapidement un incident ;
- Mettre en place une alerte si le volume de mises à jour de stock reçu chute anormalement (signe probable d’un webhook cassé côté WMS) ;
- Prévoir un tableau de réconciliation périodique comparant le stock WooCommerce et le stock WMS, pour détecter toute dérive silencieuse malgré les webhooks.
Une intégration logistique qui fonctionne parfaitement en test peut dériver silencieusement en production si un seul webhook tombe en échec sans alerte. La supervision compte autant que l’intégration elle-même.
En résumé
Connecter WooCommerce à un WMS externe repose avant tout sur une question d’architecture, pas de code : désigner un sens de vérité unique pour le stock, transmettre les commandes de façon fiable, recevoir les mises à jour via webhook plutôt que par sondage, et superviser activement la chaîne pour repérer toute dérive. Sans cette rigueur, l’automatisation logistique promise se transforme vite en source de ruptures de stock invisibles ou de clients sans nouvelles de leur colis.