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.

Votre URL de callback est une route POST publique. N’importe qui connaissant cette URL peut envoyer un faux payload — avec un status: "completed" et un montant de son choix. Si vous traitez ce payload sans vérification, vous livrez une commande ou déclenchez un payout sur la base d’un paiement qui n’a jamais eu lieu. La règle d’or : ne jamais agir sur le payload reçu. Toujours re-vérifier.

Le pattern de re-vérification

1

À la création — stocker le token

Lors de la création d’une transaction (payin ou payout), stockez le token retourné par l’API dans votre base de données, associé à votre transaction_id.
// Réponse de création — à stocker
{
  "response_code": "00",
  "token": "{INVOICE_TOKEN}"
}
2

À la réception du callback — extraire l'identifiant

Recevez le callback. Extrayez votre transaction_id depuis le tableau custom_data en filtrant sur keyof_customdata.
const entry = payload.custom_data?.find(
  (item) => item.keyof_customdata === "transaction_id"
);
const transactionId = entry?.valueof_customdata;
3

Retrouver le token stocké

Cherchez dans votre base de données le token associé à ce transaction_id. Si aucun enregistrement ne correspond, ignorez le callback — il est probablement frauduleux.
const stored = await db.transactions.findOne({ transaction_id: transactionId });
if (!stored) return; // callback non sollicité
4

Appeler l'endpoint confirm avec le token stocké

Appelez l’endpoint de vérification de LigdiCash avec le token que vous avez stocké — pas celui du callback (qui est toujours vide).
// Pour un payin redirect
const params = new URLSearchParams({ invoiceToken: stored.token });
const verify = await fetch(
  `https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm?${params}`,
  { headers: { Apikey: API_KEY, Authorization: `Bearer ${AUTH_TOKEN}` } }
);
const result = await verify.json();
5

Agir sur le résultat de confirm, pas sur le payload

Utilisez uniquement le status retourné par confirm pour décider de votre action.
if (result.status === 'completed') {
  await db.orders.markAsPaid(transactionId);
}

Ce qu’il ne faut pas faire

// DANGEREUX — traitement direct du payload sans vérification
app.post('/callback', (req, res) => {
  const { status, amount, external_id } = req.body;

  if (status === 'completed') {
    // N'importe qui peut envoyer ce payload
    markOrderAsPaid(external_id, amount);
  }
});
// CORRECT — re-vérification systématique
app.post('/callback', async (req, res) => {
  const entry = req.body.custom_data?.find(
    (item) => item.keyof_customdata === 'transaction_id'
  );
  const transactionId = entry?.valueof_customdata;
  if (!transactionId) return res.sendStatus(400);

  const stored = await db.transactions.findOne({ transaction_id: transactionId });
  if (!stored) return res.sendStatus(404);

  const result = await confirmWithLigdicash(stored.token);

  if (result.status === 'completed') {
    await markOrderAsPaid(transactionId);
  }

  res.sendStatus(200);
});

Pages associées