Skip to main content
Kulmi Pay Checkout lets you create a payment session on your server and display a pre-built, branded checkout UI in your app — without building a payment form from scratch. You initialise the session with your public key and the amount, then embed the checkout in your page or redirect the customer to it. Kulmi Pay handles card tokenisation, M-Pesa prompts, and payment state for you.

Create a checkout session

Send a POST request to /api/v1/payment/collection/checkout/ with your public key and the payment details. The response includes a url (the hosted checkout page) and a signature you use to authorise subsequent payment calls from that session.
curl -X POST https://app.kulmipay.com/api/v1/payment/collection/checkout/ \
  -H "Content-Type: application/json" \
  -d '{
    "public_key": "<your_public_key>",
    "amount": 1500.00,
    "currency": "KES",
    "email": "customer@example.com",
    "api_ref": "ORDER-003",
    "card_tarrif": "BUSINESS-PAYS",
    "mobile_tarrif": "BUSINESS-PAYS"
  }'

Request fields

FieldTypeRequiredDescription
public_keystringYesYour publishable API key from the dashboard. You can also pass this in the X-KULMI-PUBLIC-API-KEY header instead.
amountnumberYesAmount to collect, in the specified currency.
currencystringYesCurrency code: KES, USD, EUR, or GBP.
emailstringNoPre-fill the customer’s email on the checkout page.
api_refstringNoYour internal reference for this transaction.
card_tarrifstringNoWho pays card transaction fees. BUSINESS-PAYS (default) or CUSTOMER-PAYS.
mobile_tarrifstringNoWho pays mobile money fees. BUSINESS-PAYS (default) or CUSTOMER-PAYS.
unique_api_refbooleanNoWhen true, if a checkout already exists for this api_ref, Kulmi Pay returns the existing session instead of creating a new one. Use this for idempotency.

Success response

{
  "id": "<checkout_id>",
  "url": "https://app.kulmipay.com/checkout/<checkout_id>/express/",
  "signature": "<jwt_signature>",
  "amount": "1500.00",
  "currency": "KES",
  "paid": false,
  "merchant_name": "Your Business Name"
}

Embed checkout in JavaScript or React

You can redirect the customer to the url from the response, or embed the checkout inside your app using an iframe or Kulmi Pay’s JavaScript widget.
async function createCheckout(orderRef, amount) {
  const response = await fetch(
    "https://app.kulmipay.com/api/v1/payment/collection/checkout/",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        public_key: process.env.KULMIPAY_PUBLIC_KEY,
        amount: amount,
        currency: "KES",
        api_ref: orderRef,
        mobile_tarrif: "BUSINESS-PAYS",
        card_tarrif: "BUSINESS-PAYS",
        unique_api_ref: true,
      }),
    }
  );

  const data = await response.json();

  // Option 1: redirect the customer
  window.location.href = data.url;

  // Option 2: embed in an iframe
  const iframe = document.getElementById("kulmipay-checkout");
  iframe.src = data.url;
}

Idempotency with unique_api_ref

If your user navigates away and returns, or your server retries a failed request, you may not want to create a duplicate checkout session. Set unique_api_ref: true and include a consistent api_ref value (such as your order ID). Kulmi Pay returns the existing checkout session if one already exists for that reference, rather than creating a new one.
{
  "public_key": "<your_public_key>",
  "amount": 1500.00,
  "currency": "KES",
  "api_ref": "ORDER-003",
  "unique_api_ref": true
}
The checkout session URL is tied to your business account. Always use your publishable (public) key in client-side code, never your secret key. Your secret key should only be used in server-side requests.