# Masquer le prix pendant la mise à jour d’un catalogue de 100 000 produits

> Un prix affiché qui n'est déjà plus le bon vaut pire qu'aucun prix affiché : symptôme, diagnostic et correctif d'un cas fréquent en synchronisation catalogue.

- Auteur : WordPress Développement
- Publié le : 2023-02-22
- Mis à jour le : 2026-09-30
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/masquer-prix-mise-a-jour-catalogue-100000-produits/

## L’essentiel

- Détecter une fiche en cours de resynchronisation via un statut dédié
- Remplacer l'affichage du prix par un indicateur temporaire clair
- Ne jamais laisser un batch partiel exposer un prix obsolète

**Symptôme.** Sur un catalogue WooCommerce de 100 000 références synchronisé chaque nuit depuis un ERP fournisseur, plusieurs clients signalent avoir payé un article à un prix, puis reçu une facture à un tarif différent le lendemain. Aucune erreur dans les journaux, aucun code d'erreur PHP, aucune alerte du serveur : le site a fonctionné normalement pendant toute la synchronisation, ce qui rend le problème d'autant plus difficile à repérer.

## Diagnostic

La synchronisation nocturne traite les 100 000 fiches par lots de 500, via une tâche `wp_schedule_event()` qui appelle `wc_update_product_stock()` et met à jour le champ `_regular_price` et `_sale_price` produit par produit. Le traitement complet dure environ deux heures. Pendant cette fenêtre, une fiche déjà traitée affiche le nouveau prix, une fiche pas encore traitée affiche encore l'ancien, et surtout, une fiche en cours de traitement peut, dans de rares cas, être consultée exactement entre la mise à jour du prix régulier et celle du prix soldé, ce qui produit un prix affiché temporairement incohérent, ni l'ancien ni le nouveau.

Le vrai problème n'est donc pas la durée de la synchronisation en elle-même — deux heures pour 100 000 fiches est un rythme raisonnable — mais l'absence totale de signal pour le client pendant cette fenêtre. Rien ne distingue, du point de vue de l'acheteur, un prix stable d'un prix en cours de recalcul.

## Correctif

La solution consiste à marquer explicitement chaque fiche comme « en cours de resynchronisation » au tout début de son traitement, et à ne retirer ce marqueur qu'une fois toutes les métadonnées de prix cohérentes entre elles. Le marquage se fait via `update_post_meta()` sur une clé dédiée, jamais via le statut de publication du produit lui-même, qui doit rester inchangé pour ne pas affecter le référencement ni la disponibilité du produit dans les flux d'export.

```
function agence_synchroniser_lot_produits( array $ids_produits ) {
    foreach ( $ids_produits as $product_id ) {
        update_post_meta( $product_id, '_resync_en_cours', 1 );
    }

    foreach ( $ids_produits as $product_id ) {
        $donnees_erp = agence_recuperer_donnees_erp( $product_id );

        update_post_meta( $product_id, '_regular_price', $donnees_erp['prix_ht'] );
        update_post_meta( $product_id, '_price', $donnees_erp['prix_ttc'] );
        if ( ! empty( $donnees_erp['prix_solde'] ) ) {
            update_post_meta( $product_id, '_sale_price', $donnees_erp['prix_solde'] );
        }

        // Une fois toutes les métas cohérentes, on lève le marqueur
        delete_post_meta( $product_id, '_resync_en_cours' );
    }

    wc_delete_product_transients( $product_id );
}
```

> L'essentiel à retenir : Détecter une fiche en cours de resynchronisation via un statut dédié ; Remplacer l'affichage du prix par un indicateur temporaire clair ; Ne jamais laisser un batch partiel exposer un prix obsolète

### Remplacer l'affichage, pas le bloquer

Le filtre `woocommerce_get_price_html` permet d'intercepter l'affichage du prix pour chaque produit et de le remplacer par un indicateur temporaire tant que le marqueur de resynchronisation est présent, sans jamais toucher aux données de prix elles-mêmes ni bloquer la navigation.

```
add_filter( 'woocommerce_get_price_html', function ( $price_html, $product ) {
    if ( get_post_meta( $product->get_id(), '_resync_en_cours', true ) ) {
        return '<span class="prix-en-maj">' .
            esc_html__( 'Tarif en cours de mise à jour, actualisation sous quelques minutes', 'agence-boutique' ) .
            '</span>';
    }

    return $price_html;
}, 10, 2 );

add_filter( 'woocommerce_is_purchasable', function ( $is_purchasable, $product ) {
    if ( get_post_meta( $product->get_id(), '_resync_en_cours', true ) ) {
        return false;
    }

    return $is_purchasable;
}, 10, 2 );
```

Bloquer l'achat en même temps que l'affichage du prix, via `woocommerce_is_purchasable`, est indispensable : afficher un message d'attente tout en laissant le bouton d'ajout au panier actif reviendrait à recréer exactement le problème initial, avec une étape de confusion supplémentaire pour le client.

## Prévention

Trois mesures évitent que ce type d'incident ne se reproduise, y compris si la logique de synchronisation évolue par la suite :

- Toujours poser le marqueur d'indisponibilité avant de commencer à écrire la moindre métadonnée de prix, jamais après
- Traiter les lots par transaction logique complète : toutes les métadonnées d'un produit sont mises à jour ensemble, ou aucune
- Surveiller la durée réelle de la fenêtre de resynchronisation avec une alerte si elle dépasse le double du temps habituel, signe qu'un lot est resté bloqué avec des produits marqués indéfiniment indisponibles

> Un prix incohérent affiché une seconde suffit à générer une réclamation ; mieux vaut un message d'attente explicite pendant deux heures qu'un prix faux pendant deux minutes.

## En résumé

Ce correctif ne cherche pas à accélérer la synchronisation elle-même, mais à rendre visible son état transitoire. Sur un catalogue de cette taille, la fenêtre de mise à jour ne disparaîtra jamais complètement ; ce qui doit disparaître, c'est le risque qu'un client voie un prix qui n'est déjà plus vrai sans qu'aucun signal ne l'en informe.
