Exemples de logique des coupons
Exemples concrets pour l’éligibilité client, le cumul et les usages idempotents des coupons.
Cette page complète la référence Codes de réduction avec des scénarios tirés de la logique promo en production.
Exemple 1 : coupon réservé aux nouveaux clients
Configuration du coupon :
customer_type = newscope_type = organization_widediscount_type = percentagediscount_percentage = 20
Comportement :
- Client sans transaction de paiement / échéance complétée dans l’organisation : coupon valide.
- Client ayant au moins une transaction de paiement / échéance complétée : coupon refusé (non éligible).
- Sans contexte client, les contrôles d’éligibilité pour les types restreints peuvent échouer.
Exemple 2 : coupon réservé aux clients récurrents
Configuration :
customer_type = returningusage_frequency_limit = per_monthusage_limit_value = 1
Comportement :
- Un client récurrent peut utiliser une fois par mois.
- Une deuxième utilisation dans le même mois est refusée.
- Un nouveau mois autorise à nouveau une utilisation (sous autres limites).
Exemple 3 : coupon limité à certains produits
Configuration :
scope_type = specific_productsproduct_ids = [Produit A, Produit B]
Comportement :
- Tunnel pour les produits A ou B : les contrôles de périmètre passent.
- Tunnel pour le produit C : refus (« coupon non applicable à ce produit »).
- Les coupons à l’échelle de l’organisation ignorent la vérification par produit.
Exemple 4 : coupon plafonné par quantité
Configuration :
max_quantity_per_use = 2
Comportement :
- Quantité
1ou2: valide. - Quantité
3ou plus : refus avec message lié au plafond quantité.
Exemple 5 : remise fixe bornée au montant de base
Tunnel :
- Montant de base :
3 000 - Montant des frais :
500 - Prix de base éligible :
2 500
Coupon :
discount_type = fixeddiscount_fixed_amount = 5 000
Résultat :
- La remise est plafonnée à
2 500(ne peut pas dépasser la base éligible). - Le montant final est
(2 500 - 2 500) + 500 = 500.
Exemple 6 : cumul séquentiel (deux coupons)
Montant au tunnel : 10 000
Coupons dans l’ordre :
SAVE20(20 %)FLAT1000(fixe 1 000)
Calcul séquentiel :
- Après
SAVE20: remise2 000, montant courant8 000 - Après
FLAT1000: remise1 000, montant courant7 000 - Remise totale :
3 000
Important : le second coupon s’applique au montant réduit restant, pas au montant d’origine.
Exemple 7 : réservation en attente et liaison transaction
Flux :
- Application du coupon à la session de paiement.
- Enregistrement d’une réservation
coupon_usageen attente pour(coupon_id, checkout_session_id). - Callback prestataire crée ou finalise la transaction.
- La réservation est liée à la transaction.
Pourquoi c’est important :
- Évite les lignes d’usage en double lors des nouvelles tentatives ou courses entre webhooks.
- Garde des indicateurs cohérents quand les prestataires réessayent les callbacks.
Exemple 8 : nouvelle tentative sûre
Si le même événement prestataire est renvoyé :
- une réservation en attente existante est mise à jour ou liée lorsque c’est possible ;
- les doublons sont évités grâce à l’unicité et à la gestion des conflits ;
- le comptage d’usage reste cohérent à la complétion de la transaction.
Exemple 9 : l’ordre du cumul change la remise totale
Les mêmes deux coupons que l’exemple 6, mais ordre inverse :
FLAT1000d’abord : remise1 000, montant courant9 000SAVE20ensuite : 20 % de9 000=1 800, montant courant7 200- Remise totale :
2 800(et non3 000)
Affichez toujours l’ordre d’application dans l’interface et conservez ce même ordre côté serveur.
Exemple 10 : fréquence d’usage — fenêtre glissante vs calendrier
Selon le chemin de validation, les plafonds peuvent être évalués différemment :
- Un chemin compte les lignes d’usage coupon dans une fenêtre glissante (par ex. dernières 24 h pour
per_day). - Un autre rattache
per_day/per_week/per_monthaux bornes calendaires.
Pour un coupon « une utilisation par jour », un client utilisant à 23 h 59 peut ou non pouvoir réutiliser à 0 h 01 le lendemain, selon l’assistant invoqué par votre stack tunnel. Considérez les limites comme « au plus N utilisations sur la période configurée » et testez dans le bac à sable.
Exemple 11 : réapplication d’un coupon sur la même session
Lorsqu’un coupon est appliqué à une session qui a déjà une ligne coupon_usage en attente, le système peut fusionner (upsert) cette ligne (mettre à jour remise et horodateurs) au lieu d’insérer des doublons — tant que la transaction n’est pas finalisée.
Conséquences :
- Changer le code promo ou recalculer le panier doit remplacer la réservation en attente, pas empiler des lignes.
- Après paiement réussi, l’usage repose sur la transaction ; ne comptez pas uniquement sur les lignes « session » pour la comptabilité.
Exemple 12 : tunnels gratuits ou entièrement remisés
Lorsque la remise ramène le montant payable à zéro (campagnes 100 % off par ex.), la plateforme peut enregistrer un parcours gratuit avec codes prestataire / méthode dédiés pour garder grand livre et webhooks cohérents.
Les rapports marchands doivent toujours montrer prix catalogue, remise et net.
Exemple 13 : nouvelles tentatives côté client
Votre appli réessaie POST /checkout-sessions ou « apply coupon » à cause du réseau :
- utilisez la même clé d’idempotence ou le même identifiant de session pour éviter des sessions parallèles ;
- les webhooks de complétion en double ne devraient pas doubler le comptage si la complétion transaction est idempotente — évitez tout de même les applications répétées initiées par le client.
Checklist d’intégration
- Toujours valider avant l’application finale.
- Envoyer le contexte client pour les coupons
new/returning. - Rendre idempotente l’application de coupon lors des nouvelles tentatives client.
- Pour plusieurs coupons, conserver l’ordre prévu dans l’UX.
- Documenter en interne si les remises pourcentage ou fixe passent en premier (décision métier ; impact sur les totaux).