Le client, une cave en ligne spécialisée dans les vins naturels, devait se mettre en conformité avec l’obligation légale d’afficher un message d’avertissement sanitaire et de recueillir une déclaration de majorité avant toute vente d’alcool à distance. La demande précisait explicitement les limites du besoin : pas de vérification d’identité poussée avec pièce justificative, simplement une déclaration active et bloquante de l’acheteur, conservée avec chaque commande à des fins de preuve en cas de contrôle.
Cette exigence, très concrète, se traduit en quelques étapes précises côté tunnel de commande WooCommerce, sans nécessiter d’extension tierce ni de service de vérification externe.
Étape 1 : ajouter le champ de déclaration au formulaire de commande
Le hook woocommerce_after_checkout_billing_form permet d’insérer un champ personnalisé juste après les informations de facturation, un emplacement suffisamment visible pour ne pas être manqué par l’acheteur :
add_action( 'woocommerce_after_checkout_billing_form', 'va_afficher_declaration_age' );
function va_afficher_declaration_age( $checkout ) {
echo '<div id="va-declaration-age">';
woocommerce_form_field( 'va_declaration_majorite', array(
'type' => 'checkbox',
'class' => array( 'form-row-wide' ),
'label' => 'Je déclare être âgé(e) de 18 ans ou plus. L\'abus d\'alcool est dangereux pour la santé, à consommer avec modération.',
'required' => true,
), $checkout->get_value( 'va_declaration_majorite' ) );
echo '</div>';
}
Étape 2 : bloquer réellement la validation côté serveur

Une case à cocher affichée ne vaut rien juridiquement si la commande peut malgré tout être validée sans qu’elle soit cochée, par exemple si JavaScript est désactivé côté navigateur. Le contrôle doit donc se faire côté serveur, via le hook woocommerce_checkout_process, exécuté avant la création de la commande :
add_action( 'woocommerce_checkout_process', 'va_verifier_declaration_age' );
function va_verifier_declaration_age() {
if ( empty( $_POST['va_declaration_majorite'] ) ) {
wc_add_notice(
'Vous devez confirmer être majeur(e) pour valider une commande contenant de l\'alcool.',
'error'
);
}
}
Ce contrôle bloque la commande à ce stade précis, avec un message d’erreur explicite affiché en haut du formulaire, sans dépendre d’aucune validation JavaScript côté client, qui ne doit être vue que comme un confort d’expérience utilisateur, jamais comme la seule barrière de conformité.
Étape 3 : conserver la preuve de déclaration avec la commande
L’obligation légale ne s’arrête pas au blocage de la commande : il faut pouvoir démontrer, a posteriori, que cette déclaration a bien été recueillie pour chaque vente concernée. Le hook woocommerce_checkout_update_order_meta enregistre cette preuve directement sur la commande :
add_action( 'woocommerce_checkout_update_order_meta', 'va_enregistrer_declaration_age' );
function va_enregistrer_declaration_age( $order_id ) {
if ( ! empty( $_POST['va_declaration_majorite'] ) ) {
update_post_meta( $order_id, '_va_declaration_majorite', 'oui' );
update_post_meta( $order_id, '_va_declaration_horodatage', current_time( 'mysql' ) );
}
}
L’horodatage précis, conservé séparément, complète la preuve : en cas de contrôle, la boutique peut démontrer non seulement que la case a été cochée, mais aussi à quel moment exact, en cohérence avec l’heure de passation de la commande elle-même.
Étape 4 : rendre cette information visible depuis l’administration
Pour que cette donnée serve réellement en cas de besoin, elle doit apparaître directement sur l’écran de détail de commande, sans obliger l’équipe à fouiller les métadonnées techniques :
add_action( 'woocommerce_admin_order_data_after_billing_address', 'va_afficher_declaration_admin' );
function va_afficher_declaration_admin( $order ) {
$declaration = $order->get_meta( '_va_declaration_majorite' );
$horodatage = $order->get_meta( '_va_declaration_horodatage' );
if ( $declaration ) {
echo '<p><strong>Déclaration de majorité :</strong> confirmée le ' . esc_html( $horodatage ) . '</p>';
}
}
Étape 5 : appliquer la règle uniquement aux commandes concernées
Sur une boutique qui ne vend pas exclusivement des produits soumis à cette obligation, il est préférable de n’afficher le champ que si le panier contient au moins un produit marqué comme tel, via une catégorie ou un attribut dédié, plutôt que d’imposer cette déclaration à chaque commande sans distinction :
function va_panier_contient_alcool() {
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( 'boissons-alcoolisees', 'product_cat', $cart_item['product_id'] ) ) {
return true;
}
}
return false;
}
Ce contrôle s’insère en tête des deux fonctions précédentes, avec un simple if ( ! va_panier_contient_alcool() ) { return; }, pour ne pas alourdir inutilement le tunnel de commande des clients n’achetant que des produits non concernés.
- Ne jamais se contenter d’une validation JavaScript seule pour bloquer la commande.
- Toujours conserver l’horodatage de la déclaration, pas uniquement le fait qu’elle a été cochée.
- Adapter le texte du message légal aux mentions sanitaires en vigueur, qui peuvent évoluer indépendamment du code.
Une case à cocher qui ne bloque rien du tout n’a de valeur que décorative : la conformité réelle se joue dans le contrôle serveur, jamais dans l’apparence du formulaire.
En résumé
Cette mise en conformité ne demandait ni service tiers ni extension payante, uniquement une combinaison de hooks déjà présents dans le cœur de WooCommerce : un champ de formulaire, une validation serveur bloquante, un enregistrement en métadonnée de commande, et un affichage clair côté administration. Le sujet de la vérification d’identité, plus poussée, avec pièce justificative, reste un chantier distinct, à traiter séparément si l’activité l’exige.