vendredi 25 septembre 2026

À propos

Contact

E-commerce

Construire un flux Google Shopping personnalisé depuis le catalogue WooCommerce

Les extensions de flux génériques ne couvrent pas toujours les attributs spécifiques exigés par Google Shopping. Construire son propre générateur XML depuis les données produit reste parfois la solution la plus fiable.

Par Clément Hadrot • 17 janvier 2022 • 5 min de lecture • Aucun commentaire
Construire un flux Google Shopping personnalisé depuis le catalogue WooCommerce

Un développeur reçoit une mission a priori simple : exposer le catalogue WooCommerce d’un client à Google Shopping. Les extensions génériques de génération de flux existent en nombre, mais celle testée en premier sur ce projet ne gérait pas correctement les identifiants GTIN absents pour une partie du catalogue fabriqué en petite série, ni la distinction entre produits neufs et produits reconditionnés vendus sur la même boutique. Plutôt que de contourner ces limites avec des réglages bricolés, la décision a été de construire un générateur de flux XML sur mesure, directement depuis les données produit WooCommerce. Ce billet ne traite pas la configuration du compte Google Merchant Center lui-même, uniquement la construction technique du flux côté boutique.

Le format attendu par Google Shopping

Google Merchant Center attend un flux respectant la structure RSS 2.0 étendue par l’espace de noms g:, avec un ensemble d’attributs obligatoires (identifiant, titre, description, lien, image, disponibilité, prix) et des attributs conditionnels selon la catégorie de produit, comme le GTIN ou le genre pour les vêtements.

Générer le squelette XML

L'essentiel à retenir : Le flux XML doit respecter précisément le format RSS 2.0 attendu par Merchant Center ; Certains attributs GTIN, MPN ou condition demandent un mapping spécifique au catalogue ; Une régénération planifiée évite un flux figé pendant que le stock change

La génération s’appuie sur XMLWriter, plus robuste qu’une concaténation de chaînes pour éviter les problèmes d’échappement sur des titres ou descriptions produit contenant des caractères spéciaux :

function catalogue_generer_flux_google_shopping() {
    $writer = new XMLWriter();
    $writer->openMemory();
    $writer->startDocument( '1.0', 'UTF-8' );
    $writer->startElementNs( null, 'rss', null );
    $writer->writeAttribute( 'version', '2.0' );
    $writer->writeAttributeNs( 'xmlns', 'g', null, 'http://base.google.com/ns/1.0' );
    $writer->startElement( 'channel' );
    $writer->writeElement( 'title', get_bloginfo( 'name' ) );
    $writer->writeElement( 'link', home_url( '/' ) );

    $produits = wc_get_products( array(
        'status' => 'publish',
        'limit'  => -1,
    ) );

    foreach ( $produits as $produit ) {
        catalogue_ecrire_item_flux( $writer, $produit );
    }

    $writer->endElement();
    $writer->endElement();
    $writer->endDocument();

    return $writer->outputMemory();
}

Mapper chaque attribut produit

Le cœur du travail se situe dans le mapping entre les données WooCommerce et les attributs exigés par Google, notamment pour la disponibilité et la condition du produit, deux valeurs codifiées différemment côté Google et côté WooCommerce :

function catalogue_ecrire_item_flux( XMLWriter $writer, $produit ) {
    $writer->startElement( 'item' );
    $writer->writeElement( 'g:id', (string) $produit->get_id() );
    $writer->writeElement( 'title', $produit->get_name() );
    $writer->writeElement( 'link', get_permalink( $produit->get_id() ) );
    $writer->writeElement( 'g:image_link', wp_get_attachment_url( $produit->get_image_id() ) );
    $writer->writeElement( 'g:availability', $produit->is_in_stock() ? 'in stock' : 'out of stock' );
    $writer->writeElement( 'g:price', $produit->get_regular_price() . ' EUR' );

    if ( $produit->is_on_sale() ) {
        $writer->writeElement( 'g:sale_price', $produit->get_sale_price() . ' EUR' );
    }

    $condition = $produit->get_meta( '_condition_produit' );
    $writer->writeElement( 'g:condition', $condition ? $condition : 'new' );

    $gtin = $produit->get_meta( '_gtin' );
    if ( $gtin ) {
        $writer->writeElement( 'g:gtin', $gtin );
    } else {
        $writer->writeElement( 'g:identifier_exists', 'no' );
    }

    $writer->endElement();
}

La clause g:identifier_exists réglée sur no en l’absence de GTIN évite un rejet pur et simple du produit par Merchant Center, une subtilité de la spécification facile à manquer et qui a bloqué une bonne partie du catalogue lors des premiers tests.

Publier le flux à une URL stable

Le flux se sert via une réécriture d’URL dédiée plutôt qu’un fichier statique régénéré manuellement, ce qui garantit que Merchant Center récupère toujours une version à jour :

add_action( 'init', function() {
    add_rewrite_rule( '^flux-google-shopping\.xml$', 'index.php?flux_google_shopping=1', 'top' );
} );

add_filter( 'query_vars', function( $vars ) {
    $vars[] = 'flux_google_shopping';
    return $vars;
} );

add_action( 'template_redirect', function() {
    if ( get_query_var( 'flux_google_shopping' ) ) {
        header( 'Content-Type: application/xml; charset=utf-8' );
        echo catalogue_generer_flux_google_shopping();
        exit;
    }
} );

Éviter de régénérer le flux à chaque appel de Merchant Center

Générer l’intégralité du flux à chaque requête de Merchant Center, sur un catalogue de plusieurs milliers de produits, devient rapidement coûteux en temps de réponse. Une régénération planifiée toutes les six heures, stockée en fichier statique dans les uploads, résout ce problème sans complexifier la logique de génération elle-même :

as_schedule_recurring_action(
    time(),
    6 * HOUR_IN_SECONDS,
    'catalogue_regenerer_flux_shopping',
    array(),
    'catalogue-flux'
);

add_action( 'catalogue_regenerer_flux_shopping', function() {
    $upload_dir = wp_upload_dir();
    file_put_contents(
        $upload_dir['basedir'] . '/flux-google-shopping.xml',
        catalogue_generer_flux_google_shopping()
    );
} );

Ce qu’il reste à surveiller après mise en ligne

  • Le rapport de diagnostic de Merchant Center signale les produits rejetés et le motif exact, souvent plus précis qu’une supposition a priori.
  • Un changement de prix côté catalogue met jusqu’à la prochaine régénération planifiée à se refléter dans le flux, un délai à documenter clairement pour le client.
  • Les produits variables demandent un item distinct par variation exposée à la vente, avec un identifiant propre à chaque combinaison.

Une vérification qui a évité une déconvenue sur ce projet : valider le flux généré avec un validateur XML strict avant la première soumission, un simple caractère mal échappé dans une description produit suffisant à invalider l’ensemble du fichier aux yeux de Merchant Center.

Pour aller plus loin

Construire son propre générateur de flux demande davantage de rigueur qu’une extension clé en main, mais offre un contrôle total sur le mapping des attributs les plus spécifiques au métier du client, là où une extension générique impose souvent des compromis mal adaptés à un catalogue qui sort de l’ordinaire.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi