Ibexa Commerce 4.6 : une promotion réservée aux clients VIP — REX VIP20
Après la remise catalogue et le code promotionnel classique, notre formation Ibexa Commerce aborde un cas plus proche d’un vrai projet B2C ou B2B : réserver une offre à une catégorie de clients.
Notre règle est volontairement lisible : un client du groupe vip reçoit 20 % de remise avec le code VIP20, à partir de 100 € HT et uniquement en EUR.
Ce que nous allons relier
Cette démonstration utilise quatre objets différents :
- un Customer Group Commerce nommé
vip; - un contenu utilisateur de type
customer, nommévip.demo; - un code promotionnel
VIP20; - une remise panier qui réunit toutes les conditions.
Un groupe client Commerce n’est pas un groupe d’utilisateurs Ibexa. Le premier sert au contexte commercial : prix personnalisés et promotions. Le second sert principalement à l’organisation des utilisateurs et à l’attribution des rôles et permissions.
1. Créer le groupe client et la promotion
La migration src/Migrations/Demo/16_vip_customer_promotion.yaml crée le groupe, le code et la remise :
- type: customer_group
mode: create
identifier: vip
names:
eng-GB: 'VIP customers'
global_price_rate: '0'
- type: discount_code
mode: create
code: VIP20
global_usage_limit: 100
user_usage_limit: 1
- type: discount
mode: create
identifier: demo_vip20
discount_type: cart
priority: 8
enabled: true
rule:
type: percentage
expressionValues:
discount_percentage: 20
conditions:
- identifier: is_in_currency
expressionValues:
currency_code: EUR
- identifier: minimum_purchase_amount
expressionValues:
minimum_purchase_amount: 100
- identifier: is_valid_discount_code
expressionValues:
discount_code: VIP20
usage_count: 1
global_usage_count: 100
- identifier: is_user_in_customer_group
expressionValues:
customer_groups: [vip]
Le code et la remise sont deux objets distincts. Le code représente ce que le client saisit et porte les limites d’usage. La remise contient le calcul et les conditions d’éligibilité.
2. Créer un client réellement rattaché au groupe
La migration 17_vip_customer.yaml crée vip.demo avec le Content Type customer. Son champ customer_group, de type ibexa_customer_group, pointe vers le groupe Commerce VIP.
- type: user
mode: create
metadata:
login: vip.demo
contentType: customer
groups:
- ibexa_customer_group
fields:
- fieldDefIdentifier: customer_group
fieldTypeIdentifier: ibexa_customer_group
languageCode: eng-GB
value:
customer_group_id: 2
Dans cette instance de formation, le groupe vip possède l’ID 2. Dans un projet déployé sur plusieurs environnements, il faut résoudre l’ID à partir de l’identifiant vip au lieu de figer une valeur locale.
3. Ne pas oublier les permissions Storefront
Notre premier test connecté a échoué avec :
The User does not have the 'view' 'customer_group' permission
Le moteur doit lire le groupe commercial du client pour résoudre son contexte de prix et ses promotions. Nous avons donc ajouté cette permission au rôle Storefront User dans 18_storefront_customer_group_permission.yaml :
- type: role
mode: update
match:
field: identifier
value: 'Storefront User'
policies:
mode: append
list:
- module: customer_group
function: view
Ce détail est important : une configuration correcte en Back Office ne suffit pas si l’utilisateur connecté n’a pas le droit de lire son contexte commercial.
4. Exécuter les migrations
php bin/console ibexa:migrations:migrate \
--file=16_vip_customer_promotion.yaml --dry-run
php bin/console ibexa:migrations:migrate \
--file=16_vip_customer_promotion.yaml
php bin/console ibexa:migrations:migrate \
--file=17_vip_customer.yaml
php bin/console ibexa:migrations:migrate \
--file=18_storefront_customer_group_permission.yaml
php bin/console ibexa:discounts:reindex
php bin/console cache:clear
5. Vérifier d’abord la logique en ligne de commande
La commande de démonstration crée un panier appartenant à vip.demo, ajoute quatre T-shirts puis fournit le code VIP20 :
php bin/console app:demo:vip-cart
Résultat obtenu :
owner=vip.demo
quantity=4
unit_amount=2392
code=VIP20
Les montants de l’API Commerce sont exprimés dans l’unité mineure : 2392 correspond à 23,92 €.
6. Tester dans le Storefront
Nous nous connectons avec le compte VIP, plaçons quatre T-shirts à 29,90 € HT dans le panier, puis saisissons VIP20.
La preuve visuelle confirme le calcul :
Prix avant remise : 4 × 29,90 € = 119,60 € HT
Remise VIP de 20 % : -23,92 €
Sous-total remisé : 95,68 € HT
TVA à 20 % : 19,12 €
Total : 114,80 € TTC
Le seuil de 100 € est évalué avant la remise. Le total HT peut donc passer sous 100 € après application de VIP20.
Après validation du Checkout, Ibexa crée la commande en conservant la réduction. L'ajout des 7,08 € de livraison porte le total final à 121,88 € TTC. La commande, le paiement et l'expédition commencent avec le statut Pending : ils poursuivront ensuite leurs workflows respectifs.
Ce qui se passe avec les autres promotions
Le produit possède déjà une remise catalogue de 10 %. Avant de saisir un code, le panier affiche donc 26,91 € HT par unité. Le code général IBEXA15 peut également appliquer 15 %.
Pour notre client VIP, VIP20 produit finalement 23,92 € HT par unité. Les remises actives coexistent dans la configuration, mais elles ne sont pas automatiquement additionnées : dans ce scénario, Ibexa retient la promotion panier applicable à la place de la remise catalogue.
Sans code : remise catalogue 10 % → 26,91 €
IBEXA15 : remise panier 15 % → 25,42 €
VIP20 : remise panier VIP 20 % → 23,92 €
Il faut donc tester les règles, leurs conditions et leurs priorités. « Plusieurs promotions actives » ne signifie pas « plusieurs promotions cumulées ».
Pourquoi ce mécanisme est intéressant
Ibexa Commerce permet de construire des offres adaptées au contexte client sans dupliquer les produits : tarifs fidélité, avantages partenaires, conditions revendeurs ou campagnes B2B. La même fiche produit peut ainsi produire un résultat commercial différent selon l’utilisateur connecté, sa devise, son groupe et son panier.
La séparation des responsabilités reste claire :
- le Content Type
customerdécrit le client ; - le Customer Group porte son segment commercial ;
- le code contrôle l’activation et les usages ;
- la remise contient les règles de calcul ;
- les permissions autorisent le Storefront à résoudre ce contexte.
Conclusion
Ce REX valide toute la chaîne : groupe VIP, client rattaché, permission Storefront, code limité, seuil de panier et calcul réel de 20 %. Le résultat n’est pas seulement visible dans le Back Office : il est vérifié en commande puis dans le panier du client connecté.
La prochaine étape naturelle sera la migration de cette formation d’Ibexa 4.6 vers Ibexa 5, en conservant ces scénarios comme tests de non-régression Commerce.

