Checkout surfaces

Embed Throttle Without Owning Payment UI

Use an iframe-backed surface for payment capture while your backend controls session creation and your webhook endpoint controls durable state.

PaymentEmbed

Use PaymentEmbed when your storefront already owns cart, address, shipping, and order summary UI. Throttle renders the payment form and posts lifecycle events to the parent page.

Payment-only embed
import { PaymentEmbed } from '@usethrottle/checkout-react';

export function PaymentStep({ sessionId }: { sessionId: string }) {
  return (
    <PaymentEmbed
      sessionId={sessionId}
      parentOrigin="https://shop.example.com"
      baseUrl="https://checkout.usethrottle.dev"
      primary="#08786f"
      onReady={() => console.log('ready')}
      onProcessing={() => console.log('processing')}
      onSucceeded={({ orderId, paymentId }) => {
        window.location.href = `/thank-you?order=${orderId}&payment=${paymentId}`;
      }}
      onFailed={({ code, message }) => {
        console.error(code, message);
      }}
    />
  );
}

CheckoutEmbed

Use CheckoutEmbed when you want a fuller hosted checkout flow inside your page. It supports the same terminal events plus checkout step changes.

Full checkout embed
import { CheckoutEmbed } from '@usethrottle/checkout-react';

<CheckoutEmbed
  sessionId={sessionId}
  parentOrigin="https://shop.example.com"
  baseUrl="https://checkout.usethrottle.dev"
  logo="https://shop.example.com/logo.png"
  onStepChanged={({ step }) => analytics.track('checkout_step', { step })}
  onSucceeded={({ orderId }) => router.push(`/orders/${orderId}`)}
/>;

Raw iframe

If you are not using React, render the hosted checkout iframe directly and validate the postMessage envelope before trusting events.

Plain HTML
<iframe
  src="https://checkout.usethrottle.dev/c/SESSION_ID?embed=1&mode=payment-only&parentOrigin=https%3A%2F%2Fshop.example.com"
  style="width:100%;height:520px;border:0"
  allow="payment *"
></iframe>

<script>
  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://checkout.usethrottle.dev') return;
    if (event.data?.source !== 'throttle' || event.data?.version !== 1) return;

    if (event.data.type === 'throttle.completed') {
      window.location.href = '/thank-you?order=' + event.data.orderId;
    }
  });
</script>

Origin allowlist

Embedded checkout refuses to render unless the parent origin is allowlisted. Configure production and staging origins before mounting the iframe.

CLI
npm install -g @usethrottle/cli

throttle embed-config set \
  --origins https://shop.example.com,https://staging.shop.example.com \
  --primary "#08786f" \
  --logo https://shop.example.com/logo.png \
  --merchant-name "Example Shop"
Strict browser event routing
Throttle sends iframe events with a specific target origin. Your parent page should also verify event.origin, source: "throttle", and version: 1.