Skip to content
Orderboost
Esc
navigateopen⌘Jpreview
On this page

Integrate Orderboost checkout in a React application

Install the Orderboost React packages, open hosted checkout, and connect cart, sign-in, tip, and paid-resource elements to your application.

Use the Orderboost React packages to render checkout launchers and local commerce surfaces. Orderboost hosts buyer checkout, while your application supplies product URLs, placement, cart state, and lifecycle callbacks.

You consume Orderboost’s API and browser capabilities. You do not run Orderboost’s database or payment services as part of an application integration.

Get your integration values

Orderboost supplies these values when your application is registered:

Value Where to use it
API base URL SDK configuration and checkout API calls
App ID Every OrderboostWidget configuration
Allowed browser origins The production and preview origins that may load your app manifest
Merchant backend credentials Server-side checkout-session and OAuth calls, when your flow needs them

Never expose merchant backend credentials in browser code. If an origin or app ID is rejected, update the registered integration instead of bypassing the browser check.

Install the React packages

Add the SDK, React provider, and widget renderer to your application:

npm install @orderboost/react @orderboost/sdk @orderboost/widget
pnpm add @orderboost/react @orderboost/sdk @orderboost/widget
yarn add @orderboost/react @orderboost/sdk @orderboost/widget
bun add @orderboost/react @orderboost/sdk @orderboost/widget

OrderboostWidget includes its compiled styles. Your application does not need a separate widget stylesheet.

Choose the checkout element

Choose one intent for each element:

Buyer action initialScreen Your application owns
Buy one product buy-now The canonical product URL and launch placement
Review a cart cart Cart lines, quantities, and checkout continuation
Sign in sign-in The backend OAuth exchange and application session
Send a contribution send-tip The reason for the tip and server-created amount
Unlock a paid resource payment-gate The paid endpoint and payment-aware HTTP client

Orderboost derives the launcher label from initialScreen. Use the button and theme configuration for supported presentation changes.

Open hosted checkout from a product URL

The public buyer-checkout endpoint is the shortest custom Buy Now integration. Open the popup during the click before waiting for the network response:

import { preopenOrderboostPopup } from "@orderboost/widget";

export async function openOrderboostCheckout(productUrl: string) {
	const popup = preopenOrderboostPopup("buy-now", "Your order · Orderboost checkout");
	if (!popup) throw new Error("Pop-ups are blocked.");

	const response = await fetch("https://api.orderboost.example/api/v1/buyer-checkouts", {
		body: JSON.stringify({ productUrl, quantity: 1 }),
		credentials: "omit",
		headers: { "content-type": "application/json" },
		method: "POST",
		referrerPolicy: "no-referrer",
	});

	if (!response.ok) {
		popup.close();
		throw new Error("Checkout preparation failed.");
	}

	const result = (await response.json()) as { checkoutUrl: string };
	popup.location.replace(result.checkoutUrl);
}

Send the canonical product URL, selected option labels, and quantity. Do not send a browser-calculated price as authority. Orderboost resolves the merchant and current variant before creating checkout.

For a multi-item cart, send items instead of productUrl:

const body = {
	items: cart.lines.map((line) => ({
		productUrl: line.productUrl,
		quantity: line.quantity,
		selected: line.selected,
	})),
};

Render a server-created checkout session

Use OrderboostWidget when your backend already created a checkout and returned a short-lived browser session. Pass the checkout presentation and session to the browser:

import type { OrderboostCheckoutConfig, OrderboostCommerceSessionConfig } from "@orderboost/sdk";
import { OrderboostWidget } from "@orderboost/widget";

type Props = {
	checkout: OrderboostCheckoutConfig;
	session: OrderboostCommerceSessionConfig;
};

export function HostedBuyNow({ checkout, session }: Props) {
	return (
		<OrderboostWidget
			config={{
				apiBaseUrl: session.apiBaseUrl,
				appId: "your_app_id",
				checkout,
				commerceSession: session,
				displayMode: "popup",
				initialScreen: "buy-now",
			}}
			onCheckoutComplete={(result) => result.orderId && showOrder(result.orderId)}
		/>
	);
}

The session contains apiBaseUrl, checkoutId, clientToken, and optionally checkoutUrl. Treat clientToken as a short-lived browser capability. Create it on your backend and send it only to the browser that owns checkout.

Use displayMode: "page" with session.checkoutUrl to navigate the current tab. While a named popup remains open, another press focuses that popup instead of creating a duplicate.

Use createBuyNowLink for an email, message, anchor, social post, or QR code:

import { createBuyNowLink } from "@orderboost/sdk";

const href = createBuyNowLink("https://merchant.example/products/arc-field-pack?Color=Graphite", {
	apiBaseUrl: "https://api.orderboost.example",
	quantity: 1,
});

export function SharedBuyNow() {
	return <a href={href}>Buy Now</a>;
}

This capability-free link contains product intent, not checkout access. Orderboost resolves the current product and creates a fresh checkout when the buyer follows it.

The checkoutUrl returned by a buyer-checkout request is reusable too, but it is an unlisted bearer link. Share it only when everyone who receives it should be allowed to instantiate the configured checkout. Each redemption gets isolated buyer and payment state; the resulting checkout session expires independently while the reusable link remains active until revoked.

Connect a host-owned cart

Keep cart state in your application. Render the current lines in Orderboost, then create hosted checkout when the buyer continues:

import { OrderboostWidget } from "@orderboost/widget";

export function OrderboostCart({ cart }: { cart: StoreCart }) {
	return (
		<OrderboostWidget
			config={{
				apiBaseUrl: "https://api.orderboost.example",
				appId: "your_app_id",
				checkout: mapCartToCheckout(cart),
				displayMode: "bottom-right",
				initialScreen: "cart",
			}}
			onCartQuantityChange={(item, quantity) => cart.setQuantity(item.id, quantity)}
			onCheckoutContinue={() => openHostedCheckout(cart.lines)}
		/>
	);
}

mapCartToCheckout maps your cart into presentation data. openHostedCheckout sends canonical product URLs and quantities to /api/v1/buyer-checkouts. The newly returned Orderboost quote is authoritative.

Exchange Orderboost sign-in on your backend

Sign In opens the Orderboost account popup. Send its authorization result to your backend immediately:

import type { OrderboostAuthConfig } from "@orderboost/sdk";
import { OrderboostWidget } from "@orderboost/widget";
import { useState } from "react";

export function OrderboostSignIn({ auth }: { auth: OrderboostAuthConfig }) {
	const [signedIn, setSignedIn] = useState(false);

	return (
		<OrderboostWidget
			config={{
				apiBaseUrl: "https://api.orderboost.example",
				appId: "your_app_id",
				auth,
				displayMode: "modal",
				initialScreen: "sign-in",
			}}
			onAuthComplete={async (result) => {
				await exchangeOrderboostAuth(result);
				setSignedIn(true);
			}}
			signedIn={signedIn}
		/>
	);
}

Your same-origin backend exchanges the authorization result and creates the application session. Do not persist the PKCE verifier or resulting tokens in browser storage.

Render a hosted tip

Tip uses the same server-created checkout session as Buy Now. Omit shipping collection when the contribution has no physical fulfillment:

<OrderboostWidget
	config={{
		apiBaseUrl: session.apiBaseUrl,
		appId: "your_app_id",
		checkout: {
			collectBillingAddress: false,
			collectShippingAddress: false,
			kind: "tip",
			merchantName: "Northline Supply",
			tipPreset: { amount: "5.00", currency: "USD" },
			title: "Support the field guide",
		},
		commerceSession: session,
		displayMode: "popup",
		initialScreen: "send-tip",
	}}
/>

The amount in browser configuration is presentation data. Your backend-created checkout remains authoritative.

Connect Page Guard to a paid endpoint

Page Guard renders the locked, pending, error, and unlocked states. Your callback makes the Machine Payments Protocol (MPP) or x402 request:

<OrderboostWidget
	config={{
		apiBaseUrl: "https://api.orderboost.example",
		appId: "your_app_id",
		displayMode: "page",
		initialScreen: "payment-gate",
		paymentGate: {
			amount: "0.05",
			asset: "USDC",
			protocol: "x402",
			resource: "https://merchant.example/field-report",
		},
	}}
	onGatePayment={async ({ payment }) => {
		const response = await paidFetch(payment.resource);
		if (!response.ok) {
			return { message: `Payment failed (${response.status}).`, unlocked: false };
		}
		await verifySettlementEvidence(response);
		return { message: "Payment verified.", unlocked: true };
	}}
/>

paidFetch and verifySettlementEvidence are functions that your application supplies. Page Guard does not include a wallet, signer, facilitator, or paid endpoint.

Orderboost’s hosted-checkout Tempo MPP endpoint is a separate server-side checkout flow. Do not point Page Guard at it unless your application implements that checkout contract.

Validate the integration

Test these conditions before launch:

  • Your production and preview origins resolve the expected App ID
  • Popup checkout opens from a direct buyer action
  • Product and cart requests use canonical merchant URLs
  • Browser code contains no merchant credentials or payment secrets
  • Success handling requires a persisted orderId
  • Cancel, popup-close, and network-error paths leave your application recoverable

If Orderboost returns payment_adapter_unavailable, the checkout environment cannot accept payment. Contact the Orderboost integration owner instead of changing browser configuration.

Read Understand Orderboost button flows for the lifecycle and security boundaries behind each element.

Was this page helpful?