Le client vend des articles de puériculture et voulait, avant les fêtes de Pâques, proposer des cartes cadeaux dématérialisées. Budget alloué : zéro euro d’extension supplémentaire. La demande tenait en une phrase : « quelqu’un achète un produit « Carte cadeau 50 € », il reçoit par mail un code qu’il peut utiliser à la caisse ». Rien dans WooCommerce ne fait ça nativement, mais tout ce qu’il faut pour le construire est déjà présent dans le cœur du plugin.
Pas question ici de programme de fidélité à points ni de cagnotte cumulable : simplement un produit qui, une fois payé, engendre un coupon utilisable une seule fois. C’est un besoin fréquent chez les commerçants qui vendent un service ou un produit périssable et veulent offrir un geste commercial ponctuel sans complexifier leur back-office.
Modéliser le bon cadeau comme un produit classique
Le plus simple est de créer un produit WooCommerce standard, de type simple, nommé par exemple « Carte cadeau ». On y ajoute un attribut personnalisé ou, mieux, un champ produit personnalisé pour stocker le montant du bon (50, 100 ou 150 euros selon les variantes). Ce produit n’a pas besoin de gestion de stock ni d’expédition : il faut simplement cocher « Produit virtuel » dans les réglages.
La logique métier se branche ensuite sur la validation de la commande, via le hook woocommerce_order_status_completed plutôt que sur woocommerce_thankyou, pour éviter de générer un coupon avant que le paiement soit réellement confirmé.
Générer le coupon à l’aide de la classe WC_Coupon

Depuis l’arrivée du CRUD dans WooCommerce 3.0, il n’est plus nécessaire de manipuler directement wp_insert_post pour créer un coupon : la classe WC_Coupon expose des accesseurs dédiés.
add_action( 'woocommerce_order_status_completed', 'gc_generer_bon_cadeau' );
function gc_generer_bon_cadeau( $order_id ) {
$order = wc_get_order( $order_id );
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( ! $product || ! $product->is_type( 'simple' ) ) {
continue;
}
if ( ! has_term( 'carte-cadeau', 'product_cat', $product->get_id() ) ) {
continue;
}
$montant = (float) $product->get_meta( '_gc_montant' );
$code = 'GC-' . strtoupper( wp_generate_password( 8, false ) );
$coupon = new WC_Coupon();
$coupon->set_code( $code );
$coupon->set_discount_type( 'fixed_cart' );
$coupon->set_amount( $montant );
$coupon->set_individual_use( true );
$coupon->set_usage_limit( 1 );
$coupon->set_date_expires( strtotime( '+1 year' ) );
$coupon->save();
update_post_meta( $order_id, '_gc_code_genere', $code );
gc_envoyer_mail_bon_cadeau( $order, $code, $montant );
}
}
Le préfixe GC- permet de repérer d’un coup d’œil, dans la liste des coupons, ceux qui viennent de ce circuit automatisé plutôt que d’une opération marketing manuelle. Le tirage aléatoire évite les codes devinables du type CADEAU50, trop souvent partagés en dehors du cercle du destinataire prévu.
Envoyer le mail de livraison
WooCommerce dispose déjà d’un système d’e-mails transactionnels basé sur WC_Email, mais pour un besoin ponctuel, un simple appel à wp_mail() dans le même hook fait très bien l’affaire, à condition de soigner le contenu HTML.
function gc_envoyer_mail_bon_cadeau( $order, $code, $montant ) {
$destinataire = $order->get_billing_email();
$sujet = sprintf( 'Votre carte cadeau de %d €', $montant );
$corps = '<p>Merci pour votre achat.</p>';
$corps .= '<p>Voici votre code, à saisir dans le panier :</p>';
$corps .= '<p style="font-size:22px;"><strong>' . esc_html( $code ) . '</strong></p>';
add_filter( 'wp_mail_content_type', function () {
return 'text/html';
} );
wp_mail( $destinataire, $sujet, $corps );
}
Quelques précautions s’imposent sur ce point précis :
- Retirer le filtre
wp_mail_content_typejuste après l’envoi, sinon tous les mails suivants de la requête passent en HTML. - Vérifier que
get_billing_email()renvoie bien une adresse, notamment sur les commandes passées par un compte administrateur en test. - Consigner le code envoyé dans une métadonnée de commande, pour pouvoir le retrouver depuis le support client sans fouiller les journaux de mail.
Variantes utiles selon le contexte commercial
Le montant fixe convient à une carte cadeau classique, mais certains commerces préfèrent une réduction en pourcentage plafonnée, par exemple pour un bon de bienvenue. Il suffit alors de remplacer fixed_cart par percent et d’ajouter une limite avec set_maximum_amount() côté panier, cette dernière n’étant pas nativement supportée par la classe et nécessitant un contrôle manuel via woocommerce_coupon_is_valid.
Autre variante fréquente : plutôt qu’un envoi immédiat, différer la génération du coupon à une date choisie par l’acheteur, pour un anniversaire par exemple. Il faut alors stocker la date cible en métadonnée de commande et déclencher la génération via une tâche planifiée avec wp_schedule_single_event(), plutôt que dans le hook de complétion de commande.
Sur ce genre de circuit, mieux vaut toujours enregistrer le code généré dans une métadonnée de commande consultable depuis l’administration : le jour où un client dit ne rien avoir reçu, c’est la première chose que le support ira vérifier.
Ce qu’on retient
Construire un système de bons cadeaux fonctionnel ne demande ni base de données supplémentaire ni extension premium : la classe WC_Coupon, un hook sur la complétion de commande et un mail HTML suffisent pour un besoin de ce type. La limite de cette approche apparaît surtout à l’échelle : au-delà de quelques dizaines de bons par mois, il devient pertinent d’ajouter un tableau de suivi dans l’administration, avec un statut « utilisé / non utilisé » lisible sans passer par la liste générale des coupons WooCommerce, qui n’a pas été pensée pour ce cas d’usage.