Deux cents boutiques WooCommerce, un seul catalogue de référence : c’est le chiffre qui a lancé ce projet pour un réseau de franchises. Chaque franchisé devait pouvoir vendre les mêmes deux mille références, avec sa propre grille de prix et ses propres stocks locaux, sans qu’aucune équipe n’ait à ressaisir une fiche produit deux cents fois.
Le multisite WordPress (WP_MULTISITE) fournit l’infrastructure de base : un réseau de sites qui partagent le même cœur applicatif et la même base de plugins. Mais WooCommerce ne prévoit pas nativement de partage de catalogue entre sites d’un réseau : chaque site a sa propre table wp_posts et ses propres wc_product_meta_lookup. Il faut donc construire la brique de synchronisation soi-même.
Un site source, N sites destination
L’architecture retenue distingue un site « source » — invisible du public, réservé au back-office produit — et N sites « destination », un par franchise. Le site source est celui où l’équipe marketing crée et met à jour les fiches produit : description, images, catégories, attributs. Rien d’autre n’y transite.
Chaque site destination reçoit une copie de ces fiches via un plugin maison qui s’appuie sur l’API REST de WooCommerce (wc/v3/products) en interne, site à site, plutôt que sur des requêtes SQL directes entre bases — ce qui aurait fragilisé la portabilité en cas de migration d’un site franchisé vers un autre hébergement.
Ce qui se synchronise, ce qui reste local

La règle la plus importante du projet a été de tracer une frontière nette entre ce qui appartient au catalogue central et ce qui appartient à la franchise :
- Synchronisé depuis le site source : titre, description, images, catégories, attributs, SKU.
- Local à chaque franchise : prix de vente, stock, statut de publication (un produit peut être masqué localement sans être supprimé du catalogue).
- Jamais touché par la synchronisation : les commandes, les avis clients, les pages de contenu propres au site.
Techniquement, la surcharge de prix repose sur une meta dédiée, _franchise_price_override, lue par un filtre accroché à woocommerce_product_get_price et à woocommerce_product_get_regular_price. Si la meta est vide, le prix synchronisé depuis le catalogue central s’applique tel quel.
add_filter( 'woocommerce_product_get_price', function( $price, $product ) {
$override = $product->get_meta( '_franchise_price_override', true );
return ( $override !== '' ) ? $override : $price;
}, 10, 2 );
La tâche de synchronisation, pas en temps réel
Synchroniser deux cents sites en temps réel à chaque clic d’un chargé de catalogue aurait saturé le serveur. Le choix a été de passer par Action Scheduler, déjà présent avec WooCommerce, avec une tâche horaire qui traite un lot de modifications par site :
as_schedule_recurring_action(
time(),
HOUR_IN_SECONDS,
'franchise_catalog_sync',
array(),
'catalog-sync'
);
Chaque exécution ne pousse que les produits modifiés depuis la dernière synchronisation, identifiés grâce à un horodatage _catalog_last_sync comparé à post_modified_gmt sur le site source. Cette approche incrémentale a ramené une synchronisation complète, qui prenait plus de trois heures en réécrivant tout, à quelques minutes par lot.
Arborescence du réseau
reseau-franchise.exemple/
├── source-catalogue/ (site invisible, back-office produit)
│ └── wp-content/plugins/catalog-sync-core/
├── franchise-lyon/
│ └── surcharges: prix, stock local
├── franchise-marseille/
│ └── surcharges: prix, stock local
└── ... (198 autres franchises)
Les pièges rencontrés
Le premier piège a été la duplication de SKU : deux franchisés avaient créé localement, avant le projet, des produits avec le même identifiant que des références du catalogue central. La migration a nécessité un script de réconciliation qui a renommé les SKU en conflit avant d’activer la synchronisation.
Le second piège concerne les attributs de variation. Une variation créée localement sur un site franchisé, avec des valeurs d’attribut qui n’existaient pas dans la taxonomie du site source, se retrouvait orpheline à la synchronisation suivante. La solution a été de verrouiller la création de variations aux seuls administrateurs du site source.
Conseil maison : ne synchronisez jamais les stocks depuis le catalogue central si chaque franchise a son propre entrepôt physique. Le stock est une donnée locale par nature ; le catalogue est une donnée partagée par nature. Les confondre est la source de la majorité des bugs de synchronisation multisite.
En résumé
Un réseau de deux cents boutiques WooCommerce peut fonctionner avec un catalogue unique, à condition de séparer clairement ce qui est central (fiches produit) de ce qui est local (prix, stock). L’API REST interne au réseau, couplée à Action Scheduler pour l’exécution asynchrone, a permis de tenir la charge sans réécrire WooCommerce. La facturation inter-boutiques, elle, reste un sujet à part entière, traité par un système de reversement financier distinct de ce catalogue.