CheckoutElement
The full unified checkout iframe. Auth, address, payment method, and submit all live in one frame. This is the iframe behind `<CimplifyCheckout>` and the hosted Pay page, sharing the same code at `packages/link/src/pages/elements/checkout/`.
Iframe URL
https://link.cimplify.io/elements/checkout?businessId=biz_…&nonce=<random>
# Alias (same component, same behavior):
https://link.cimplify.io/elements/payment?businessId=biz_…&nonce=<random>What it renders
A vertically stacked form whose sections appear conditionally based on auth state and order type:
- Auth section: contact + OTP, hidden once a token is present.
- Order type: pickup / delivery / dine-in toggle (only when
orderTypescontains more than one). - Address section: shown for delivery orders. Picks from saved addresses if signed in; otherwise a form with optional "use my location".
- Payment section: saved methods if signed in; otherwise the merchant's configured options (mobile-money providers, card, cash).
- Save info: "remember me for 1-click checkout" toggle when the customer is signed in to Link.
- Submit button: rendered only when
renderSubmitButton: true. - Cart summary: when
set_carthas been called, switches the layout to two columns and shows itemized totals.
Init message
After ready, send the standard init. Fields specific to CheckoutElement:
| Field | Notes |
|---|---|
orderTypes | Subset of delivery | pickup | dine_in. Defaults to ["pickup", "delivery"]. |
defaultOrderType | Pre-selected order type. Falls back to first entry of orderTypes. |
renderSubmitButton | When true the iframe renders its own Pay button and emits request_submit. When false, you trigger process_checkout from the parent. |
submitLabel | Override the Pay button copy. |
prefillEmail | Seed the auth contact field. |
appearance | See Appearance API. |
demoMode | Skip API; useful for screenshots. |
Mounting
React (high-level)
import { CimplifyCheckout } from "@cimplify/sdk/react";
<CimplifyCheckout
client={client}
cartId={cart.id}
orderTypes={["delivery", "pickup"]}
defaultOrderType="delivery"
submitLabel="Pay GH₵29.99"
appearance={appearance} // memoize!
onComplete={handleComplete}
onStatusChange={handleStatus}
/>Vanilla
const checkout = elements.create(ELEMENT_TYPES.CHECKOUT, {
orderTypes: ["delivery", "pickup"],
defaultOrderType: "delivery",
submitLabel: "Pay GH₵29.99",
});
checkout.on(EVENT_TYPES.REQUEST_SUBMIT, async () => {
const result = await elements.processCheckout({
cart_id: cart.id,
order_type: "delivery",
});
// …
});
checkout.mount("#checkout");Pre-filling the cart
set_cart renders the line-item summary alongside the form. The element switches to a 2-column layout when a cart is provided. CheckoutCartData:
interface CheckoutCartData {
items: CheckoutCartItem[];
subtotal: string;
tax_amount: string;
total_discounts: string;
service_charge: string;
total: string;
currency: string; // ISO 4217
}
interface CheckoutCartItem {
name: string;
quantity: number;
unit_price: string; // Money string
total_price: string;
image_url?: string;
line_type: "simple" | "service" | "bundle" | "composite" | "digital";
variant_name?: string;
scheduled_start?: string; // ISO 8601 (services)
scheduled_end?: string;
selections?: { name: string; quantity: number; variant_name?: string }[];
add_ons?: { name: string; price: string }[];
special_instructions?: string;
}Lifecycle
See checkout lifecycle for the full state machine. The element emits checkout_status for every transition and checkout_complete on terminal success or failure.
Authorization challenges
When the payment provider needs an OTP, PIN, birthday, phone, or address to authorize, the element switches to its built-in AuthorizationView and emits checkout_status: "awaiting_authorization" with context.authorization_type. The customer enters the challenge inside the iframe; you don't need to render anything yourself.
Recovery
If the customer reloads while a payment is in flight, the element rehydrates from local storage on next mount and resumes from the last known state. The first lifecycle event you receive will be checkout_status: "recovering".
Next
- CimplifyCheckout (React): High-level wrapper
- Embedded iframe: Raw postMessage integration
AuthElement
A single-line OTP sign-in component. Customer types an email or phone number, presses submit, types the 6-digit code, and the Element emits an `authenticated` event with a Link session token. Use it standalone (e.g. on a login page) or alongside other Elements (the parent controller broadcasts the token to them automatically).
AccountElement
An embeddable, chrome-less version of the Link dashboard. Drop it on any page where the customer is already signed in to Cimplify Link and they can manage their saved addresses, payment methods, sessions, orders, and subscriptions without leaving your domain.