---
title: "Create a checkout session"
method: POST
path: "/api/v1/checkout-session"
tags: ["Checkout Sessions"]
---

# Create a checkout session

`POST /api/v1/checkout-session`

## Request

- Base URL: `https://sandbox.api.afriex.com`
- URL: `https://sandbox.api.afriex.com/api/v1/checkout-session`
- Auth: API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/afriex/apis/afriex-business-api/docs/api/v1/checkout-session/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a hosted checkout session for a customer and returns a `checkoutUrl` that the customer should be redirected to in order to complete payment. The session captures the merchant intent (amount, currency, merchant reference, customer details, and allowed payment channels).

The response carries the `checkoutId` and `checkoutUrl` directly, and no webhook is sent when a session is created. Track the payment with transaction events. Every transaction the customer's payment produces carries your `merchantReference` as `merchantReference`, and your `metadata` as `meta`, in transaction webhooks and in the transaction responses.

**Available in sandbox and production.** Create a session with a sandbox API key to try the full flow in test mode, and with a production API key to take real payments.

## Request body

- object
  - `amount` integer, required: The transaction amount in **minor currency units** (e.g. kobo for NGN, cents for USD). Minimum 100 (equivalent to 1 major currency unit).
  - `currency` string, required: 3-letter ISO 4217 currency code (e.g. NGN, GHS). Must be one of the currencies enabled for checkout sessions: NGN, GHS, KES, UGX, TZS, ETB, XAF, XOF, SLE, USD.
  - `merchantReference` string, required: Your own reference for this session, for example an order number. It is not required to be unique. It is returned as `merchantReference` on the transactions the customer's payment produces, so you can reconcile them with your order.
  - `redirectUrl` string, uri, required: HTTPS URL the hosted checkout sends the customer to when they leave the success screen after paying. No query parameters are added to it.
  - `name` string: Optional title of the session, at most 100 characters. Angle brackets and control characters are rejected.
  - `description` string: Optional description of what the customer is paying for.
  - `customer` CheckoutSessionCustomer, required
    - `name` string, required: The full name of the customer, at most 100 characters. Angle brackets and control characters are rejected.
    - `email` string, email, required: The email address of the customer.
    - `phone` string, required: The phone number of the customer in E.164 format.
    - `countryCode` string, required: The ISO 3166-1 alpha-2 country code of the customer (e.g., 'NG', 'GH'). Case-insensitive; values are normalized to uppercase.
  - `channels` string[], required: The payment channels you are willing to offer the customer, at least one. **This is a cap, not an exact list: you do not need to vary it per country.** The channels the customer is shown are decided when they open the checkout page, once their currency is known: channels it cannot collect on are dropped then, so the same list works for every country (send `["VIRTUAL_BANK_ACCOUNT", "MOBILE_MONEY", "CARD"]` and a KES checkout offers mobile money while a USD one offers cards).
  - `metadata` object: Optional flat key/value metadata to attach to the session. It is returned as `meta` on the transactions the customer's payment produces. Both keys and values must be strings. At most 50 entries; keys up to 128 characters, values up to 1024 characters.

## Response `201`

Checkout session created successfully.

- object
  - `data` CreateCheckoutSessionResponse
    - `checkoutId` string: Unique identifier of the checkout session. It is the last path segment of `checkoutUrl`.
    - `checkoutUrl` string, uri: The URL the customer should be redirected to in order to complete the hosted checkout flow. With a sandbox API key the host is `sandbox.pay.afriex.com`.
    - `channels` string[]: The payment channels you asked for (all of them when you sent none). The customer is shown the ones their currency can collect on, which is decided when they open the checkout page.

## Other responses

- `400`: Invalid request: the body failed validation (unknown fields are rejected), or your business has no webhook URL set.
- `401`: Unauthorized - Invalid business API key.
- `500`: Server error.
- `503`: Temporarily unavailable: an upstream service failed or timed out, or the API is momentarily offline. Retry with backoff and honour the Retry-After header when present.

---

[API](https://skmtc.dev/afriex/apis/afriex-business-api.md) - [All operations](https://skmtc.dev/afriex/apis/afriex-business-api/llms.txt) - [OpenAPI document](https://skmtc.dev/afriex/apis/afriex-business-api/revisions/d94198b6c256?raw)
