Passer au contenu principal

Documentation Index

Fetch the complete documentation index at: https://developers.ligdicash.com/llms.txt

Use this file to discover all available pages before exploring further.

Ce guide décrit le flux de bout en bout pour un site e-commerce : depuis la validation du panier côté client jusqu’à la confirmation de livraison côté serveur. Il utilise le payin avec redirection, qui est le mode d’intégration le plus simple et le plus compatible avec tous les opérateurs. Pré-requis : vous avez un projet API LigdiCash avec une Apikey et un Auth Token. Voir Créer un projet API.

Vue d’ensemble du flux

Client           Frontend          Backend          LigdiCash
  |                 |                  |                 |
  |-- Valider --->  |                  |                 |
  |   le panier     |-- POST /pay --> |                  |
  |                 |                  |-- create -----> |
  |                 |                  | <-- token ----- |
  |                 | <-- pay_url ---- |                 |
  |-- Redirect -->  |                  |                 |
  |                 |--- Ouvre URL --> |                 |
  |  [Paiement sur la page LigdiCash]  |                 |
  |                 |                  | <-- callback -- |
  |                 |                  |-- confirm ----> |
  |                 |                  | <-- statut ---- |
  |                 |                  |-- Confirme      |
  |                 |                  |   commande      |
  | <-- Retour ---- |                  |                 |
  |   return_url    |-- GET /statut -> |                 |
  |                 | <-- résultat --- |                 |
Ne jamais appeler l’API LigdiCash directement depuis le frontend. Votre Apikey et votre Auth Token doivent rester sur votre backend. Voir Architecture recommandée.

Étape 1 — Stocker la commande avant le paiement

Avant de créer la facture LigdiCash, persistez la commande en base de données avec le statut pending. Vous aurez besoin de son identifiant pour tracer le paiement.
INSERT INTO commandes (id, client_id, montant, statut, created_at)
VALUES ('cmd_7f3a9b', 42, 15000, 'pending', NOW());
Utilisez un identifiant interne non-devinable (UUID ou ID préfixé) comme transaction_id. Vous le passerez dans custom_data et l’utiliserez pour identifier la commande dans le callback.

Étape 2 — Créer la facture côté backend

Votre backend appelle l’endpoint de création de facture et stocke le token retourné.
curl -X POST https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/create \
  -H "Apikey: {API_KEY}" \
  -H "Authorization: Bearer {AUTH_TOKEN}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "commande": {
      "invoice": {
        "items": [
          {
            "name": "Abonnement Premium",
            "description": "1 mois d'\''accès Premium",
            "quantity": 1,
            "unit_price": 15000,
            "total_price": 15000
          }
        ],
        "total_amount": 15000,
        "devise": "XOF",
        "description": "Commande #cmd_7f3a9b",
        "customer": "",
        "customer_firstname": "Aminata",
        "customer_lastname": "Ouédraogo",
        "customer_email": "aminata@exemple.com",
        "external_id": "",
        "otp": ""
      },
      "store": {
        "name": "Ma Boutique",
        "website_url": "https://maboutique.com"
      },
      "actions": {
        "cancel_url": "https://maboutique.com/paiement/annule",
        "return_url": "https://maboutique.com/paiement/succes",
        "callback_url": "https://maboutique.com/api/ligdicash/callback"
      },
      "custom_data": {
        "transaction_id": "cmd_7f3a9b"
      }
    }
  }'
Réponse en cas de succès (response_code: "00") :
{
  "response_code": "00",
  "response_text": "https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm?token=eyJ0...",
  "description": "Checkout-Invoice created with success.",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
Stockez le token en base de données en l’associant à votre commande. Vous en aurez besoin pour vérifier le paiement.
UPDATE commandes
SET ligdicash_token = 'eyJ0eXAiOiJKV1Qi...'
WHERE id = 'cmd_7f3a9b';

Étape 3 — Rediriger le client vers la page de paiement

Retournez response_text (l’URL de paiement) à votre frontend, puis redirigez le client.
Frontend (JavaScript)
// Appel backend → récupère l'URL de paiement
const { payUrl } = await fetch("/api/commandes/cmd_7f3a9b/payer", {
  method: "POST",
}).then((r) => r.json());

// Redirection dans le même onglet (recommandé)
window.location.href = payUrl;

// Ou dans un nouvel onglet
// window.open(payUrl, "_blank");
Ne jamais ouvrir l’URL LigdiCash dans une <iframe>. LigdiCash bloque l’affichage en iframe. Utilisez une redirection dans le même onglet, un nouvel onglet, ou un popup. Voir Pièges courants.
Le client voit la page de paiement LigdiCash, sélectionne son opérateur mobile money et finalise le paiement. LigdiCash le redirige ensuite vers votre return_url (succès) ou cancel_url (annulation).

Étape 4 — Réceptionner le callback

LigdiCash envoie une notification POST à votre callback_url dès que le statut de la transaction change. Votre backend doit :
  1. Identifier la commande via custom_data
  2. Re-vérifier le statut avec l’endpoint confirm (ne jamais faire confiance au payload seul)
  3. Mettre à jour la commande en base
  4. Répondre 200 OK
Node.js (Express)
app.post("/api/ligdicash/callback", express.json(), async (req, res) => {
  // Répondre 200 immédiatement pour éviter les retries
  res.sendStatus(200);

  // Extraire le transaction_id depuis custom_data
  const customData = req.body.custom_data ?? [];
  const entry = Array.isArray(customData)
    ? customData.find((e) => e.keyof_customdata === "transaction_id")
    : null;

  if (!entry) return;

  const transactionId = entry.valueof_customdata;

  // Récupérer la commande et son token LigdiCash
  const commande = await db.commandes.findById(transactionId);
  if (!commande || commande.statut !== "pending") return;

  // Re-vérifier le statut côté LigdiCash
  const confirm = await fetch(
    `https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm?token=${commande.ligdicash_token}`,
    {
      headers: {
        Apikey: process.env.LIGDICASH_API_KEY,
        Authorization: `Bearer ${process.env.LIGDICASH_AUTH_TOKEN}`,
        Accept: "application/json",
      },
    }
  ).then((r) => r.json());

  if (confirm.status === "completed") {
    await db.commandes.update(transactionId, { statut: "payee" });
    await livraison.declencher(transactionId);
  } else if (confirm.status === "notcompleted") {
    await db.commandes.update(transactionId, { statut: "echec" });
  }
  // Si "pending" : ne rien faire, attendre le prochain callback
});
LigdiCash envoie deux requêtes POST à votre callback pour chaque événement : une en application/x-www-form-urlencoded et une en application/json. Traitez-les de manière idempotente. Voir Idempotence du callback.

Étape 5 — Vérifier le statut côté frontend

Après la redirection vers votre return_url, le frontend interroge votre backend pour afficher le résultat final. La return_url est un signal d’interface — elle ne prouve pas que le paiement a réussi.
Frontend — page return_url
// Extrait le transaction_id depuis l'URL (ex: /paiement/succes?cmd=cmd_7f3a9b)
const params = new URLSearchParams(window.location.search);
const commandeId = params.get("cmd");

const { statut } = await fetch(`/api/commandes/${commandeId}/statut`).then(
  (r) => r.json()
);

switch (statut) {
  case "payee":
    afficherConfirmation();
    break;
  case "pending":
    // Le callback n'est pas encore arrivé — afficher un loader et repolling
    afficherAttenteVerification();
    break;
  case "echec":
    afficherErreur();
    break;
}
Backend — GET /api/commandes/:id/statut
app.get("/api/commandes/:id/statut", async (req, res) => {
  const commande = await db.commandes.findById(req.params.id);
  if (!commande) return res.status(404).json({ error: "not_found" });

  // Si toujours pending, interroger LigdiCash en temps réel
  if (commande.statut === "pending") {
    const confirm = await fetch(
      `https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm?token=${commande.ligdicash_token}`,
      {
        headers: {
          Apikey: process.env.LIGDICASH_API_KEY,
          Authorization: `Bearer ${process.env.LIGDICASH_AUTH_TOKEN}`,
          Accept: "application/json",
        },
      }
    ).then((r) => r.json());

    if (confirm.status === "completed") {
      await db.commandes.update(commande.id, { statut: "payee" });
      commande.statut = "payee";
    }
  }

  res.json({ statut: commande.statut });
});

Récapitulatif

1

Stocker la commande

Créez la commande en base avec le statut pending avant tout appel LigdiCash.
2

Créer la facture

Backend → POST /pay/v01/redirect/checkout-invoice/create. Stockez le token retourné.
3

Rediriger le client

Frontend → redirection vers response_text (même onglet ou popup). Jamais d’iframe.
4

Réceptionner le callback

Répondre 200 immédiatement, puis re-vérifier via confirm avec le token stocké.
5

Confirmer la commande

Mettre à jour le statut en base et déclencher la livraison si status === "completed".
6

Afficher le résultat

Frontend → interroger votre backend pour afficher le statut réel après retour sur return_url.

Pages associées