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

# Public checkout

> Payer-facing endpoints for payment links, business pay, and subscriptions.

These routes power hosted checkout and embed flows. They are **unsigned** unless noted. Base path: `https://api.morapay.io/api/public`.

Use them from your checkout BFF or browser when building custom payer UI. Merchant-side configuration lives under [Payment links](/api-reference/payment-links) and [Business QR](/api-reference/business-qr).

## Payment links

| Method | Path                              | Description                    |
| ------ | --------------------------------- | ------------------------------ |
| `GET`  | `/links/:lookup`                  | Link by slug or public code    |
| `POST` | `/links/:slug/sessions`           | Start checkout session         |
| `GET`  | `/links/gas-checkout/:publicCode` | Gas-sponsored checkout payload |

Legacy aliases under `/payment-links/*` mirror the same handlers.

### Get payment link

`GET /api/public/links/:lookup`

Optional query: `wallet` for wallet-aware pricing.

<RequestExample>
  ```bash cURL theme={null}
  curl -s "https://api.morapay.io/api/public/links/invoice-42"
  ```
</RequestExample>

<ResponseExample>
  <CodeGroup>
    ```json 200 OK theme={null}
    {
      "success": true,
      "data": {
        "id": "link_uuid",
        "title": "Invoice #42",
        "amount": 100,
        "currency": "USD",
        "publicCode": "abc123xyz",
        "isActive": true
      }
    }
    ```

    ```json 404 Not Found theme={null}
    {
      "success": false,
      "error": "Payment link not found.",
      "code": "resource.not_found",
      "requestId": "req_pl404"
    }
    ```

    ```json 410 Gone theme={null}
    {
      "success": false,
      "error": "Payment link is no longer active.",
      "code": "resource.conflict",
      "requestId": "req_pl410"
    }
    ```
  </CodeGroup>
</ResponseExample>

### Start checkout session

`POST /api/public/links/:slug/sessions`

<RequestExample>
  ```bash cURL theme={null}
  curl -s -X POST "https://api.morapay.io/api/public/links/invoice-42/sessions" \
    -H "Content-Type: application/json" \
    -d '{ "amount": 100, "currency": "USD" }'
  ```
</RequestExample>

<ResponseExample>
  <CodeGroup>
    ```json 201 Created theme={null}
    {
      "success": true,
      "data": {
        "sessionId": "session_uuid",
        "transactionId": "txn_uuid",
        "status": "PENDING"
      }
    }
    ```

    ```json 422 Unprocessable Entity theme={null}
    {
      "success": false,
      "error": "Amount is below the minimum for this link.",
      "code": "links.amount.below_minimum",
      "requestId": "req_sess422"
    }
    ```
  </CodeGroup>
</ResponseExample>

## Business pay

| Method | Path                      | Description                          |
| ------ | ------------------------- | ------------------------------------ |
| `GET`  | `/checkout/:businessSlug` | Open-amount business checkout config |

<RequestExample>
  ```bash cURL theme={null}
  curl -s "https://api.morapay.io/api/public/checkout/acme-coffee"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "success": true,
    "data": {
      "businessSlug": "acme-coffee",
      "name": "Acme Coffee",
      "defaultCurrency": "GHS",
      "enabled": true
    }
  }
  ```
</ResponseExample>

See [Business QR](/api-reference/business-qr) for merchant-side QR configuration.

## Subscription checkout

Public subscription routes live under `/api/public/subscription/*`. Subscribers never use merchant API keys.

| Method | Path                                                     | Description               |
| ------ | -------------------------------------------------------- | ------------------------- |
| `GET`  | `/subscription/:planId`                                  | Plan details for checkout |
| `POST` | `/subscription/:planId/quote`                            | Payer quote               |
| `POST` | `/subscription/:planId/session`                          | Create checkout session   |
| `GET`  | `/subscription/session/:sessionId`                       | Session status            |
| `POST` | `/subscription/:planId/subscribe`                        | Complete enrollment       |
| `POST` | `/subscription/:planId/session/:sessionId/crypto/intent` | Crypto payment intent     |
| `POST` | `/subscription/:planId/session/:sessionId/card/pay`      | Card payment              |
| `POST` | `/subscription/:planId/session/:sessionId/momo/charge`   | MoMo charge               |
| `GET`  | `/subscription/:planId/session/:sessionId/momo/poll`     | MoMo status poll          |

Merchant plan management: [Subscriptions](/api-reference/subscriptions).

<RequestExample>
  ```bash cURL theme={null}
  curl -s "https://api.morapay.io/api/public/subscription/plan_uuid"
  ```
</RequestExample>

<ResponseExample>
  <CodeGroup>
    ```json 200 OK theme={null}
    {
      "success": true,
      "data": {
        "id": "plan_uuid",
        "name": "Pro monthly",
        "amount": 29,
        "currency": "USD",
        "interval": "month"
      }
    }
    ```

    ```json 422 Unprocessable Entity theme={null}
    {
      "success": false,
      "error": "Plan is not active.",
      "code": "request.validation_failed",
      "requestId": "req_sub_checkout422"
    }
    ```
  </CodeGroup>
</ResponseExample>

## Payment requests

Payer-facing helpers for REQUEST-type invoices created via [Business QR](/api-reference/business-qr).

| Method | Path                        | Description              |
| ------ | --------------------------- | ------------------------ |
| `GET`  | `/requests/by-link/:linkId` | Lookup by pay link id    |
| `GET`  | `/requests/:id`             | Request detail           |
| `GET`  | `/requests/calldata`        | Crypto pay calldata      |
| `POST` | `/requests/confirm-crypto`  | Confirm on-chain payment |

Merchant management uses signed `GET`/`POST /api/v1/merchant/requests`.

## Checkout quotes

| Method | Path               | Description                                            |
| ------ | ------------------ | ------------------------------------------------------ |
| `POST` | `/quotes/checkout` | Multi-row token quotes (checkout UI)                   |
| `POST` | `/quotes/swap`     | Swap quote for on-chain checkout                       |
| `POST` | `/commerce/fiat`   | Fiat payer total (Core: `/api/commerce/checkout-fiat`) |

<RequestExample>
  ```bash cURL theme={null}
  curl -s -X POST "https://api.morapay.io/api/public/quotes/checkout" \
    -H "Content-Type: application/json" \
    -d '{
      "inputAmount": "100",
      "inputCurrency": "USD",
      "environment": "LIVE"
    }'
  ```
</RequestExample>

See [Quotes](/api-reference/quotes) and [Fiat checkout](/api-reference/fiat-checkout).

## Transaction status

| Method | Path                                   | Description              |
| ------ | -------------------------------------- | ------------------------ |
| `GET`  | `/transactions/:id`                    | Transaction by id        |
| `GET`  | `/transactions/verify-by-hash`         | Confirm on-chain payment |
| `GET`  | `/fiat/transactions/verify/:reference` | Fiat payment status      |

## Validation helpers

| Method | Path                          | Description                  |
| ------ | ----------------------------- | ---------------------------- |
| `POST` | `/validate/momo`              | Validate MoMo number         |
| `POST` | `/validate/bank`              | Validate bank account        |
| `GET`  | `/validate/banks?country=gha` | Bank list for checkout forms |

Documented in [Fiat checkout](/api-reference/fiat-checkout) and [Payout rails](/api-reference/payout-rails).

## Related

* [Payment links](/api-reference/payment-links)
* [Fiat checkout](/api-reference/fiat-checkout)
* [Subscriptions](/api-reference/subscriptions)
* [Conventions](/api-reference/conventions)
