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

# Direct payin

> Collect payments directly inside your interface, without redirecting your customer to LigdiCash. You handle the UX, LigdiCash handles the operator.

Direct payin lets you embed the payment form directly inside your application. Your customer never leaves your interface: they enter their phone number, validate the payment following their operator's instructions, and the transaction is confirmed by callback. You have full control over the user experience.

This method requires more integration work than hosted payin: the validation mode varies by operator, and your UX must adapt to each one.

## How it works

The general flow has four steps, with step 3 varying depending on the [validation mode](/en/payment-api/direct-payin/validation-modes) of the chosen operator.

<Steps>
  <Step title="Collect the customer's phone number">
    Your interface collects the customer's mobile money number, in the format without `+` or spaces (`22670XXXXXXX`). Depending on the operator, you decide which validation mode to apply.
  </Step>

  <Step title="Initiate the transaction">
    You call `POST /pay/v01/straight/checkout-invoice/create` (or the dedicated endpoints for the LigdiCash Wallet) with the customer's number and, depending on the mode, either the OTP already collected or an empty `otp` field.
  </Step>

  <Step title="Customer validation">
    The customer validates the payment based on their operator: by responding to a USSD push, dialing a USSD code, or sharing an OTP received by SMS. In the SMS OTP case only, you resubmit a second request with the code.
  </Step>

  <Step title="Confirmation">
    LigdiCash sends a callback to your `callback_url`. You re-verify the status via the `confirm` endpoint with the token stored at creation, before fulfilling the order.
  </Step>
</Steps>

## Validation modes

The behavior of step 3 depends on the operator. Four modes exist:

| Mode            | Trigger           | Summary                                                                        |
| --------------- | ----------------- | ------------------------------------------------------------------------------ |
| **USSD OTP**    | Before submission | The customer dials a USSD code → generates an OTP → you submit with that OTP   |
| **USSD Push**   | After submission  | The operator sends a USSD push → the customer validates with their PIN         |
| **Guided USSD** | After submission  | The operator sends an SMS with a USSD code → the customer dials the USSD       |
| **SMS OTP**     | After submission  | The operator sends an OTP by SMS → the customer shares the code → you resubmit |

```mermaid theme={null}
flowchart TD
    A[Customer enters their number] --> B{Operator's\nvalidation mode}

    B -->|USSD OTP| C["Customer dials the USSD\nand obtains their OTP"]
    C --> D["Backend submits\notp: {OTP code}"]

    B -->|USSD Push| E["Backend submits\notp: ''"]
    E --> F["Operator sends\na USSD push"]
    F --> G["Customer validates\nwith their PIN"]

    B -->|Guided USSD| H["Backend submits\notp: ''"]
    H --> I["Operator sends an SMS\nwith USSD code"]
    I --> J["Customer dials\nthe USSD code"]

    B -->|SMS OTP| K["Backend submits\notp: ''"]
    K --> L["Operator sends\nan OTP by SMS"]
    L --> M["Customer shares\nthe OTP with merchant"]
    M --> N["Backend resubmits\notp: {OTP code}"]

    D --> Z["LigdiCash sends the callback\nBackend re-verifies via confirm"]
    G --> Z
    J --> Z
    N --> Z
```

<Card title="Validation modes — full guide" icon="list-check" href="/en/payment-api/direct-payin/validation-modes">
  Understand the modes and adapt your UX to each operator
</Card>

## Important constraints

<Warning>
  The `external_id` field must always be empty (`""`) in every direct payin request.
</Warning>

<Note>
  The token returned at creation is different from the token present in the callback payload. Always store the creation token on the merchant side and use it to call `confirm` — never rely on the callback token alone.
</Note>

## In this section

<CardGroup cols={2}>
  <Card title="Validation modes" icon="list-check" href="/en/payment-api/direct-payin/validation-modes">
    USSD OTP, USSD Push, Guided USSD, SMS OTP — understand and adapt the UX
  </Card>

  <Card title="Create a transaction" icon="file-invoice" href="/en/payment-api/direct-payin/create-transaction">
    Parameters, full payload, and response of the create endpoint
  </Card>

  <Card title="Verify the status" icon="circle-check" href="/en/payment-api/direct-payin/verify-status">
    Call the confirm endpoint with the creation token
  </Card>

  <Card title="Supported operators" icon="mobile" href="/en/payment-api/direct-payin/operators/orange-burkina">
    A dedicated page per operator with identifiers, mode, and examples
  </Card>
</CardGroup>
