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

# FAQ

> Frequently asked questions about LigdiCash integration — technical, account, business.

This page collects the most frequent questions from developers and business teams integrating LigdiCash. Each answer points to the detailed documentation for follow-up reading.

## Account and access

<AccordionGroup>
  <Accordion title="How do I create a LigdiCash merchant account?">
    Download the LigdiCash mobile app (App Store / Play Store) and create your account from the app. You will then provide the required KYC documents and sign a partnership contract with your Partner Manager.

    See [Integration protocol](/en/getting-started/integration-protocol) for step-by-step details.
  </Accordion>

  <Accordion title="How do I get my API keys?">
    You don't create your API project yourself. After the contract is signed, the **LigdiCash technical team** creates and enables your project. Your `Apikey` and `API_TOKEN` are then available in the Dashboard.

    See [API project](/en/concepts/api-project) and [Authentication](/en/concepts/authentication).
  </Accordion>

  <Accordion title="Can I have multiple API projects on the same account?">
    Yes, but each API project requires its **own contract**. If you have multiple applications or countries to cover, discuss it with your Partner Manager before starting a new integration.
  </Accordion>

  <Accordion title="Is there a sandbox to test without paying?">
    LigdiCash does not currently offer a separate sandbox environment. Testing is done in production with real transactions. Check with your Partner Manager about available test arrangements.

    Contact: [developper@ligdicash.com](mailto:developper@ligdicash.com)
  </Accordion>
</AccordionGroup>

## Technical integration

<AccordionGroup>
  <Accordion title="What's the difference between hosted payin and direct payin?">
    * **Hosted payin**: the customer is sent to a payment page hosted by LigdiCash. Simple integration, UI managed by LigdiCash, less control.
    * **Direct payin**: the merchant fully owns the interface and submits the payment via API. More UX control, but more complex integration and operator-specific.

    See [Payment API overview](/en/payment-api/overview) for the decision matrix.
  </Accordion>

  <Accordion title="Can I show the payment page in an iframe?">
    No. LigdiCash blocks iframe rendering of its page. Open the link in the same tab, a new tab, a popup, or a native WebView (mobile apps).

    See [Hosted payin pitfalls](/en/payment-api/hosted-payin/common-pitfalls).
  </Accordion>

  <Accordion title="Why must the customer field stay empty in hosted payin?">
    If you set a phone number in `customer`, LigdiCash filters the payment page to show only the operators tied to that number, hiding the other options. Leave `customer: ""` so your customer can freely pick their operator.

    See [Hosted payin pitfalls](/en/payment-api/hosted-payin/common-pitfalls).
  </Accordion>

  <Accordion title="My payment popup is blocked by the browser. How do I work around it?">
    Browsers block popups opened outside a direct user event. The recommended pattern is to open `window.open('about:blank')` at the moment of the user click (before the `await fetch`), then navigate to the payment URL once the response is received.

    See [Redirect the customer](/en/payment-api/hosted-payin/redirect-customer).
  </Accordion>

  <Accordion title="How do I identify my transaction in the callback if the token changes?">
    The `token` present in the callback is different from the token returned at creation. Don't rely on it to look up your order. The reliable method is to inject your own order identifier into `custom_data` at creation, then look it up via `keyof_customdata === "transaction_id"` in the callback.

    See [The transaction\_id pattern](/en/concepts/transaction-id-pattern) and [Parse custom\_data](/en/payment-api/callback/parse-custom-data).
  </Accordion>

  <Accordion title="Why is my callback called twice for the same transaction?">
    This is normal LigdiCash behavior. For each event, two POST requests are sent to your callback URL: one as `application/x-www-form-urlencoded` and one as `application/json`. The content is identical. Implement deduplication (check whether the transaction is already processed in your database before acting).

    See [Callback idempotency](/en/payment-api/callback/idempotency).
  </Accordion>

  <Accordion title="How do I secure my callback endpoint?">
    Never trust the received payload without verification. Anyone who knows your callback URL can send a forged payload. After receiving a callback, always re-verify the status by calling the `confirm` endpoint with the token you stored at invoice creation.

    See [Callback security](/en/payment-api/callback/security).
  </Accordion>

  <Accordion title="Is the withdrawal/confirm endpoint GET or POST?">
    The `GET /pay/v01/withdrawal/confirm/` endpoint is called with **GET** and the token in the query string. There's an inconsistency in the existing documentation.

    See [Verify payout status](/en/payment-api/payout/verify-status).
  </Accordion>

  <Accordion title="What's the difference between wallet payout and direct mobile money payout?">
    * **`/withdrawal/create`**: sends to the recipient's LigdiCash wallet. The funds can stay in the wallet (`top_up_wallet: 1`) or be automatically transferred to their linked mobile money (`top_up_wallet: 0`).
    * **`/straight/payout`**: sends directly to the mobile money number, no intermediate wallet. Slower, but doesn't require the recipient to have a LigdiCash account.

    See [Payout — Introduction](/en/payment-api/payout/introduction).
  </Accordion>

  <Accordion title="How do I handle the different validation modes per operator?">
    There are four modes depending on the operator:

    * **USSD OTP** — the customer generates an OTP by dialing a USSD code before you submit. One API request.
    * **USSD Push** — you submit with `otp: ""`, the operator sends a USSD push screen to the customer, who confirms with their PIN. One API request.
    * **Guided USSD** — you submit with `otp: ""`, the operator sends an SMS with instructions and a USSD code to dial. One API request.
    * **SMS OTP** — you first submit with `otp: ""`, the operator sends an OTP by SMS, you resubmit with the entered OTP. Two API requests.

    See [Validation modes](/en/payment-api/direct-payin/validation-modes) for the detailed flows and recommended UX.
  </Accordion>
</AccordionGroup>

## Security

<AccordionGroup>
  <Accordion title="How do I protect my API keys?">
    * Never expose `Apikey` and `Auth Token` on the client side (browser, mobile app).
    * Always make LigdiCash calls from your backend.
    * Use environment variables, never constants in source code.
    * Regenerate keys immediately from the Dashboard if compromised.

    See [Recommended architecture](/en/guides/recommended-architecture).
  </Accordion>

  <Accordion title="What do I do if my API keys are compromised?">
    Log into the LigdiCash Dashboard and regenerate your keys immediately. Update your production environment variables. Audit your logs for unauthorized transactions. Contact [developper@ligdicash.com](mailto:developper@ligdicash.com) if you suspect fraud.
  </Accordion>

  <Accordion title="How do I avoid duplicate transactions?">
    Two combined mechanisms:

    1. **Callback deduplication**: before processing a callback, check in your database whether the `transaction_id` is already processed.
    2. **Systematic re-verification**: call the `confirm` endpoint with the creation token to validate the real state, rather than trusting the received callback payload.

    See [Callback idempotency](/en/payment-api/callback/idempotency) and [Callback security](/en/payment-api/callback/security).
  </Accordion>
</AccordionGroup>

## Business and operations

<AccordionGroup>
  <Accordion title="Which countries and operators are supported?">
    LigdiCash covers Burkina Faso, Côte d'Ivoire, Mali, Niger, Benin, Togo, Senegal, Guinea (Conakry), and DRC. Supported operators include Orange Money, Moov Africa, MTN Mobile Money, Wave, Airtel Money, Vodacom, Africell, YAS, Zamani, and the LigdiCash Wallet.

    See [Supported operators](/en/reference/supported-operators) for the full matrix.
  </Accordion>

  <Accordion title="What currency does the API use?">
    The LigdiCash API **always uses XOF (CFA franc)**, whatever the customer's local currency is. This also applies to DRC and Guinea (Conakry), whose national currencies are not XOF — LigdiCash handles the conversion internally. Amounts are always **integers** (XOF has no sub-unit).

    For foreign currencies like the dollar or euro, the merchant must convert to XOF before calling the API.

    See [Currencies and amounts](/en/concepts/currencies-and-amounts).
  </Accordion>

  <Accordion title="What are the minimum and maximum transaction amounts?">
    Limits vary by operator and country. Contact your Partner Manager or check the Dashboard for the limits active on your account.

    See [Supported operators](/en/reference/supported-operators).
  </Accordion>

  <Accordion title="What are the settlement delays to my bank account?">
    Settlement terms (frequency, delay, minimum threshold) are defined in your partnership contract. Contact your Partner Manager for details.
  </Accordion>

  <Accordion title="How do I integrate LigdiCash on a WooCommerce store?">
    An official plugin is available. Install it manually from your WooCommerce Dashboard, configure your API keys and callback behavior, and you're ready.

    See [WordPress / WooCommerce SDK](/en/sdk/wordpress-woocommerce).
  </Accordion>

  <Accordion title="Are there official SDKs for my language?">
    Yes. LigdiCash offers official SDKs for PHP, Python, JavaScript/Node.js, Dart/Flutter, and a WooCommerce plugin.

    See [SDK overview](/en/sdk/overview).
  </Accordion>

  <Accordion title="How do I go live after testing?">
    Going live follows a formal process:

    1. You complete your integration and tests on the temporary account.
    2. The LigdiCash technical team runs **validation tests** on your integration.
    3. A **formal record (PV) is signed** between you and LigdiCash to officially close the integration phase.
    4. The technical team enables your production project. Only your keys change — the code stays the same.

    Also review the technical checklist to prepare your integration before validation.

    See [Production checklist](/en/guides/production-checklist).
  </Accordion>
</AccordionGroup>
