Comment utiliser le checkout hébergé ?
Créez une session de checkout, redirigez le client vers lomi., puis confirmez le résultat avec redirections, dashboard et webhooks.
Le checkout hébergé est l’intégration recommandée pour la plupart des équipes. Votre serveur crée une session, le client paie sur une page hébergée par lomi., puis votre système confirme le résultat.
À savoir : les sessions expirent par défaut après 60 minutes. Les clés test s’exécutent en mode sandbox. Règles transverses (codes promo, lignes, état du paiement) : Comportement du tunnel.
Quand utiliser le checkout hébergé ?
Utilisez-le si vous voulez :
- Une page de paiement complète avec plusieurs moyens de paiement.
- Moins de travail UI et conformité dans votre propre application.
- Un flux clair avec URL de succès et d’annulation.
- Un checkout basé sur un montant ou sur un produit.
- Un chemin fiable de la sandbox vers le live.
Créer une session de paiement
Votre serveur appelle POST /checkout-sessions et redirige le client vers checkout_url.
Référence API (schéma complet) : Créer une session de checkout
Champs essentiels :
| Champ | Notes |
|---|---|
currency_code | Obligatoire, XOF, USD ou EUR |
amount | Obligatoire sauf si vous passez product_id ou line_items |
product_id / price_id | Checkout catalogue ; montant dérivé du tarif |
success_url / cancel_url | Redirection après paiement ou annulation |
customer_email | Optionnel, préremplit le formulaire hébergé |
require_name / require_email / require_phone / require_billing_address | Optionnel, contrôle les champs du formulaire ; voir Champs du formulaire checkout |
Passez metadata pour vos propres identifiants de commande. Voir la page API pour tous les champs optionnels.
Produits « payez ce que vous voulez »
Lorsque product_id ou price_id pointe vers un tarif avec pricing_model: pay_what_you_want :
- Omettre
amount: la session utilise le prix unitaire suggéré (amountsur le tarif) ×quantity. - Fournir
amount: doit être un sous-total valide : prix unitaire dans[minimum_amount, maximum_amount]×quantity. Le serveur rejette les valeurs hors bornes. - Tunnel hébergé: l’acheteur peut modifier le prix unitaire avant de payer ; validation côté client et serveur.
- Flux programmatiques: définissez
amountà la création de session si le total est déjà connu.
Panier multi-produits (line_items)
Avec line_items, chaque ligne doit référencer un tarif ponctuel en tarification standard (fixe). L’API renvoie 400 avec l’un des codes :
| Code | Signification |
|---|---|
line_items_pwyw_not_supported | Une ligne utilise pay_what_you_want, utilisez une session mono-produit |
line_items_recurring_not_supported | Une ligne référence un produit récurrent |
line_items_usage_based_not_supported | Tarification à l’usage (pas encore prise en charge en panier) |
line_items_mixed_product_types | Mélange ponctuel et récurrent dans un même panier |
Produits récurrents (abonnements)
Lorsque product_id désigne un produit récurrent :
- Omettre
amount: la session utilise le prix catalogue duprice_idchoisi (la quantité n’est pas multipliée pour les abonnements). - Fournir
amount: doit correspondre au prix récurrent catalogue pour la validation (sauf prorata au moment du paiement ; voir Comportement du tunnel: Abonnements). - Essai ou inscription
non_initial: le client peut payer 0 au tunnel, mais la session enregistre souvent le prix catalogue pour quecreate_checkout_sessionrespecteamount > 0. N’envoyez pasamount: 0sans vous appuyer sur le calcul produit. - La finalisation crée un abonnement (webhook
SUBSCRIPTION_CREATED), pas seulement une transaction ponctuelle.
Exemple :
const subscriptionSession = await lomi.checkoutSessions.create({
product_id: 'prod_recurring_abc...',
price_id: 'price_monthly_xyz...',
currency_code: 'XOF',
customer_email: 'customer@example.com',
success_url: 'https://your-site.com/welcome',
allow_coupon_code: true,
});import { LomiSDK } from '@lomi./sdk';
const lomi = new LomiSDK({
apiKey: process.env.LOMI_SECRET_KEY!,
environment: 'live',
});
// Tunnel simple avec montant
const session = await lomi.checkoutSessions.create({
amount: 10000,
currency_code: 'XOF',
title: 'Order #12345',
description: 'Paiement des articles du panier',
customer_email: 'customer@example.com',
success_url: 'https://your-site.com/success',
cancel_url: 'https://your-site.com/cancel',
metadata: {
order_id: 'ORD-12345',
},
});
// Tunnel basé sur un produit
const productSession = await lomi.checkoutSessions.create({
product_id: 'prod_abc123...',
currency_code: 'XOF',
quantity: 2,
allow_coupon_code: true,
success_url: 'https://your-site.com/success',
});
// Produit PWYW avec montant personnalisé et quantité
const pwywSession = await lomi.checkoutSessions.create({
product_id: 'prod_tip_jar...',
currency_code: 'XOF',
amount: 1500,
quantity: 2,
success_url: 'https://your-site.com/success',
});
console.log(`Redirect to: ${session.checkout_url}`);from lomi import LomiClient
import os
client = LomiClient(
api_key=os.environ["LOMI_SECRET_KEY"],
environment="test"
)
session = client.checkout_sessions.create({
"amount": 10000,
"currency_code": "XOF",
"title": "Order #12345",
"description": "Payment for items in cart",
"customer_email": "customer@example.com",
"success_url": "https://your-site.com/success",
"cancel_url": "https://your-site.com/cancel",
"metadata": {
"order_id": "ORD-12345"
}
})
# Produit PWYW avec montant personnalisé et quantité
pwyw_session = client.checkout_sessions.create({
"product_id": "prod_tip_jar...",
"currency_code": "XOF",
"amount": 1500,
"quantity": 2,
"success_url": "https://your-site.com/success"
})
print(f"Redirect to: {session['checkout_url']}")curl -X POST "https://api.lomi.africa/checkout-sessions" \
-H "X-API-KEY: $LOMI_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency_code": "XOF",
"title": "Order #12345",
"description": "Payment for items in cart",
"customer_email": "customer@example.com",
"success_url": "https://your-site.com/success",
"cancel_url": "https://your-site.com/cancel",
"metadata": {
"order_id": "ORD-12345"
}
}'Réponse
{
"id": "cs_abc123...",
"checkout_url": "https://checkout.lomi.africa/cs_abc123...",
"status": "open",
"amount": 10000,
"currency_code": "XOF",
"title": "Order #12345",
"customer_email": "customer@example.com",
"expires_at": "2024-01-15T11:30:00Z",
"created_at": "2024-01-15T10:30:00Z"
}Intégrer sans redirection
Pour garder le client sur votre page, utilisez le SDK embed avec le même checkout_url :
import { loadLomiCheckout } from '@lomi./embed';
loadLomiCheckout({
checkoutUrl: session.checkout_url,
mode: 'modal',
onComplete: (payload) => console.log(payload.transactionId),
});Voir Widget de paiement intégré pour modal, inline et self-hosted.
Confirmer le paiement
Les redirections servent à l’expérience client, pas à la réconciliation finale. Votre serveur doit s’appuyer sur les webhooks ou une lecture API côté serveur avant de livrer une commande.
Vérifiez :
- Le statut de la session de checkout.
- Le statut de la transaction liée.
- Le montant, la devise, le client et les métadonnées.
- La signature webhook et l’ID d’événement.
Variantes courantes
| Variante | À utiliser quand |
|---|---|
| Montant fixe | Votre backend connaît déjà le montant |
| Checkout produit | Le montant vient d’un produit ou prix |
| Checkout abonnement | Le client démarre un plan récurrent |
| Coupons activés | Vous acceptez des codes promo |
| Checkout test | Vous validez avec lomi_sk_test_... |
Lister et récupérer les sessions
Utilisez la référence API pour lister ou récupérer une session par ID :
Webhooks
Les webhooks sortants marchands (lomi. appelle votre URL) utilisent l’énumération webhook_event documentée dans Webhooks. Le champ HTTP `event` et l’en-tête `X-Lomi-Event` reprennent ces valeurs (par ex. `PAYMENT_SUCCEEDED`).
Pour les résultats de tunnel côté votre serveur, souscrivez au minimum à :
Valeur authorized_events | Déclenchement |
|---|---|
`PAYMENT_SUCCEEDED` | Paiement terminé ; le corps `data` suit la forme transaction (voir Webhooks). |
`PAYMENT_FAILED` | Tentative échouée (y compris certains chemins d’échec prestataire). |
Il n’existe pas de valeur séparée `checkout.session.*` dans l’énumération `webhook_event`. L’expiration de session sans paiement réussi se voit sur les enregistrements session et transaction (statut `expired` par ex.) ; utilisez `GET /checkout-sessions/{id}` ou une liste avec `status=expired` / `completed` plutôt qu’un webhook marchand nommé comme checkout.session.expired.
Réponses d’erreur
| Statut | Description |
|---|---|
400 | Entrée invalide ou erreur de validation |
401 | Clé API invalide ou manquante |
404 | Session introuvable ou accès refusé |
API liée
Comment accepter les paiements par carte ?
Choisissez le checkout hébergé pour la plupart des flux carte, ou la collecte embarquée si votre app doit contrôler toute l’interface.
Widget de paiement intégré
Intégrez le checkout hébergé lomi. sur votre site avec @lomi./embed, fenêtre modale ou iframe inline.