View as Markdown

Checkout sessions

A checkout session is a cart made somewhere else that the customer completes in WhatsApp. You create it, you get a url, and the customer opens it on their phone: WhatsApp starts a chat with the shop with a message like "Hi Mama Njeri's! I'd like to complete my order (C-7K2Q9)" ready to send. When they send it, the shop shows that cart for review, then takes delivery or pickup and payment (M-Pesa, card, or cash on delivery) as usual.

Use it for:

The order it becomes carries the session's source and attribution, so you can see which site, campaign or agent sold what.

Create a checkout session

POST /v1/checkout_sessions

curl $KIBANDA_API/v1/checkout_sessions \
  -H "Authorization: Bearer $KIBANDA_KEY" -H "Content-Type: application/json" \
  -d '{
    "items": [{ "external_id": "SKU-1001", "quantity": 2 }, { "product": "pr_9f2c", "quantity": 1 }],
    "source": "website",
    "attribution": { "utm_source": "instagram", "utm_campaign": "october" }
  }'
Parameter
items Required. 1–50 of { product | external_id | code, quantity }.
source website, agent, ad, link or api (default). Copied to the order.
customer { phone, name } — if phone is set, only that WhatsApp number can use the link.
attribution Your tracking fields (≤ 2 KB), e.g. UTM tags. Copied to the order.
expires_in Seconds, 300 to 604800. Default 86400 (24 h).
external_id, metadata
{
  "id": "cs_…",
  "object": "checkout_session",
  "code": "C-7K2Q9",
  "url": "https://wa.me/254700000000?text=Hi%20Mama%20Njeri%27s!%20I%27d%20like%20to%20complete%20my%20order%20(C-7K2Q9)",
  "status": "open",
  "items": [{ "product": "pr_1001", "quantity": 2 }, { "product": "pr_9f2c", "quantity": 1 }],
  "source": "website",
  "customer": null,
  "order": null,
  "attribution": { "utm_source": "instagram", "utm_campaign": "october" },
  "expires_at": 1792802400,
  "created": 1792716000
}

Redirect the customer to url (or show it as a QR code on desktop).

What the customer sees

Prices are checked when they open it: if something sold out or was archived since, it's left out and they're told. Quantities are capped at what's in stock.

Status

open → claimed (someone sent the code; it's now theirs) → completed (their order was placed; order is set) — or expired. A completed link can't be reused; a claimed link can't be used by another number.

Retrieve, list, expire

The checkout_session.completed event fires when its order is placed.

Without a server: the shop page and button

Every shop has a public page at https://api.kibanda.africa/s/<shop-slug> — a catalog with quantities and an Order on WhatsApp button. Use it as a link in bio or an ad landing page; UTM tags on the URL are recorded on the order.

To add the button to any website, no API key needed:

<script src="https://api.kibanda.africa/s/<shop-slug>/button.js" async></script>

<button data-kibanda-product="pr_9f2c" data-quantity="1">Order on WhatsApp</button>

Or build your own cart and call Kibanda.checkout([{ product: "pr_9f2c", quantity: 2 }]) — it creates the session and opens WhatsApp. Behind it is the public endpoint POST /s/<shop-slug>/checkout with { "items": [...] }, which returns { url, code }.