> ## Documentation Index
> Fetch the complete documentation index at: https://docs.minisend.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Onramp quickstart

> Collect your first M-Pesa payment and receive USDC in your own wallet in two API calls: quote the amount, then create the order.

This guide collects KES 1,000 from a customer's phone and releases USDC to your own Base address.

**Before you start, you need:**

* An API key with the `onramp` scope. See [getting access](/onramp/overview#getting-access).
* A Base address you control to receive the USDC.

<Steps>
  <Step title="Quote the collection">
    Specify either the KES amount to charge the customer, or the USDC amount you want to receive. This example charges the customer an exact KES figure.

    ```bash theme={null}
    curl -X POST https://merchant.minisend.xyz/api/onramp/quote \
      -H "Authorization: Bearer ms_live_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
        "currency": "KES",
        "amount_kes": 1000
      }'
    ```

    ```json theme={null}
    {
      "currency": "KES",
      "amount_kes": 1000,
      "fee_kes": 10,
      "net_kes": 990,
      "amount_usdc": 7.62,
      "rate": 129.92,
      "expires_at": "2026-07-23T12:05:00.000Z"
    }
    ```

    `amount_kes` is the exact figure the customer's phone will be prompted to pay. `amount_usdc` is what your address receives.
  </Step>

  <Step title="Create the order">
    Pass an `Idempotency-Key` header so a network retry can never send a second payment prompt.

    ```bash theme={null}
    curl -X POST https://merchant.minisend.xyz/api/onramp/orders \
      -H "Authorization: Bearer ms_live_your_key_here" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: collect-2201" \
      -d '{
        "currency": "KES",
        "amount_kes": 1000,
        "phone": "0712345678",
        "address": "0xYourWalletAddress0000000000000000000000",
        "reference": "collect-2201"
      }'
    ```

    ```json theme={null}
    {
      "order_id": "7c1e4f9a-...",
      "status": "pending",
      "currency": "KES",
      "amount_usdc": 7.62,
      "amount_local": 1000,
      "fee": 10,
      "rate": 129.92,
      "customer_phone": "0712345678",
      "mobile_network": "Safaricom",
      "release_address": "0xyourwalletaddress0000000000000000000000",
      "release_chain": "base",
      "release_asset": "USDC",
      "external_reference": "collect-2201",
      "expires_at": "2026-07-23T12:30:00.000Z",
      "created_at": "2026-07-23T12:00:03.000Z",
      "instructions": "The customer's phone (0712345678) will receive an M-Pesa prompt for KSh 1,000. On payment, 7.62 USDC (Base) is released to release_address."
    }
    ```

    The payment prompt is sent to the customer's phone the moment this call succeeds. There is no separate trigger step.
  </Step>

  <Step title="Customer confirms">
    The customer enters their PIN on the prompt. Nothing further is required from your side.

    <Note>
      Each order is one-shot. If the customer cancels or the prompt times out, the order moves to `failed` and cannot be retried. Create a new order.
    </Note>
  </Step>

  <Step title="Confirm completion">
    Poll the order, or listen for the webhook:

    ```bash theme={null}
    curl https://merchant.minisend.xyz/api/onramp/orders/7c1e4f9a-... \
      -H "Authorization: Bearer ms_live_your_key_here"
    ```

    When payment is collected, `status` becomes `completed` and `receipt_number` holds the M-Pesa confirmation code. An `onramp.completed` webhook fires at that moment; `onramp.released` follows once the on-chain transfer is confirmed and carries `release_tx_hash`. See [onramp webhooks](/onramp/webhooks).
  </Step>
</Steps>

## Quoting the other direction

If you'd rather guarantee a specific USDC amount and let the KES figure float, pass `amount_usdc` instead of `amount_kes`:

```bash theme={null}
curl -X POST https://merchant.minisend.xyz/api/onramp/quote \
  -H "Authorization: Bearer ms_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "KES",
    "amount_usdc": 10
  }'
```

The response's `amount_kes` is then the figure the customer is charged, always your requested `amount_usdc` plus the 1% fee. Pass the same field to `POST /api/onramp/orders` in place of `amount_kes`.
