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

# Create Checkout Request

> Initiate a hosted checkout session and receive a checkout URL.

## Overview

Use Checkout to collect a payment through a hosted page. Your account must have the **[Collections](/pages/guides/collections)** service enabled. For a full walkthrough, see the **[Checkout guide](/pages/guides/checkout)**.

Flow

1. Use `consumer_key` and `consumer_secret` to generate a token in **[Get Authentication Token](/api-reference/auth/auth-token)**.
2. Cache the token and refresh only on expiry.
3. Call **Create Checkout Request** with customer details, amount, and redirect URLs.
4. Redirect the user to the returned `checkout_url` (or render it in an iframe).
5. Receive the final result on your `callback_url` (see **[Webhooks](/pages/webhooks/overview)**).

***

## Authentication

**Required headers**

| Header          | Required | Notes              |
| --------------- | -------- | ------------------ |
| `Authorization` | Yes      | `Bearer <token>`   |
| `Content-Type`  | Yes      | `application/json` |

***

## Example request

```json theme={null}
{
  "customer": {
    "first_name": "Amina",
    "other_names": "Kariuki",
    "email": "amina.kariuki@example.com",
    "phone_number": "254733112244"
  },
  "timestamp": "2025-11-18T09:45:30.540Z",
  "checkout_reference": "CHK623581942",
  "payment_reference": "INV20478519",
  "msisdn": "254711223344",
  "country": "KEN",
  "currency": "KES",
  "amount": 1750.0,
  "mode": "redirect",
  "callback_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "success_redirect_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "fail_redirect_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "meta_data": {
    "order_id": "ORDER-39182"
  },
  "extra_params": {
    "language": "en",
    "expiry": "2026-02-14 18:30:00",
    "strict_amount": true
  }
}
```

***

## Example cURL

```bash theme={null}
curl --request POST \
  --url https://dev.waftpay.io/checkout/api/v1/request \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "customer": {
    "first_name": "Amina",
    "other_names": "Kariuki",
    "email": "amina.kariuki@example.com",
    "phone_number": "254733112244"
  },
  "timestamp": "2025-11-18T09:45:30.540Z",
  "checkout_reference": "CHK623581942",
  "payment_reference": "INV20478519",
  "msisdn": "254711223344",
  "country": "KEN",
  "currency": "KES",
  "amount": 1750,
  "mode": "redirect",
  "callback_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "success_redirect_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "fail_redirect_url": "https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1",
  "meta_data": {
    "order_id": "ORDER-39182"
  },
  "extra_params": {
    "language": "en",
    "expiry": "2026-02-14 18:30:00",
    "strict_amount": true
  }
}'
```

***

## Example response

```json theme={null}
{
  "code": "200",
  "status": "SUCCESS",
  "description": "Request accepted",
  "data": {
    "checkout_url": "https://waftpay.netlify.app/checkout/OTRkN2I2YTQtZTliZi00MDI0LTk2N2ItZGI1MTQ0NmU2NzY2",
    "expires_at": "2026-03-02T14:08:41.921Z"
  }
}
```

***

## Example callback payload

```json theme={null}
{
  "status": "SUCCESS",
  "code": "102",
  "description": "Transaction successfully processed",
  "results": {
    "transaction_reference": "CHK1769954123895429017",
    "checkout_status": "FULLY_PAID",
    "amount": 1750,
    "payments": [
      {
        "status": "SUCCESS",
        "result_code": "0",
        "result_description": "The service request is processed successfully.",
        "amount": 1750,
        "account": "254733112244",
        "total_charges": 140,
        "total_amount": 1750,
        "service_code": "SAF_COL_KE",
        "external_reference": "Q8MN7RX4J2",
        "payment_uuid": "197563911284320774",
        "time_processed": 1769954132.447
      }
    ],
    "metadata": "{\"order_id\":\"ORDER-39182\"}"
  }
}
```

***


## OpenAPI

````yaml POST /checkout/api/v1/request
openapi: 3.1.0
info:
  title: Waftpay Payments API
  description: >-
    Process payments, collect funds, and remit payouts with Waftpay. Includes
    Authentication Token, idempotency, webhooks, and sandbox support.
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://dev.waftpay.io
    description: Sandbox (dev)
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: Obtain and manage access tokens
  - name: Payments
    description: Charge a customer and track status
  - name: Collections
    description: Customer-initiated payments and hosted checkouts
  - name: Checkout
    description: >-
      Hosted checkout flow for customer payments.


      Flow:

      1. Ensure the Collections service is enabled for your account.

      2. Use `consumer_key` and `consumer_secret` to generate a Bearer token via
      **Get Authentication Token**.

      3. Cache the token and refresh only on expiry.

      4. Call **Create Checkout Request** with customer details, amount, and
      redirect URLs.

      5. Use the returned `checkout_url` for redirect or iframe.

      6. The `callback_url` receives a payload matching the `CheckoutCallback`
      schema.
  - name: Remittance
    description: Send payouts to mobile wallets and bank accounts
  - name: Webhooks
    description: Receive asynchronous notifications
  - name: Utilities
    description: Common utilities (idempotency, health)
paths:
  /checkout/api/v1/request:
    post:
      tags:
        - Checkout
      summary: Create Checkout Request
      description: >-
        Initiate a hosted checkout session and receive a `checkout_url` for
        redirect or iframe. Requires a valid Bearer token from **Get
        Authentication Token**. The `callback_url` receives the
        `CheckoutCallback` payload.
      operationId: createCheckoutRequest
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutRequest'
            examples:
              redirect:
                value:
                  customer:
                    first_name: Amina
                    other_names: Kariuki
                    email: amina.kariuki@example.com
                    phone_number: '254733112244'
                  timestamp: '2025-11-18T09:45:30.540Z'
                  checkout_reference: CHK623581942
                  payment_reference: INV20478519
                  msisdn: '254711223344'
                  country: KEN
                  currency: KES
                  amount: 1750
                  mode: redirect
                  callback_url: https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1
                  success_redirect_url: https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1
                  fail_redirect_url: https://webhook.site/aa2b85e4-1c13-4a9c-9b7e-3d7f3d91c9f1
                  meta_data:
                    order_id: ORDER-39182
                  extra_params:
                    language: en
                    expiry: '2026-02-14 18:30:00'
                    strict_amount: true
      responses:
        '200':
          description: Request accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckoutResponse'
              examples:
                accepted:
                  value:
                    code: '200'
                    status: SUCCESS
                    description: Request accepted
                    data:
                      checkout_url: >-
                        https://waftpay.netlify.app/checkout/OTRkN2I2YTQtZTliZi00MDI0LTk2N2ItZGI1MTQ0NmU2NzY2
                      expires_at: '2026-03-02T14:08:41.921Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    CheckoutRequest:
      type: object
      required:
        - customer
        - timestamp
        - checkout_reference
        - payment_reference
        - msisdn
        - country
        - currency
        - amount
        - mode
        - callback_url
        - success_redirect_url
        - fail_redirect_url
      properties:
        customer:
          $ref: '#/components/schemas/CheckoutCustomer'
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp for the request.
        checkout_reference:
          type: string
          description: Client-generated unique checkout reference.
        payment_reference:
          type: string
          description: Your internal invoice or payment reference.
        msisdn:
          type: string
          description: Payer phone number in MSISDN format (e.g., 2547XXXXXXXX).
        country:
          type: string
          description: ISO 3166-1 alpha-3 country code (e.g., KEN).
        currency:
          type: string
          description: ISO 4217 currency code (e.g., KES).
        amount:
          type: number
          description: Amount in major units (e.g., 1000 = 1000 KES).
        mode:
          type: string
          enum:
            - redirect
          description: Checkout mode.
        callback_url:
          type: string
          format: uri
          description: URL for payment status callback notifications.
        success_redirect_url:
          type: string
          format: uri
          description: URL to redirect on successful payment.
        fail_redirect_url:
          type: string
          format: uri
          description: URL to redirect on failed payment.
        meta_data:
          type: object
          description: Arbitrary key-value data returned in the callback.
          additionalProperties: true
        extra_params:
          $ref: '#/components/schemas/CheckoutExtraParams'
    CheckoutResponse:
      type: object
      required:
        - code
        - status
        - description
        - data
      properties:
        code:
          type: string
          example: '200'
        status:
          type: string
          example: SUCCESS
        description:
          type: string
        data:
          $ref: '#/components/schemas/CheckoutResponseData'
    CheckoutCustomer:
      type: object
      required:
        - first_name
        - other_names
        - phone_number
        - email
      properties:
        first_name:
          type: string
        other_names:
          type: string
        email:
          type: string
          format: email
        phone_number:
          type: string
          description: Customer phone number in MSISDN format (e.g., 2547XXXXXXXX).
    CheckoutExtraParams:
      type: object
      properties:
        language:
          type: string
          description: Checkout language preference (e.g., en, fr).
        expiry:
          type: string
          description: >-
            Optional expiry timestamp in `YYYY-MM-DD HH:mm:ss` format. If
            omitted, the default expiry applies.
        strict_amount:
          type: boolean
          description: >-
            If true, only full payment is allowed. If false, partial payments
            are allowed.
    CheckoutResponseData:
      type: object
      required:
        - checkout_url
        - expires_at
      properties:
        checkout_url:
          type: string
          format: uri
        expires_at:
          type: string
          format: date-time
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Machine readable error code
        message:
          type: string
          description: Human readable message
        param:
          type: string
        request_id:
          type: string
    WaftpayErrorEnvelope:
      type: object
      required:
        - code
        - status
        - description
      properties:
        code:
          type: string
          description: >-
            Application code. Can be a top-level code (e.g., 400.600) or a
            granular code (e.g., 404.001.000).
        status:
          type: string
          description: >-
            Semantic status, e.g., REJECTED, FAILED, UNAUTHORIZED, FORBIDDEN,
            NOT_FOUND, ACCEPTED.
        description:
          type: string
          description: Human-readable description.
        data:
          type: object
          description: Additional details (may be empty).
          additionalProperties: true
          nullable: true
      examples:
        notFoundGranular:
          summary: 404 with granular code
          value:
            code: 404.001.000
            status: REJECTED
            description: Requested resource not found
            data: {}
        validationFailed:
          summary: 400 validation failed
          value:
            code: '400.100'
            status: REJECTED
            description: Validation failed
            data:
              field_errors:
                - field: recipient.account
                  message: Invalid account
        unauthorized:
          summary: 401 failed authentication
          value:
            code: '400.200'
            status: REJECTED
            description: Failed Authentication
            data: null
        forbidden:
          summary: 403 failed authorization
          value:
            code: '403.300'
            status: REJECTED
            description: Failed Authorization
            data: null
        internal:
          summary: 500 internal server error
          value:
            code: '400.500'
            status: FAILED
            description: Internal server error
            data: null
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WaftpayErrorEnvelope'
          examples:
            unauthorized:
              value:
                code: 400.001.100
                status: REJECTED
                description: Invalid or expired token
                data: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````