Configurer les webhooks
Les webhooks permettent à votre application de recevoir des notifications en temps réel sur les événements qui se produisent dans votre compte lomi., comme les paiements réussis, les nouveaux abonnements ou les transactions échouées.
Au lieu d’interroger constamment l’API pour détecter les changements, vous pouvez configurer lomi. pour qu’elle envoie des requêtes HTTP POST vers un point de terminaison que vous contrôlez dès qu’un événement précis se produit.
Pour les tentatives, les doublons de livraison et le débogage des journaux de livraison, voir Fiabilité des webhooks.
Pourquoi utiliser des webhooks ?
- Mises à jour en temps réel : soyez informé immédiatement des événements importants.
- Automatisation : déclenchez des actions dans vos systèmes automatiquement (par ex. mise à jour des fiches clients, provisionnement des services, e-mails de confirmation, logiciel comptable).
- Efficacité : évitez les sondages (polling) inutiles sur l’API et économisez des ressources.
- Fiabilité accrue : réagissez rapidement aux événements comme les paiements échoués.
Événements webhook disponibles
Vous pouvez vous abonner aux notifications pour les événements suivants :
PAYMENT_CREATED: une nouvelle tentative de paiement a été initiée.PAYMENT_SUCCEEDED: un paiement s’est terminé avec succès.PAYMENT_FAILED: une tentative de paiement a échoué.REFUND_CREATED: un remboursement a été initié.REFUND_COMPLETED: un remboursement a été traité avec succès.REFUND_FAILED: le processus de remboursement a échoué.SUBSCRIPTION_CREATED: un nouvel abonnement a été créé.SUBSCRIPTION_RENEWED: un abonnement a été renouvelé avec succès.SUBSCRIPTION_CANCELLED: un abonnement a été annulé.
Mettre en place votre point de terminaison webhook
Avant de configurer un webhook dans lomi., vous devez créer un point de terminaison (une URL) sur votre serveur qui :
- est accessible publiquement en HTTPS ;
- peut recevoir des requêtes HTTP POST avec un corps JSON ;
- est prêt à traiter les données webhook entrantes de lomi..
Pour le développement et les tests locaux, vous pouvez utiliser des outils comme ngrok ou localtunnel pour exposer votre serveur local sur Internet, ou des services en ligne comme Webhook.site ou Beeceptor pour des points de terminaison temporaires.
Configurer les webhooks dans lomi.
Une fois votre point de terminaison prêt, configurez-le dans votre tableau de bord marchand lomi. (ou via l’API LOMI) :
- Allez dans la section Developers → Webhooks de votre tableau de bord lomi..
- Cliquez sur « Add Endpoint » ou « Create Webhook ».
- Saisissez l’URL du point de terminaison (l’URL HTTPS publiquement accessible que vous avez préparée).
- Sélectionnez les événements auxquels vous souhaitez vous abonner pour ce point de terminaison. Vous pouvez en choisir plusieurs.
- Cliquez sur « Create Webhook ».
- Copiez impérativement le
Signing Secretgénéré (il commence parwhsec_). Ce secret est propre à ce point de terminaison webhook et est indispensable pour vérifier les requêtes entrantes. Stockez-le en lieu sûr sur votre serveur ; vous en aurez besoin pour vérifier les signatures. Voir le guide Clés d’API pour la gestion des secrets.
Recevoir les webhooks
Lorsqu’un événement auquel vous êtes abonné se produit, lomi. envoie une requête HTTP POST vers l’URL configurée avec les caractéristiques suivantes :
- Méthode :
POST - Content-Type :
application/json - En-têtes :
X-Lomi-Event: le type d’événement ayant déclenché le webhook (par ex.PAYMENT_SUCCEEDED).X-Lomi-Signature: la signature calculée par lomi. pour cette requête. Vous DEVEZ l’utiliser pour vérifier l’authenticité de la requête.User-Agent:Lomi-Webhook/1.0
- Corps : un objet JSON contenant les détails de l’événement.
Structure de la charge utile
La charge JSON aura la structure suivante. L’objet data contient en général la ressource concernée (par ex. Transaction, Abonnement) avec les champs internes et de rapprochement prestataire retirés lorsque c’est pertinent. Appuyez-vous sur les identifiants lomi (par ex. `transaction_id` et les clés `metadata` que vous définissez au checkout) ; ne supposez pas la présence d’identifiants spécifiques à un processeur dans le JSON webhook.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"event": "PAYMENT_SUCCEEDED",
"timestamp": "2023-10-27T10:30:00.000Z",
"data": {
"transaction_id": "txn_abc123...",
"organization_id": "org_123abc...",
"customer_id": "cus_def456...",
"amount": 10000,
"currency_code": "XOF",
"status": "completed",
"provider_code": "WAVE",
"created_at": "2023-10-27T10:29:55.000Z",
"updated_at": "2023-10-27T10:30:00.000Z",
"metadata": {
"order_id": "ord_98765"
}
},
"lomi_environment": "production"
}L’identifiant racine `id` est un UUID pour l’idempotence (sans préfixe `evt_`). Le champ lomi_environment reflète l’`NODE_ENV` de l’hôte qui envoie (production, development, etc.) ; servez-vous‑en comme diagnostic, pas comme substitut aux couples URL/clés bac à sable vs production du côté client.
Vérifier les signatures
C’est l’étape la plus importante. La vérification de la signature garantit que la requête webhook provient bien de lomi. et qu’elle n’a pas été altérée en transit. Ne traitez pas les webhooks sans vérifier la signature.
lomi. calcule la signature à l’aide d’un code d’authentification de message basé sur le hachage (HMAC) avec SHA256.
Étapes de vérification :
- Extraire la signature : récupérez la valeur de l’en-tête
X-Lomi-Signaturede la requête entrante. - Obtenir la charge brute : vous avez besoin du corps brut de la requête sous forme de chaîne, exactement tel qu’il a été reçu, avant tout parsing ou modification JSON. L’accès dépend de votre framework web (voir les exemples ci-dessous).
- Préparer le HMAC : avec votre
Signing Secretconservé en sécurité (la chaînewhsec_…fournie par lomi. pour ce point de terminaison) comme clé, calculez le hachage HMAC SHA256 de la chaîne du corps brut. - Comparer : comparez le hachage que vous calculez (au format hexadécimal) à la signature extraite de l’en-tête. Utilisez une fonction de comparaison à temps constant pour prévenir les attaques par timing. S’ils correspondent, la requête est valide.
Exemples de code pour la vérification de signature
Remplacez 'your-webhook-signing-secret' par le secret réel de votre point de terminaison (de préférence récupéré via des variables d’environnement comme process.env.LOMI_WEBHOOK_SECRET).
Node.js (avec Express) :
const crypto = require('crypto');
const express = require('express');
// Store your secret securely (e.g., in environment variables)
const LOMI_WEBHOOK_SECRET = process.env.LOMI_WEBHOOK_SECRET;
// Middleware to get raw body
app.use('/your-webhook-endpoint', express.raw({ type: 'application/json' }));
app.post('/your-webhook-endpoint', (req, res) => {
if (!LOMI_WEBHOOK_SECRET) {
console.error('Webhook secret is not configured.');
return res.status(500).send('Webhook configuration error');
}
const receivedSignature = req.headers['x-lomi-signature'];
// req.body contains the raw buffer because of express.raw()
const rawBody = req.body;
if (!receivedSignature || !rawBody) {
return res.status(400).send('Missing signature or body');
}
try {
const expectedSignature = crypto
.createHmac('sha256', LOMI_WEBHOOK_SECRET)
.update(rawBody)
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(receivedSignature),
Buffer.from(expectedSignature),
);
if (!isValid) {
return res.status(400).send('Invalid signature');
}
// Signature verified
const event = JSON.parse(rawBody.toString());
// --- Process event data (event.data) ---
res.status(200).json({ received: true });
} catch (error) {
console.error('Error verifying webhook:', error);
return res.status(400).send(`Webhook Error: ${error.message}`);
}
});Python (avec Flask) :
import hmac
import hashlib
import json
import os
from flask import Flask, request, abort
app = Flask(__name__)
# Store your secret securely
LOMI_WEBHOOK_SECRET = os.environ.get('LOMI_WEBHOOK_SECRET')
@app.route('/your-webhook-endpoint', methods=['POST'])
def webhook_listener():
if not LOMI_WEBHOOK_SECRET:
print('Webhook secret is not configured.')
abort(500)
received_signature = request.headers.get('X-Lomi-Signature')
raw_body = request.get_data() # Get raw body as bytes
if not received_signature:
abort(400)
try:
expected_signature = hmac.new(
LOMI_WEBHOOK_SECRET.encode('utf-8'), # Encode secret to bytes
raw_body,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(received_signature, expected_signature):
abort(400)
# Signature verified
event = json.loads(raw_body.decode('utf-8'))
# --- Process event data (event['data']) ---
return json.dumps({'received': True}), 200
except Exception as e:
print(f"Error processing webhook: {e}")
abort(400)Répondre aux webhooks
Votre point de terminaison DOIT répondre rapidement à la requête webhook avec un code HTTP dans la plage 2xx (par ex. 200 OK). Cela accuse réception auprès de lomi..
- Répondre immédiatement : accusez réception avant toute logique complexe ou appels API externes susceptibles de dépasser le délai d’attente.
- Reporter le traitement : si le traitement de l’événement est long, utilisez une file d’attente de tâches en arrière-plan (Redis/Celery, BullMQ, Sidekiq, etc.) pour traiter le travail de façon asynchrone après l’envoi de la réponse
200 OK.
Pourquoi répondre d’abord ? Tant que lomi ne reçoit pas un 2xx, la livraison n’est pas considérée comme acceptée par votre système. L’usage attendu après vérification de la signature est d’accuser réception (« j’ai reçu cet envoi sans altération ») ; tout le traitement métier lourd passe ensuite dans vos workers ou votre base.
Chaque tentative côté lomi utilise un délai d’expiration HTTP borné (environ quatre secondes). Si votre serveur ne termine pas la réponse HTTP dans cette fenêtre, la tentative échoue pour ce tour. Dans des conditions normales, renvoyer 200 ou 204 prend typiquement bien moins d’une seconde ; après cela vous pouvez enfiler le travail long dans vos files internes. Chiffres, backoff et exceptions détaillés : Fiabilité des webhooks — Délais et tentatives.
Nouvelles tentatives
Sans réponse 2xx exploitable ou en cas de timeout pour une tentative donnée, lomi enregistre un échec pour cet essai. Selon les circonstances, d’autres tentatives peuvent avoir lieu plus tard jusqu’aux plafonds décrits dans le guide fiabilité.
- Pour les problèmes réessayables (souvent 5xx, pannes réseau transitoires, ou timeout côté client HTTP de la tentative précédente), lomi peut appliquer un recul exponentiel et rejouer un nombre limité d’essais. Le nombre maximal diffère suivant que l’événement part sur le chemin synchrone ou mis en file (voir le guide détaillé).
- Les erreurs client 4xx (dont 401, 404, ou un 400 dû à votre logique applicative) sont en principe non réessayables sur le même flux : lomi ne répète pas indéfiniment si la configuration de votre endpoint est en cause. Corrigez la route ou l’auth, puis relancez manuellement depuis le tableau de bord ou l’API si besoin.
L’idempotence reste indispensable : retries légitimes, doublons de job, ou rejeu manuel peuvent faire arriver plusieurs fois le même événement logique. Concevez vos handlers pour qu’un second traitement soit inoffensif : conservez le champ `id` à la racine (UUID) avec vos clés métier (par ex. `transaction_id` ou vos propres métadonnées), utilisez des contraintes d’unicité quand c’est pertinent, et préférez « déjà traité → no-op » à une erreur bloquante.
Pour tableaux, variables d’environnement et détail d’implémentation, la référence canonique est Fiabilité des webhooks — Délais et tentatives.
Tester les webhooks
Vous pouvez tester votre intégration avec la fonction « Test Webhook » du tableau de bord lomi. (Developers → Webhooks → sélectionner le point de terminaison → Test). Cela envoie une charge de test PAYMENT_SUCCEEDED vers votre URL configurée, ce qui permet de vérifier la réception et la vérification de signature sans transaction réelle.
Synthèse des bonnes pratiques
- Vérifier les signatures : vérifiez toujours
X-Lomi-Signatureavec votre secret de signature et une comparaison à temps constant. - Répondre vite : renvoyez un
`200 OK`ou autre2xxdès que la signature est valide — bien avant le délai de lecture sortant (environ quatre secondes) décrit dans le guide fiabilité. - Traiter en asynchrone : reportez la logique complexe vers des jobs en arrière-plan.
- Gérer les doublons (idempotence) : prévoyez de recevoir le même événement plusieurs fois. Vérifiez l’
idde l’événement. - Utiliser HTTPS : assurez-vous que votre point de terminaison utilise HTTPS.
- Sécuriser le secret : gardez le secret de signature webhook confidentiel. Ne le committez pas dans le dépôt. Utilisez des variables d’environnement ou un gestionnaire de secrets (voir le guide Clés d’API).
Dépannage
- Consulter les journaux de livraison : le tableau de bord lomi. (Developers → Webhooks → sélectionner le point de terminaison → Logs) affiche l’historique des tentatives de livraison, les codes succès/échec et les corps de réponse capturés par lomi.. Utile pour diagnostiquer les problèmes.
- 401 Unauthorized / corps « Authentication required » : en principe votre serveur ou proxy répond ainsi, pas lomi. Les POST sortants de lomi. incluent uniquement
`X-Lomi-Signature`pour contrôle — pas`Authorization: Bearer`ni`X-API-Key`. Excluez la route webhook de l’authentification globale puis vérifiez le HMAC ; voir Secret de signature et Authorization. - Écarts de signature : souvent dus à un mauvais secret, à une modification de la charge avant vérification, ou à l’absence d’utilisation du corps brut de la requête.
- Dépassements de délai : lomi n’attend qu’environ quatre secondes par tentative HTTP. Si vous voyez encore des timeouts, profilez tout ce qui s’exécute avant l’envoi du
2xx— en pratique une réponse JSON minimale suffit dans la quasi-totalité des intégrations, le reste allant dans votre file. - Pare-feu / réseau : vérifiez que votre serveur ou pare-feu autorise les requêtes POST entrantes depuis les adresses IP de lomi. (si filtrage par IP utilisé).