> ## 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.

# Quickstart — Premier paiement en 5 minutes

> Réalisez votre premier payin avec redirection de bout en bout : créer la facture, rediriger le client, recevoir le callback et vérifier le paiement.

Ce guide vous fait parcourir le flux complet d'un payin avec redirection : vous créez une facture, vous redirigez votre client vers la page de paiement LigdiCash, vous recevez le callback, et vous vérifiez le statut avec l'endpoint `confirm`.

## Prérequis

* Votre `Apikey` et votre `API_TOKEN` disponibles dans votre dashboard LigdiCash
* Une `callback_url` accessible publiquement depuis internet (pas `localhost`)

<Note>
  Pour exposer un serveur local lors du développement, vous pouvez utiliser un outil comme [ngrok](https://ngrok.com).
</Note>

## Étape 1 — Créer la transaction

Appelez l'endpoint de création en passant votre `transaction_id` dans `custom_data`. Stockez le `token` retourné — vous en aurez besoin à l'étape 4.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/create \
    -H "Apikey: {API_KEY}" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -d '{
      "commande": {
        "invoice": {
          "items": [
            { "name": "Abonnement Pro", "price": 5000, "quantity": 1 }
          ],
          "total_amount": 5000,
          "devise": "XOF",
          "description": "Abonnement Pro — Janvier 2025",
          "customer": "",
          "customer_firstname": "Amadou",
          "customer_lastname": "Diallo",
          "customer_email": "amadou@exemple.com"
        },
        "store": {
          "name": "MonApp",
          "website_url": "https://monapp.com"
        },
        "actions": {
          "cancel_url": "https://monapp.com/paiement/annule",
          "return_url": "https://monapp.com/paiement/succes",
          "callback_url": "https://monapp.com/api/callback/ligdicash"
        },
        "custom_data": {
          "transaction_id": "ORD-2025-00042"
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const transactionId = "ORD-2025-00042";

  // Stockez transactionId en base avec statut "pending" avant cet appel
  await db.orders.update({ id: orderId, ligdicash_tx_id: transactionId, status: "pending" });

  const response = await fetch(
    "https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/create",
    {
      method: "POST",
      headers: {
        Apikey: process.env.LIGDICASH_API_KEY,
        Authorization: `Bearer ${process.env.LIGDICASH_API_TOKEN}`,
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        commande: {
          invoice: {
            items: [{ name: "Abonnement Pro", price: 5000, quantity: 1 }],
            total_amount: 5000,
            devise: "XOF",
            description: "Abonnement Pro — Janvier 2025",
            customer: "",
            customer_firstname: "Amadou",
            customer_lastname: "Diallo",
            customer_email: "amadou@exemple.com",
          },
          store: { name: "MonApp", website_url: "https://monapp.com" },
          actions: {
            cancel_url: "https://monapp.com/paiement/annule",
            return_url: "https://monapp.com/paiement/succes",
            callback_url: "https://monapp.com/api/callback/ligdicash",
          },
          custom_data: { transaction_id: transactionId },
        },
      }),
    }
  );

  const data = await response.json();

  if (data.response_code !== "00") {
    throw new Error(`LigdiCash error: ${data.response_text}`);
  }

  // Stockez le token pour la re-vérification à l'étape 4
  await db.orders.update({ ligdicash_tx_id: transactionId, ligdicash_token: data.token });

  const paymentUrl = data.response_text;
  ```

  ```php PHP theme={null}
  $transactionId = "ORD-2025-00042";

  $payload = [
    "commande" => [
      "invoice" => [
        "items" => [["name" => "Abonnement Pro", "price" => 5000, "quantity" => 1]],
        "total_amount" => 5000,
        "devise" => "XOF",
        "description" => "Abonnement Pro — Janvier 2025",
        "customer" => "",
        "customer_firstname" => "Amadou",
        "customer_lastname" => "Diallo",
        "customer_email" => "amadou@exemple.com",
      ],
      "store" => ["name" => "MonApp", "website_url" => "https://monapp.com"],
      "actions" => [
        "cancel_url" => "https://monapp.com/paiement/annule",
        "return_url" => "https://monapp.com/paiement/succes",
        "callback_url" => "https://monapp.com/api/callback/ligdicash",
      ],
      "custom_data" => ["transaction_id" => $transactionId],
    ],
  ];

  $ch = curl_init("https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/create");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Apikey: " . $_ENV["LIGDICASH_API_KEY"],
    "Authorization: Bearer " . $_ENV["LIGDICASH_API_TOKEN"],
    "Accept: application/json",
    "Content-Type: application/json",
  ]);

  $data = json_decode(curl_exec($ch), true);
  curl_close($ch);

  if ($data["response_code"] !== "00") {
    throw new Exception("LigdiCash error: " . $data["response_text"]);
  }

  $paymentUrl = $data["response_text"];
  ```
</CodeGroup>

La réponse en cas de succès contient dans `response_text` l'URL de la page de paiement :

```json theme={null}
{
  "response_code": "00",
  "token": "eyJ0eXAiOiJKV1Qi...",
  "response_text": "https://app.ligdicash.com/pay/invoice/eyJ0eXAiOiJKV1Qi...",
  "wiki": "https://client.ligdicash.com/wiki/createInvoice"
}
```

## Étape 2 — Rediriger le client

L'URL de paiement est dans `response_text`. Ouvrez-la dans le même onglet ou un nouvel onglet — **jamais dans une iframe**.

```javascript Node.js theme={null}
// Même onglet
window.location.href = paymentUrl;

// Nouvel onglet
window.open(paymentUrl, "_blank");
```

<Warning>
  L'iframe est bloqué par LigdiCash. Le lien de paiement doit obligatoirement s'ouvrir dans le même onglet, un nouvel onglet, un popup, ou une WebView native sur mobile.
</Warning>

Une fois le paiement effectué ou annulé, LigdiCash redirige le client vers votre `return_url` ou `cancel_url`.

## Étape 3 — Recevoir le callback

LigdiCash envoie une requête POST à votre `callback_url` quand le statut de la transaction change.

```javascript Node.js (Express) theme={null}
app.post("/api/callback/ligdicash", async (req, res) => {
  // Idéalement, toujours répondre 200 en premier
  res.status(200).json({ ok: true });

  const payload = req.body;

  // Extraire votre transaction_id depuis custom_data
  const entry = payload.custom_data?.find(
    (item) => item.keyof_customdata === "transaction_id"
  );
  const transactionId = entry?.valueof_customdata;

  if (!transactionId) return;

  // Récupérer le token stocké à la création (étape 1)
  const order = await db.orders.findOne({ ligdicash_tx_id: transactionId });
  if (!order) return;

  // Re-vérifier le statut avec confirm (étape 4)
  await verifyAndUpdateOrder(order);
});
```

<Tip>
  Par convention, répondez `200` à LigdiCash pour accuser réception du callback.
</Tip>

## Étape 4 — Vérifier avec confirm

N'accordez jamais confiance au seul payload du callback. Appelez `confirm` avec le `token` stocké à la création pour valider le statut.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm/?invoiceToken={TOKEN}" \
    -H "Apikey: {API_KEY}" \
    -H "Authorization: Bearer {API_TOKEN}" \
    -H "Accept: application/json"
  ```

  ```javascript Node.js theme={null}
  async function verifyAndUpdateOrder(order) {
    const response = await fetch(
      `https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm/?invoiceToken=${order.ligdicash_token}`,
      {
        headers: {
          Apikey: process.env.LIGDICASH_API_KEY,
          Authorization: `Bearer ${process.env.LIGDICASH_API_TOKEN}`,
          Accept: "application/json",
        },
      }
    );

    const data = await response.json();

    if (data.status === "completed") {
      await db.orders.update({ id: order.id, status: "paid" });
    } else if (data.status === "notcompleted") {
      await db.orders.update({ id: order.id, status: "failed" });
    }
    // Si "pending" : ne rien faire, attendre le prochain callback
  }
  ```
</CodeGroup>

## Et après ?

Votre premier paiement fonctionne. Pour aller plus loin :

<CardGroup cols={2}>
  <Card title="Payin sans redirection" icon="mobile" href="/api-paiement/payin-sans-redirect/introduction">
    Initiez le paiement directement depuis votre interface, sans quitter votre app
  </Card>

  <Card title="Sécuriser le callback" icon="shield" href="/api-paiement/callback/securisation">
    Le pattern complet de re-vérification et de déduplication
  </Card>

  <Card title="Payout" icon="arrow-right" href="/api-paiement/payout/introduction">
    Effectuez des virements vers vos clients ou partenaires
  </Card>

  <Card title="Tous les opérateurs" icon="globe" href="/reference/operateurs-supportes">
    Orange Money, Moov, MTN, Wave et plus encore
  </Card>
</CardGroup>
