cimplify
Checkout integration

CimplifyCheckout (React)

Mount the Cimplify checkout iframe from React. This is the recommended embedded checkout path for agent-built storefronts and custom merchant sites.

<CimplifyCheckout> gives the merchant a complete checkout on their own page: contact capture, Cimplify Link verification, saved details, address, payment, provider authorization, submit, recovery, and status updates. The SDK creates the checkout iframe and handles the message bridge, OAuth hand-off, checkout processing, aborts, and completion events.

Under the iframe, checkout mints a durable purchase intent, renders one immutable terms revision, and confirms that exact revision. A material or money change emits reviewing_terms; ctx.replacement_terms and ctx.terms_deltas let the host mirror the review state without guessing from cart totals.

For most storefronts, this is the embedded checkout integration to use.

Required Auth Setup

Checkout uses the storefront's OAuth client when a shopper chooses to use Cimplify saved details. Add the route handlers from Sign in with Cimplify, then expose these browser env vars:

NEXT_PUBLIC_CIMPLIFY_CLIENT_ID=cim_client_…
NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI=https://your-store.com/auth/callback

These values let checkout verify the shopper through auth.cimplify.io and return to the merchant page.

Example

import { CimplifyClient } from "@cimplify/sdk";
import { CimplifyCheckout } from "@cimplify/sdk/react";

const client = new CimplifyClient({
  publicKey: process.env.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY!,
  credentials: "include",
});

export function CheckoutScreen({ cartId }: { cartId: string }) {
  return (
    <CimplifyCheckout
      client={client}
      cartId={cartId}
      orderTypes={["delivery", "pickup"]}
      defaultOrderType="delivery"
      submitLabel="Pay now"
      appearance={{
        theme: "light",
        variables: { primaryColor: "#059669", borderRadius: "0.85rem" },
      }}
      onStatusChange={(status, ctx) => {
        console.log(status, ctx.display_text);
      }}
      onComplete={(result) => {
        if (result.success) {
          window.location.assign(`/orders/${result.order!.id}`);
        }
      }}
      onError={(err) => console.error(err.code, err.message)}
    />
  );
}

Props

PropTypeRequiredNotes
clientCimplifyClientyesSame client you use elsewhere; the checkout iframe inherits the public key.
businessIdstringnoAuto-resolved from the public key when omitted.
cartIdstringnoAuto-resolved via client.cart.get() when omitted.
intentIdstringnoConfirm an existing hosted-session/paylink intent. The iframe must not mint a replacement.
initialTermsCheckoutTermsViewnoInitial display hint for intentId; server authority is re-read before confirmation.
locationIdstringnoPin the order to a specific store location.
orderTypes("delivery" | "pickup" | "dine_in")[]noDefaults to ["pickup", "delivery"].
defaultOrderTypesame as abovenoPre-selected order type.
submitLabelstringnoOverride the Pay button copy.
enrollInLinkbooleannoDefault true. Saves details when the shopper opts in.
appearanceElementAppearancenoMemoize this; reference changes after mount are warned about and ignored.
linkUrlstringnoOverride the Link host for development.
onComplete(result: ProcessCheckoutResult) => voidyesFires once on terminal success/failure.
onStatusChange(status, ctx) => voidnoSee checkout lifecycle. reviewing_terms carries replacement terms/deltas or unavailable lines.
onError(err: { code, message }) => voidnoNon-terminal initialization or runtime errors.

For a hosted session or paylink, bind the element to the authority the server already minted. Do not pass the shopper's current cart as a substitute:

<CimplifyCheckout
  client={client}
  intentId={session.intent_id}
  initialTerms={session.terms}
  onComplete={handleComplete}
/>

initialTerms is sent in the initial iframe handshake so the screen can render before Pay is clicked. The iframe still fetches the intent again and confirms the current server-issued terms; the hint is never payment authority.

Checkout Sign-In UX

Checkout collects email or phone inline. Once the contact is valid, the SDK starts Cimplify OAuth with that contact as login_hint and checkout-oriented copy.

If the shopper already has a matching Cimplify session, checkout loads saved details without showing verification UI. If the shopper needs to verify, hosted auth opens directly to OTP/passkey for that contact. The checkout iframe only receives the access token after verification succeeds.

The UI does not reveal account existence before verification. It can show a generic "Use saved details with Cimplify" action after a valid contact, then Cimplify decides whether silent sign-in, OTP, passkey, consent, or account switching is needed.

Account Switching

When the shopper is signed in during checkout, checkout shows the verified contact and a Change action. Choosing Change starts Cimplify OAuth with an account-switch prompt so the shopper can use a different Cimplify account before selecting saved details or entering new payment information.

Agent Checklist

  1. Use <CimplifyCheckout> for embedded checkout.
  2. Set NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY, NEXT_PUBLIC_CIMPLIFY_CLIENT_ID, and NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI.
  3. Add /auth/callback with both GET and POST handlers.
  4. Use cpk_test_ / cpk_live_ for Cimplify public keys.
  5. Leave shopper verification to auth.cimplify.io.
  6. Load saved Link details only after verification completes.

Next

On this page