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:
- Your website or app. "Order on WhatsApp" instead of building a checkout.
- Ads. A landing page or Click-to-WhatsApp ad that drops the customer straight into a ready cart.
- AI agents. An assistant shops for someone and hands them a link to confirm and pay.
- Sales over chat. Send a customer a link for exactly what they asked 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
GET /v1/checkout_sessions/{id}GET /v1/checkout_sessions— filters:status,created_gte,created_ltPOST /v1/checkout_sessions/{id}/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 }.