Skip to main content

Overview

Once a shopper has a cart, you can either redirect them to Henry’s hosted checkout or run the entire checkout flow server-side with the headless SDK. Both approaches reuse the cart you built with the Universal Cart guide and return an order ID you can track afterwards.
import HenrySDK from '@henrylabs/sdk';

const client = new HenrySDK({
  apiKey: process.env.HENRY_API_KEY!,
});

Hosted checkout (fastest path)

Hosted checkout handles authentication, address capture, taxes, payments, and confirmation in a single responsive UI.
1

Generate a checkout URL

Generate the hosted checkout URL with client.cart.createCheckout. Pass the shopper’s identifier through x-user-id.
const checkout = await client.cart.createCheckout({
  'x-user-id': 'user_123',
});

const checkoutUrl = checkout.data.checkout_url;
Embed the URL in an iframe, open it in a new tab, or load it inside a native webview.
2

Listen for postMessage events

When you embed the checkout page, subscribe to window.postMessage to react to lifecycle events such as orderCompleted or checkoutClosed.
window.addEventListener('message', (event) => {
  if (!event.origin.endsWith('.henrylabs.ai')) return;

  const payload = event.data;
  if (payload?.type === 'orderCompleted') {
    const { orderId } = payload.data;
    // Persist the order ID and transition the UI
  }
});
See Hosted Checkout for a complete iframe integration.

Headless checkout API

Use the headless SDK when you want full control over the checkout experience while still relying on Henry for payments, risk, and order orchestration.
1

Create a quote session

Call client.checkout.session.createQuote with shipping details. The response returns a session_token and order_metadata containing taxes and totals.
const quote = await client.checkout.session.createQuote({
  'x-user-id': 'user_123',
  shippingDetails: {
    fullName: 'Jamie Merchant',
    email: 'jamie@example.com',
    phoneNumber: '+19175551234',
    addressLine1: '350 5th Ave',
    addressLine2: 'Floor 21',
    city: 'New York',
    stateOrProvince: 'NY',
    postalCode: '10118',
    countryCode: 'US',
  },
});

const sessionToken = quote.data.session_token;
const orderMetadata = quote.data.order_metadata;
console.log(orderMetadata.total_price, orderMetadata.tax);
2

Review the session state

Use the session token to inspect the products and any shipping metadata Henry derived.
const products = await client.checkout.session.listProducts({
  'x-session-token': sessionToken,
});

const shipping = await client.checkout.session.retrieveShippingInfo({
  // Required when using API key auth
  'x-user-id': 'user_123',
});
The products payload mirrors your cart, while the shipping response indicates whether Henry already has shipping info (hasShipping) and echoes the validated address.
3

Collect a payment method

Launch Henry’s hosted card collection modal before you place the order.
const cardCollect = await client.wallet.createCardCollection({
  'x-user-id': 'user_123',
});

const modalUrl = cardCollect.data.modal_url;
// Redirect or open the URL in a modal so the buyer can add a card
4

Confirm checkout

When the buyer approves the totals and payment method, call client.checkout.session.confirmCheckout to place the order. Provide the session token and include shipping details if you need to override the quote.
const confirmation = await client.checkout.session.confirmCheckout({
  'x-session-token': sessionToken,
  'x-user-id': 'user_123',
  // Optional shipping override:
  // shippingDetails: {
  //   fullName: 'Jamie Merchant',
  //   email: 'jamie@example.com',
  //   phoneNumber: '+19175551234',
  //   addressLine1: '350 5th Ave',
  //   city: 'New York',
  //   stateOrProvince: 'NY',
  //   postalCode: '10118',
  //   countryCode: 'US',
  // },
});

const orderId = confirmation.data.id;
const { grandTotal, status } = confirmation.data;
The confirmation response contains the newly created orderId, monetary breakdown (subtotal, tax, shipping, grandTotal), and line-item snapshot so you can display a receipt instantly.
Both hosted and headless flows return an order identifier you can monitor via the Order Management guide.