lomi.
Payments

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é :

  1. Création du coupon (create_discount_coupon).
  2. Validation au tunnel (validate_coupon_for_checkout / validate_coupon_for_frontend).
  3. Calcul (calculate_coupon_discount) et application (apply_coupon), ou plusieurs coupons (calculate_multi_coupon_discount, apply_coupons_to_checkout).
  4. Réservation d’usage liée à la session dans coupon_usage.
  5. Liaison à la transaction (link_or_insert_coupon_usage_for_transaction).
  6. 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

ChampTypeObligatoireDescription
codestringOuiCode unique (passé en majuscules automatiquement)
discount_typestringNonpercentage ou fixed (défaut : percentage)
discount_percentagenumberSi pourcentagePourcentage (> 0 et <= 100)
discount_fixed_amountnumberSi fixeMontant fixe
descriptionstringNonDescription
is_activebooleanNonActif (défaut : true)
max_usesnumberNonPlafond total d’utilisations
max_quantity_per_usenumberNonQuantité max par utilisation
valid_fromstringNonDébut (ISO 8601)
expires_atstringNonFin (ISO 8601)
customer_typestringNonall, new, returning
usage_frequency_limitstringNontotal, per_customer, per_day, per_week, per_month
usage_limit_valuenumberConditionnelRequis si usage_frequency_limit != total
scope_typestringNonorganization_wide, specific_products, specific_prices
product_idsarrayNonIDs 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_at lorsque les deux existent ;
  • usage_limit_value requis pour les modes autre que total ;
  • 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 :

  1. Existe et actif pour la même organisation.
  2. Fenêtre temporelle : valid_from démarrée et expires_at non dépassée.
  3. Plafond global : current_uses < max_uses (si max_uses).
  4. Fréquence client (si activée) : par client/jour/semaine/mois.
  5. Quantité : quantité du tunnel ≤ max_quantity_per_use.
  6. É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.
  7. Périmètre :
    • organization_wide : tous les produits ;
    • specific_products / specific_prices : liaison dans coupon_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 que transaction_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

ChampTypeDescription
idstringIdentifiant unique
codestringCode
discount_typestringpercentage ou fixed
discount_percentagenumberValeur pourcentage
discount_fixed_amountnumberMontant fixe
customer_typestringall, new, returning
usage_frequency_limitstringtotal, per_customer, per_day, per_week, per_month
usage_limit_valuenumberPlafond de fréquence le cas échéant
is_activebooleanActif
max_usesnumberMaximum d’utilisations
current_usesnumberUtilisations courantes
max_quantity_per_usenumberQuantité max par utilisation
valid_fromstringDébut de validité
expires_atstringExpiration
scope_typestringPérimètre
product_linksarrayProduits liés si périmètre spécifique
completed_redemptionsnumberUtilisations terminées
distinct_customers_completednumberClients distincts avec utilisations complétées
created_atstringCréation

Modèles d’implémentation courants

Valider avant d’appliquer

  1. valider le coupon (endpoint de pré-validation),
  2. afficher un aperçu de la remise,
  3. 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

StatutDescription
400Entrée invalide ou code en double
401Clé API invalide ou manquante
404Coupon introuvable

Sur cette page