cimplify

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

ElementEventPayload
checkout, authauthenticated{ token, accountId, customerId, customer }
checkout, authrequires_otp{ contactMasked }
checkoutorder_type_changed{ orderType }
checkoutcontact_provided{ contact, contactType }
checkoutcheckout_status{ status, context }
checkoutcheckout_complete{ success, order?, error? }
checkoutrequest_submit{}
checkout, authready{ height }
allerror{ code, message }
TS
// Subscribe
checkout.on("authenticated", handler);

// Unsubscribe
checkout.off("authenticated", handler);

CimplifyElements API

MethodReturnsDescription
create(type, opts?)CimplifyElementCreates or reuses element for checkout, auth, address, or payment.
getElement(type)CimplifyElement | undefinedReturns existing element instance.
processCheckout(opts)AbortablePromiseFull checkout with status callbacks. Prefers checkout element, falls back to payment.
submitCheckout(data)PromiseSimpler checkout wrapper.
isAuthenticated()booleanTrue when auth or checkout element has a session token.
getAccessToken()string | nullCurrent access token.
destroy()voidUnmounts all elements, removes listeners. Call on page teardown.

CimplifyElement API

MethodDescription
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();

Next Steps