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

# Error handling — Overview

> Understand the two levels of errors in the LigdiCash API: request rejection (response_code) and transaction failure (callback/confirm).

The LigdiCash API distinguishes between two levels of errors that must not be confused: the immediate rejection of a malformed request, and the failure of a transaction that was successfully initiated. This guide explains how to handle each one.

## The two error levels

### Level 1 — Request rejection (response\_code)

Happens immediately on the HTTP call. LigdiCash has read your payload and rejected it.

| `response_code` | Meaning                                                       |
| --------------- | ------------------------------------------------------------- |
| `00`            | Valid payload — the transaction is initiated                  |
| `01`            | Invalid payload or authentication error — nothing was created |

When `response_code` is `01`, the `response_text` field contains a technical sub-code in the form `Echec (CodeXX)`. Read the `wiki` field to get the human-readable description.

<Warning>
  `response_code: "00"` does not guarantee that the payment will succeed. It only confirms that your request was syntactically correct and that the transaction has been queued. The actual payment outcome is delivered via the callback or the `confirm` endpoint.
</Warning>

### Level 2 — Transaction failure (callback / confirm)

Happens after `response_code: "00"`. The transaction was initiated but did not complete on the operator side.

| Field                          | Value on failure                        |
| ------------------------------ | --------------------------------------- |
| `status` in the callback       | `notcompleted`                          |
| `response_code` from `confirm` | `01` with a sub-code in `response_text` |

These failures indicate business issues: insufficient balance, wrong OTP, ineligible number, etc.

***

## Error categories

| Category                    | When                | Examples                                                     |
| --------------------------- | ------------------- | ------------------------------------------------------------ |
| **Authentication**          | Immediate           | Invalid Apikey, expired token                                |
| **Invalid payload**         | Immediate           | Missing field, wrong phone number format, non-integer amount |
| **Operator error**          | Deferred (callback) | Cancellation                                                 |
| **Merchant business error** | Immediate           | Payout not enabled on the account, limit exceeded            |
| **Technical error**         | Immediate           | Timeout, service unavailable                                 |

***

## General handling strategy

<Steps>
  <Step title="Check response_code immediately">
    If `response_code === "01"`: log `response_text`, follow the URL in `wiki` to read the human description. Do not retry immediately — fix the root cause first.
  </Step>

  <Step title="Store the creation token">
    If `response_code === "00"`: store the returned `token` in your database, linked to your `transaction_id`. You will need it to re-verify the callback.
  </Step>

  <Step title="Handle the callback defensively">
    Never trust the callback payload alone. Always call `confirm` with the token stored in the previous step to validate the real outcome.
  </Step>
</Steps>

***

## Complete handling example

```javascript Node.js theme={null}
async function initiatePayment(payload) {
  const res = await fetch("https://app.ligdicash.com/pay/v01/straight/checkout-invoice/create", {
    method: "POST",
    headers: {
      "Apikey": process.env.LIGDICASH_API_KEY,
      "Authorization": `Bearer ${process.env.LIGDICASH_AUTH_TOKEN}`,
      "Accept": "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  const data = await res.json();

  if (data.response_code === "01") {
    // Level 1 — immediate rejection
    logger.error({
      event: "ligdicash_request_rejected",
      subcode: data.response_text,  // e.g. "Echec (Code00)"
      wiki: data.wiki,              // URL for the human-readable description
    });
    throw new Error(`Request rejected: ${data.response_text}`);
  }

  // response_code === "00": transaction initiated
  // Store the token for callback re-verification
  await db.transactions.create({
    transaction_id: payload.custom_data[0].valueof_customdata,
    ligdicash_token: data.token,
    status: "pending",
  });

  return data;
}
```

***

## Related pages

* [The wiki field](/en/errors/wiki-field) — how to decode `Echec (CodeXX)` into a human-readable message
* [Sub-codes reference](/en/errors/sub-codes) — full list by endpoint
* [Common errors](/en/errors/common-errors) — causes and solutions
* [Response codes and statuses](/en/concepts/response-codes-and-statuses) — full reference for `response_code`
* [Callback security](/en/payment-api/callback/security) — re-verification via `confirm`
