Vanilla JS Elements
Use Cimplify Elements without React -- works with Vue, Svelte, plain HTML, or any frontend.
HTML
<!DOCTYPE html>
<html>
<body>
<div id="checkout-container"></div>
<div id="status"></div>
<script type="module">
import { createCimplifyClient } from "@cimplify/sdk";
const client = createCimplifyClient({ publicKey: "pk_live_..." });
const elements = client.elements("bus_123", {
appearance: {
theme: "light",
variables: { primaryColor: "#111827", borderRadius: "12px" },
},
});
// Single checkout element handles auth, address, and payment
const checkout = elements.create("checkout", {
orderTypes: ["pickup", "delivery"],
defaultOrderType: "pickup",
});
checkout.mount("#checkout-container");
checkout.on("authenticated", (data) => {
console.log("Token:", data.token);
console.log("Customer:", data.customer);
});
checkout.on("order_type_changed", (data) => {
console.log("Order type:", data.orderType);
});
checkout.on("ready", () => console.log("Checkout ready"));
checkout.on("error", (err) => console.error("Checkout:", err.message));
// Process checkout when ready
checkout.on("ready", async () => {
const result = await elements.processCheckout({
cart_id: "cart_123",
order_type: "delivery",
location_id: "loc_001",
enroll_in_link: true,
on_status_change: (status, context) => {
document.getElementById("status").textContent =
context.display_text || status;
},
});
if (result.success) {
window.location.href = "/order/" + result.order.id;
} else {
console.error(result.error?.code, result.error?.message);
}
});
</script>
</body>
</html>Standalone Auth Element
If you need a standalone sign-in step before the checkout element, use the auth element separately.
TS
const auth = elements.create("auth", { prefillEmail: "ada@example.com" });
auth.mount("#auth-container");
auth.on("authenticated", (data) => {
console.log("Signed in:", data.customerId);
// Now mount the checkout element
const checkout = elements.create("checkout", {
orderTypes: ["pickup", "delivery"],
});
checkout.mount("#checkout-container");
});Creating Elements
TS
import { createCimplifyClient } from "@cimplify/sdk";
const client = createCimplifyClient({ publicKey: "pk_live_..." });
const elements = client.elements("bus_123", { appearance });
// Primary: unified checkout element
const checkout = elements.create("checkout", {
orderTypes: ["pickup", "delivery"],
defaultOrderType: "pickup",
});
// Standalone auth (for sign-in only)
const auth = elements.create("auth", { prefillEmail: "..." });
// Mount to DOM -- accepts CSS selector or HTMLElement
checkout.mount("#checkout-container");
checkout.mount(document.getElementById("checkout-container"));Event Listeners
| Element | Event | Payload |
|---|---|---|
| checkout, auth | authenticated | { token, accountId, customerId, customer } |
| checkout, auth | requires_otp | { contactMasked } |
| checkout | order_type_changed | { orderType } |
| checkout | contact_provided | { contact, contactType } |
| checkout | checkout_status | { status, context } |
| checkout | checkout_complete | { success, order?, error? } |
| checkout | request_submit | {} |
| checkout, auth | ready | { height } |
| all | error | { code, message } |
TS
// Subscribe
checkout.on("authenticated", handler);
// Unsubscribe
checkout.off("authenticated", handler);CimplifyElements API
| Method | Returns | Description |
|---|---|---|
create(type, opts?) | CimplifyElement | Creates or reuses element for checkout, auth, address, or payment. |
getElement(type) | CimplifyElement | undefined | Returns existing element instance. |
processCheckout(opts) | AbortablePromise | Full checkout with status callbacks. Prefers checkout element, falls back to payment. |
submitCheckout(data) | Promise | Simpler checkout wrapper. |
isAuthenticated() | boolean | True when auth or checkout element has a session token. |
getAccessToken() | string | null | Current access token. |
destroy() | void | Unmounts all elements, removes listeners. Call on page teardown. |
CimplifyElement API
| Method | Description |
|---|---|
mount(selectorOrElement) | Mounts iframe into a CSS selector or HTMLElement. |
destroy() | Unmounts and clears handlers. |
on(event, handler) | Subscribe to element events. |
off(event, handler) | Remove a listener. |
getData() | Request current data from the iframe. |
setCart(cartData) | Send cart data (items, subtotal, tax, total) for inline order summary. |
isMounted() | True when iframe is connected. |
Cart Summary
Send cart data to the checkout element for an inline order summary with line items, tax, and totals. Call setCart() after the element is ready.
TS
checkout.on("ready", () => {
checkout.setCart({
items: [
{
name: "Jollof Rice",
quantity: 2,
unit_price: "25.00",
total_price: "50.00",
line_type: "simple",
},
],
subtotal: "50.00",
tax_amount: "4.50",
total_discounts: "0.00",
service_charge: "0.00",
total: "54.50",
currency: "GHS",
});
});Built-in Submit Button
The checkout element renders a submit button inside the iframe. When pressed, it fires request_submit. Listen for it to trigger processCheckout().
TS
checkout.on("request_submit", () => {
elements.processCheckout({
cart_id: "cart_123",
order_type: "delivery",
location_id: "loc_001",
on_status_change: (status, context) => {
console.log(status, context.display_text);
},
});
});Legacy: Composed Elements
Backward compatibility: create("address") and create("payment") still work but now render the full unified checkout UI internally. Use create("checkout") instead.
Cancellation and Cleanup
TS
const checkoutResult = elements.processCheckout({
cart_id: "cart_123",
order_type: "delivery",
timeout_ms: 180_000,
});
// Cancel in-flight checkout
checkoutResult.abort();
// On page teardown -- unmounts all elements, removes postMessage listeners
elements.destroy();