Codes de réduction
Créez, validez, cumulez et suivez les coupons selon les mêmes règles qu’au tunnel de paiement.
L’API Discount Coupons assure une validation serveur stricte et un suivi d’usage pour les tunnels.
Exemples : Exemples de logique des coupons.
Cette page décrit le comportement des migrations logique promo :
- validation à la création ;
- validation au tunnel (client, périmètre, quantité, fréquence) ;
- application mono ou multi-coupon ;
- réservation d’usage dédupliquée et liaison transaction.
Fonctionnement de la logique coupon (bout en bout)
En résumé :
- Création du coupon (
create_discount_coupon). - Validation au tunnel (
validate_coupon_for_checkout/validate_coupon_for_frontend). - Calcul (
calculate_coupon_discount) et application (apply_coupon), ou plusieurs coupons (calculate_multi_coupon_discount,apply_coupons_to_checkout). - Réservation d’usage liée à la session dans
coupon_usage. - Liaison à la transaction (
link_or_insert_coupon_usage_for_transaction). - Incrément des compteurs à transaction complétée (
increment_coupon_usage_for_completed_transaction).
Le comportement reste ainsi déterministe entre l’aperçu front et l’enregistrement final.
Créer un coupon de réduction
Corps de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
code | string | Oui | Code unique (passé en majuscules automatiquement) |
discount_type | string | Non | percentage ou fixed (défaut : percentage) |
discount_percentage | number | Si pourcentage | Pourcentage (> 0 et <= 100) |
discount_fixed_amount | number | Si fixe | Montant fixe |
description | string | Non | Description |
is_active | boolean | Non | Actif (défaut : true) |
max_uses | number | Non | Plafond total d’utilisations |
max_quantity_per_use | number | Non | Quantité max par utilisation |
valid_from | string | Non | Début (ISO 8601) |
expires_at | string | Non | Fin (ISO 8601) |
customer_type | string | Non | all, new, returning |
usage_frequency_limit | string | Non | total, per_customer, per_day, per_week, per_month |
usage_limit_value | number | Conditionnel | Requis si usage_frequency_limit != total |
scope_type | string | Non | organization_wide, specific_products, specific_prices |
product_ids | array | Non | IDs produits (si périmètre spécifique) |
Règles à la création
À la création, l’API impose :
- unicité du code par organisation ;
- exclusion mutuelle pourcentage vs fixe ;
valid_from < expires_atlorsque les deux existent ;usage_limit_valuerequis pour les modes autre quetotal;- pour
specific_products/specific_prices, produits liés à la même organisation.
import { LomiSDK } from '@lomi./sdk';
const lomi = new LomiSDK({
apiKey: process.env.LOMI_API_KEY!,
environment: 'live',
});
// Percentage discount
const coupon = await lomi.discountCoupons.create({
code: 'SAVE20',
discount_type: 'percentage',
discount_percentage: 20,
description: '20% off all products',
max_uses: 100,
expires_at: '2024-12-31T23:59:59Z',
});
// Fixed amount discount
const fixedCoupon = await lomi.discountCoupons.create({
code: 'FLAT5000',
discount_type: 'fixed',
discount_fixed_amount: 5000,
description: '5000 XOF off',
customer_type: 'new',
});
console.log(`Coupon created: ${coupon.code}`);from lomi import LomiClient
import os
client = LomiClient(
api_key=os.environ["LOMI_API_KEY"],
environment="test"
)
coupon = client.discount_coupons.create({
"code": "SAVE20",
"discount_type": "percentage",
"discount_percentage": 20,
"description": "20% off all products",
"max_uses": 100,
"expires_at": "2024-12-31T23:59:59Z"
})
print(f"Coupon created: {coupon['code']}")curl -X POST "https://api.lomi.africa/discount-coupons" \
-H "X-API-KEY: $LOMI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "SAVE20",
"discount_type": "percentage",
"discount_percentage": 20,
"description": "20% off all products",
"max_uses": 100,
"expires_at": "2024-12-31T23:59:59Z"
}'Validation au tunnel
La validation combine contrôles structurels et métier. Un coupon doit satisfaire tous les points suivants :
- Existe et actif pour la même organisation.
- Fenêtre temporelle :
valid_fromdémarrée etexpires_atnon dépassée. - Plafond global :
current_uses < max_uses(simax_uses). - Fréquence client (si activée) : par client/jour/semaine/mois.
- Quantité : quantité du tunnel ≤
max_quantity_per_use. - Éligibilité client :
new: aucune transaction de paiement ou d’échéance complétée dans l’org ;returning: au moins une telle transaction ;all: sans restriction d’historique.
- Périmètre :
organization_wide: tous les produits ;specific_products/specific_prices: liaison danscoupon_product_links.
En cas d’échec, l’API renvoie un message explicite.
Calcul de la réduction
calculate_coupon_discount applique la remise sur le montant de base hors frais optionnels :
base_price = p_base_amount - p_fees_amount;- coupon pourcentage :
discount = base_price * percentage; - coupon fixe :
discount = fixed_amount; - multiplication par quantité si pertinent ;
- plafonnement pour ne pas dépasser la base éligible ;
- montant final
(base_price - discount) + frais.
Cela évite totaux négatifs et sur-remises.
Cumul multi-coupons (séquentiel)
Les coupons s’appliquent dans l’ordre sur un montant courant :
- A sur le montant initial ;
- B sur le montant après A ;
C’est un cumul séquentiel, pas une somme parallèle. La réponse détaille pour chaque coupon le montant d’origine, la remise et le résultat.
Si un coupon du tableau échoue à la validation, tout le calcul multi-coupon échoue.
Suivi d’usage et déduplication
L’usage est enregistré dans coupon_usage avec garde-fous contre les réservations en double :
- réservation unique par
(coupon_id, checkout_session_id)tant quetransaction_id IS NULL; - nettoyage des doublons obsolètes avant l’index unique partiel ;
- à paiement terminé, liaison à la transaction (sans doublon) ;
- sinon insertion directe liée à la transaction.
Comportement attendu pour nouvelles tentatives prestataire et courses entre webhooks.
Lister les coupons
Récupère tous les coupons de réduction de votre organisation.
const coupons = await lomi.discountCoupons.list();coupons = client.discount_coupons.list()curl -X GET "https://api.lomi.africa/discount-coupons" \
-H "X-API-KEY: $LOMI_API_KEY"Obtenir un coupon
Récupère le détail d’un coupon.
const coupon = await lomi.discountCoupons.get('dc_abc123...');coupon = client.discount_coupons.get('dc_abc123...')curl -X GET "https://api.lomi.africa/discount-coupons/dc_abc123..." \
-H "X-API-KEY: $LOMI_API_KEY"Indicateurs de performance d’un coupon
Statistiques d’usage et impact chiffre d’affaires pour un coupon (transactions completed uniquement).
const performance = await lomi.discountCoupons.getPerformance('dc_abc123...');
console.log(`Total uses: ${performance.total_uses}`);
console.log(`Total discounted: ${performance.total_discount_amount}`);
console.log(`Revenue generated: ${performance.total_revenue}`);
console.log(`Avg order value: ${performance.average_order_value}`);performance = client.discount_coupons.get_performance('dc_abc123...')
print(f"Total uses: {performance['total_uses']}")curl -X GET "https://api.lomi.africa/discount-coupons/dc_abc123.../performance" \
-H "X-API-KEY: $LOMI_API_KEY"Réponse
{
"total_uses": 45,
"total_discounts": 25000,
"total_revenue": 150000,
"average_discount": 555.56,
"unique_customers": 38
}Objet Discount Coupon
| Champ | Type | Description |
|---|---|---|
id | string | Identifiant unique |
code | string | Code |
discount_type | string | percentage ou fixed |
discount_percentage | number | Valeur pourcentage |
discount_fixed_amount | number | Montant fixe |
customer_type | string | all, new, returning |
usage_frequency_limit | string | total, per_customer, per_day, per_week, per_month |
usage_limit_value | number | Plafond de fréquence le cas échéant |
is_active | boolean | Actif |
max_uses | number | Maximum d’utilisations |
current_uses | number | Utilisations courantes |
max_quantity_per_use | number | Quantité max par utilisation |
valid_from | string | Début de validité |
expires_at | string | Expiration |
scope_type | string | Périmètre |
product_links | array | Produits liés si périmètre spécifique |
completed_redemptions | number | Utilisations terminées |
distinct_customers_completed | number | Clients distincts avec utilisations complétées |
created_at | string | Création |
Modèles d’implémentation courants
Valider avant d’appliquer
- valider le coupon (endpoint de pré-validation),
- afficher un aperçu de la remise,
- appliquer à la création ou confirmation du tunnel.
Gérer les relances prestataires
Les callbacks peuvent être renvoyés. La réservation / liaison coupon est pensée pour être idempotente par paire session + coupon.
Fournir le client quand c’est possible
Pour les coupons new et returning, envoyez customer_id pour une évaluation d’éligibilité correcte.
Réponses d’erreur
| Statut | Description |
|---|---|
400 | Entrée invalide ou code en double |
401 | Clé API invalide ou manquante |
404 | Coupon introuvable |