Skip to Content
WordPressPartie 10 — WooCommercePersonnaliser produits & checkout

Chapitre 10.3 — Personnaliser produits & checkout

⏱️ TL;DR — Deux besoins fréquents : enrichir les produits (champ custom, onglet, données affichées) et adapter le checkout (ajouter/retirer/valider des champs, conditions). Côté produit : on ajoute des champs dans l’admin (woocommerce_product_options_* + save_post) et on les affiche via hooks. Côté checkout : historiquement les hooks woocommerce_checkout_fields, mais le checkout est désormais en blocs (Gutenberg) — la personnalisation moderne passe par des blocs/inner blocks et l’API des champs additionnels. On sécurise toujours (sanitize/escape/nonce, ch. 7.7).

🎯 Objectifs

  • Ajouter un champ custom à un produit (admin + affichage).
  • Personnaliser les champs du checkout (classique et blocs).
  • Valider et sécuriser les données saisies.
  • Connaître la bascule checkout classique → checkout blocs.

1. Ajouter un champ custom à un produit

Dans l’admin produit, on ajoute un champ dans un groupe d’options, puis on l’enregistre (mêmes réflexes que les metaboxes, ch. 7.4) :

// Afficher un champ dans l'onglet "Général" add_action( 'woocommerce_product_options_general_product_data', function () { woocommerce_wp_text_input( array( 'id' => '_wpr_isbn', 'label' => __( 'ISBN', 'wpr' ), 'desc_tip' => true, ) ); } ); // Enregistrer (Woo fournit un hook dédié à la sauvegarde produit) add_action( 'woocommerce_admin_process_product_object', function ( $product ) { if ( isset( $_POST['_wpr_isbn'] ) ) { $product->update_meta_data( '_wpr_isbn', sanitize_text_field( wp_unslash( $_POST['_wpr_isbn'] ) ) ); } } );
  • woocommerce_wp_text_input() (et _select, _checkbox…) génèrent des champs cohérents avec l’UI Woo.
  • woocommerce_admin_process_product_object reçoit l’objet WC_Product : on met à jour via update_meta_data + le save est géré par Woo (pas de update_post_meta en dur, ch. 10.1).
  • Sanitize l’entrée (Woo gère le nonce du formulaire produit, mais on assainit toujours).

Afficher le champ sur la fiche produit : via un hook de template (ch. 10.2) et $product->get_meta( '_wpr_isbn' ), en échappant la sortie.


2. Un onglet produit custom

add_filter( 'woocommerce_product_tabs', function ( $tabs ) { $tabs['wpr_infos'] = array( 'title' => __( 'Fiche technique', 'wpr' ), 'priority' => 25, 'callback' => function () { global $product; echo '<p>' . esc_html( $product->get_meta( '_wpr_isbn' ) ) . '</p>'; }, ); return $tabs; } );

Un filtre ajoute un onglet à la fiche produit (Description, Avis… + le vôtre).


3. Personnaliser le checkout (classique)

Historiquement, les champs du checkout se modifient via le filtre woocommerce_checkout_fields :

add_filter( 'woocommerce_checkout_fields', function ( $fields ) { $fields['billing']['billing_company']['required'] = false; // rendre optionnel $fields['order']['wpr_instructions'] = array( // ajouter un champ 'type' => 'textarea', 'label' => __( 'Instructions de livraison', 'wpr' ), 'required' => false, ); return $fields; } ); // Enregistrer le champ custom sur la commande add_action( 'woocommerce_checkout_update_order_meta', function ( $order_id ) { if ( ! empty( $_POST['wpr_instructions'] ) ) { $order = wc_get_order( $order_id ); $order->update_meta_data( '_wpr_instructions', sanitize_textarea_field( wp_unslash( $_POST['wpr_instructions'] ) ) ); $order->save(); } } );

Validation custom via woocommerce_checkout_process (ajouter une wc_add_notice( …, 'error' ) pour bloquer).


4. Le checkout en blocs (moderne)

WooCommerce a introduit un checkout basé sur des blocs (Gutenberg) qui remplace progressivement le checkout « shortcode ». Conséquence majeure :

⚠️ Piège n°1 — woocommerce_checkout_fields ignoré par le checkout blocs. Le filtre classique ne s’applique pas au checkout en blocs. Pour ce dernier, on utilise l’API des champs additionnels (woocommerce_register_additional_checkout_field) et/ou des blocs d’extension (inner blocks du checkout). Vérifiez quel checkout la boutique utilise (shortcode legacy vs blocs) avant de coder — c’est la confusion n°1 aujourd’hui.

Exemple (checkout blocs) — champ additionnel via l’API récente :

add_action( 'woocommerce_init', function () { woocommerce_register_additional_checkout_field( array( 'id' => 'wpr/instructions', 'label' => __( 'Instructions de livraison', 'wpr' ), 'location' => 'order', 'type' => 'text', ) ); } );

Cette API expose le champ dans le checkout blocs et le stocke proprement sur la commande. L’écosystème évolue vite : consultez la doc à jour pour la signature exacte.


5. Sécurité et bonnes pratiques

  • Sanitize toute entrée (checkout, admin produit), échappez l’affichage (ch. 7.7).
  • Passez par les objets ($product, $order) et leurs méthodes, pas le SQL/meta direct (ch. 10.1).
  • Préférez les hooks/API à la surcharge de template (ch. 10.2).
  • Testez sur le checkout réel de la boutique (blocs vs classique).

💡 Pour un dev React — Le passage au checkout en blocs rapproche WooCommerce de votre monde : le checkout devient une app React (@woocommerce/blocks), extensible par des composants/inner blocks et une API de champs — plus par des filtres PHP. Pour des personnalisations riches du checkout moderne, vos compétences React (Partie 8) redeviennent l’atout. C’est un créneau technique peu pourvu (beaucoup de devs Woo « classiques » sont à l’aise en PHP mais pas en React).


✏️ Exercices

  1. Vous ajoutez un champ « ISBN » à un produit. Quels hooks pour l’afficher en admin et l’enregistrer proprement ?
  2. Pourquoi votre woocommerce_checkout_fields n’a-t-il aucun effet sur une boutique récente ?
  3. Où enregistre-t-on un champ custom saisi au checkout (classique) sur la commande ?

✅ Solution

  1. Afficher : woocommerce_product_options_general_product_data avec woocommerce_wp_text_input. Enregistrer : woocommerce_admin_process_product_object (reçoit WC_Product) → update_meta_data + sanitize_text_field. On passe par l’objet produit, pas update_post_meta en dur.
  2. Parce que la boutique utilise le checkout en blocs, sur lequel le filtre woocommerce_checkout_fields (checkout classique) ne s’applique pas. Il faut l’API des champs additionnels (woocommerce_register_additional_checkout_field) ou des blocs d’extension.
  3. Sur le hook woocommerce_checkout_update_order_meta : récupérer la commande (wc_get_order), update_meta_data avec la valeur assainie, save().

🧠 Quiz de révision

1. Quel hook enregistre un champ produit custom proprement ?

woocommerce_admin_process_product_object (via l’objet WC_Product + update_meta_data).

2. Comment ajoute-t-on un onglet à la fiche produit ?

Via le filtre woocommerce_product_tabs (titre, priorité, callback).

3. Le filtre woocommerce_checkout_fields marche-t-il partout ?

Non : pas sur le checkout en blocs ; il faut alors l’API des champs additionnels / blocs d’extension.

4. Comment valider une saisie au checkout (classique) ?

Via woocommerce_checkout_process en ajoutant une wc_add_notice(…, 'error') pour bloquer.

5. Pourquoi le checkout blocs est-il un atout pour un dev React ?

Il est en React (@woocommerce/blocks) : la personnalisation riche passe par des composants/blocs — un créneau peu pourvu chez les devs Woo classiques.


Chapitre suivant : Développer une extension WooCommerce.