lomi.

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

  1. est accessible publiquement en HTTPS ;
  2. peut recevoir des requêtes HTTP POST avec un corps JSON ;
  3. 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) :

  1. Allez dans la section Developers → Webhooks de votre tableau de bord lomi..
  2. Cliquez sur « Add Endpoint » ou « Create Webhook ».
  3. Saisissez l’URL du point de terminaison (l’URL HTTPS publiquement accessible que vous avez préparée).
  4. Sélectionnez les événements auxquels vous souhaitez vous abonner pour ce point de terminaison. Vous pouvez en choisir plusieurs.
  5. Cliquez sur « Create Webhook ».
  6. Copiez impérativement le Signing Secret généré (il commence par whsec_). 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 retirés.

{
  "id": "evt_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": "live"
}

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 :

  1. Extraire la signature : récupérez la valeur de l’en-tête X-Lomi-Signature de la requête entrante.
  2. 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).
  3. Préparer le HMAC : avec votre Signing Secret conservé en sécurité (la chaîne whsec_… fournie par lomi. pour ce point de terminaison) comme clé, calculez le hachage HMAC SHA256 de la chaîne du corps brut.
  4. 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.

L’absence de réponse 2xx dans un délai raisonnable (par ex. 10 secondes) sera considérée comme un échec de livraison par lomi..

Nouvelles tentatives

Si lomi. ne reçoit pas de réponse 2xx de votre point de terminaison, elle considère que la livraison a échoué et retentera automatiquement l’envoi du webhook.

  • Les nouvelles tentatives suivent une stratégie de backoff exponentiel (délais croissants entre les essais).
  • lomi. effectue jusqu’à 3 nouvelles tentatives après l’échec initial.
  • Idempotence : en raison des nouvelles tentatives (et d’éventuels autres problèmes réseau), votre point de terminaison peut recevoir plusieurs fois la même notification d’événement. Concevez votre logique de traitement pour être idempotente, c’est-à-dire que traiter le même événement plusieurs fois ne doit pas provoquer d’actions en double ni d’erreurs. Une stratégie courante consiste à vérifier si vous avez déjà traité un événement d’après son identifiant unique id (evt_…) avant d’agir.

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-Signature avec votre secret de signature et une comparaison à temps constant.
  • Répondre vite : envoyez une réponse 200 OK immédiatement à la réception.
  • 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’id de 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.
  • É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 : votre point de terminaison doit répondre en moins de 10 secondes. Déplacez le traitement lourd en arrière-plan.
  • 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é).

Sur cette page