Skip to main content

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.

This page gathers the operational best practices to verify the status of LigdiCash transactions reliably, without overloading the API or leaving orphan transactions behind. The optimal interval depends on the type of transaction:
FlowRecommended intervalReason
Payin (hosted or direct)3 to 5 secondsOperator confirmation often arrives within seconds after the customer’s action
Payout30 to 60 secondsPayouts are processed in batches by the operator — polling too fast is pointless
Do not go below 3 seconds between two confirm calls. Overly aggressive polling can trigger rate limits on the LigdiCash side and degrade the reliability of your integrations.

Timeouts — when to stop polling

Set a maximum number of attempts rather than an absolute delay: this gives you precise control over the number of API calls generated.
FlowRecommended max attemptsApprox. total duration
Payin10 to 1540 to 75 seconds
Payout105 to 10 minutes
After the timeout, the transaction technically remains pending on the LigdiCash side — it is not cancelled. The callback may still arrive. Apply the following logic:
  1. Mark the transaction as expired in your database (application-level status, not LigdiCash).
  2. Inform the user that the processing is in progress and that they will be notified.
  3. Keep listening for the callback — if it arrives, re-verify with confirm and update.

Hybrid strategy — primary callback + fallback polling

1. Create the transaction → store the token and status = "pending"
2. Configure a callback_url reachable from the internet
3. On callback receipt:
     → Call confirm with the creation token
     → Update your database
4. If the callback does not arrive after 2 minutes:
     → Trigger a fallback polling (async job)
     → 10 attempts, every 5 seconds
5. If polling timeout:
     → Mark "expired" in the database
     → Keep processing the callback if it arrives late
Trigger the fallback polling from a background job (cron, queue worker) — not from the initial HTTP request thread. This avoids blocking the user during the wait.

Handling pending transactions

A transaction stays pending until the operator has made its final decision. Several situations explain a prolonged pending:
  • Approval mode (Moov Africa) — the customer must confirm on their mobile app, which can take several minutes.
  • Expired OTP — the customer did not enter the OTP in time. The transaction will stay pending then move to notcompleted after expiration.
  • Operator network congestion — rare but possible during traffic spikes.
  • Payout awaiting funds — if the merchant account balance is insufficient at the moment of initiation.
For every transaction still pending after your polling timeout, keep the token in the database and schedule a deferred re-verification (e.g. +30 min, +2h, +24h) before considering it definitively lost.
JavaScript — deferred re-verification
async function reCheckExpiredTransaction(token) {
  const res = await fetch(
    `https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/confirm?token=${token}`,
    {
      headers: {
        Apikey: process.env.LIGDICASH_API_KEY,
        Authorization: `Bearer ${process.env.LIGDICASH_API_TOKEN}`,
        Accept: "application/json",
      },
    }
  );
  const data = await res.json();

  if (data.status === "completed") {
    await updateOrder(token, "paid");
  } else if (data.status === "notcompleted") {
    await updateOrder(token, "failed");
  }
  // If still "pending", leave the scheduled job for the next check
}