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

# Cursor

> Configure Cursor to generate correct LigdiCash integration code on the first try

Cursor can generate LigdiCash integration code in seconds. By adding a rules file to your project, you give it the API conventions once.

## LigdiCash skill

<Card title="LigdiCash skill — download and install" icon="brain-circuit" color="#e11d48" href="/en/sdk/ai-skill">
  Download the ZIP or install via `npx skills`. The `references/` files can be dragged directly into the Cursor chat as session context.
</Card>

## Requirements

* [Cursor](https://cursor.sh) installed
* Access to the project you want to integrate

## Rules file to create

Cursor supports two locations for project rules:

* **Cursor ≥ 0.45**: create `.cursor/rules/ligdicash.mdc` at the root
* **Older versions**: create `.cursorrules` at the root

Add the following content:

````markdown theme={null}
# LigdiCash integration

## Context

LigdiCash is a mobile money payment aggregator in West Africa.
API base URL: https://app.ligdicash.com

## Mandatory headers on every request

```
Apikey: {API_KEY}
Authorization: Bearer {AUTH_TOKEN}
Accept: application/json
Content-Type: application/json
```

## Data format

- Phone numbers: E.164 format without `+` or spaces — e.g. `22670000000`
- Amounts: integers (CFA francs have no sub-unit) — e.g. `5000`
- Currency: `XOF` exclusively
- API keys in examples: always `{API_KEY}` and `{AUTH_TOKEN}`, never real values

## Golden rule — transaction identification

The `token` returned at creation is different from the `token` received in the callback.
Never use that token to identify a transaction.

Always pass a merchant identifier in `custom_data` at creation:
```json
"custom_data": { "transaction_id": "ORD-2025-00042" }
```

In the callback, `custom_data` comes back as an array of objects. LigdiCash adds its own fields (`hash`, `logfile`). Extract with:
```javascript
const entry = custom_data.find(e => e.keyof_customdata === "transaction_id");
const transactionId = entry?.valueof_customdata;
```

## Hosted payin — pitfalls

- `customer` must stay `""` — otherwise LigdiCash filters the visible operators
- Never open the payment URL in an `<iframe>` — use the same tab, a new tab, a popup, or a native WebView

## Callback

- LigdiCash sends two POSTs: one `application/x-www-form-urlencoded` + one `application/json`. Deduplicate.
- Re-verify each callback by calling the `confirm` endpoint with the token stored at creation. Never trust the received payload.
````

## Ready-to-use prompts

Use these prompts in the Cursor chat (Cmd+L or Ctrl+L).

<AccordionGroup>
  <Accordion title="Hosted payin (checkout-invoice)">
    ```
    Implement a LigdiCash hosted payin in [language].

    - Endpoint: POST https://app.ligdicash.com/pay/v01/redirect/checkout-invoice/create
    - Amount: variable (function parameter)
    - customer must stay "" (empty)
    - Pass transaction_id in custom_data (object): { "transaction_id": "..." }
    - Open the returned URL in a new tab (no iframe)
    - Handle HTTP errors and response_code != "00"

    Return the payment URL or throw an exception.
    ```
  </Accordion>

  <Accordion title="Secure callback handler">
    ```
    Write a LigdiCash callback handler in [language/framework].

    Required behavior:
    1. Accept POST in application/json AND application/x-www-form-urlencoded
    2. Deduplicate by token (idempotency)
    3. Re-verify the status by calling the confirm endpoint with the token stored in the database
    4. custom_data in the callback is an array of objects — extract via keyof_customdata === "transaction_id"
    5. Update the order in the database only if the confirm status is "00"
    ```
  </Accordion>

  <Accordion title="Payout to mobile money">
    ```
    Implement a direct LigdiCash payout to mobile money in [language].

    - Endpoint: POST https://app.ligdicash.com/pay/v01/straight/payout
    - Parameters: amount, phone number (22670XXXXXXX format), description
    - Pass transaction_id in custom_data (object): { "transaction_id": "..." }
    - Handle errors and log the wiki URL on failure
    ```
  </Accordion>
</AccordionGroup>

<Tip>
  Enable **Codebase indexing** in Cursor's settings so it analyzes your existing files and generates code that matches your architecture.
</Tip>
