@usethrottle/checkout-sdk
v1.1.0
Published
Production checkout SDK for Throttle storefront integrations.
Readme
@usethrottle/checkout-sdk
Production checkout SDK for Throttle storefront integrations.
Use the server entrypoint from backend routes to create sessions, mint embed tokens,
and read orders/payments. Use the React wrapper in the browser when you want
idempotent terminal callbacks, telemetry, and brand theming on top of
@usethrottle/checkout-react.
Install
npm install @usethrottle/checkout-sdkQuickstart
import { ThrottleCheckout } from '@usethrottle/checkout-sdk';
<ThrottleCheckout
sessionId="sess_abc"
parentOrigin="https://shop.example.com"
theme={{ primary: '#ff6600', logo: 'https://shop.example.com/logo.png' }}
onSucceeded={({ orderId }) => router.push(`/orders/${orderId}`)}
onTelemetry={(event) => analytics.track(event.type, event)}
/>;Server quickstart
Use the server export from backend routes only. It keeps your Throttle API key
out of the browser and unwraps both { data } envelopes and direct responses.
import {
buildCheckoutEmbedUrl,
buildCheckoutHostedUrl,
createCheckoutClient,
} from '@usethrottle/checkout-sdk/server';
const checkout = createCheckoutClient({
apiKey: process.env.THROTTLE_API_KEY!,
baseUrl: process.env.THROTTLE_BASE_URL,
});
const session = await checkout.createSession({
storeId: process.env.THROTTLE_STORE_ID!,
cartId: 'cart_123',
returnUrl: 'https://shop.example.com/checkout/success',
cancelUrl: 'https://shop.example.com/cart',
allowedMethods: ['net30'],
paymentTerms: { netN: 45 },
collect: { shippingAddress: true, billingAddress: false },
});
const embedUrl = buildCheckoutEmbedUrl({
checkoutOrigin: 'https://checkout.usethrottle.dev',
sessionId: session.sessionId,
parentOrigin: 'https://shop.example.com',
mode: 'payment-only',
});
const hostedUrl = buildCheckoutHostedUrl({
checkoutOrigin: 'https://checkout.usethrottle.dev',
sessionId: session.sessionId,
});Server methods
| Method | Endpoint | Description |
| ----------------------------- | --------------------------------------------- | --------------------------------------------------------- |
| createSession(input) | POST /api/v1/checkout/sessions | Creates a cart-backed hosted/embed checkout session. |
| completeSession(id, input) | POST /api/v1/checkout/sessions/:id/complete | Completes a checkout session from server-side proxy mode. |
| createEmbedToken(input) | POST /api/v1/checkout-sessions/embed-token | Mints a Gr4vy Embed token for proxy-mode card capture. |
| getOrder(id) | GET /api/v1/orders/:id | Reads public-safe order totals/status. |
| listOrderPayments(id) | GET /api/v1/orders/:id/payments | Lists payments for an order. |
| listPaymentTransactions(id) | GET /api/v1/payments/:id/transactions | Lists transactions for a payment. |
| getOrderWithPayments(id) | Combined reads | Fetches an order, payments, and transactions together. |
Net-N invoice terms
Use paymentTerms.netN when creating a checkout session to stamp a cart-level
Invoice Terms override. Customer-level netN still wins when the attached
customer has an override; otherwise checkout falls back to the cart override and
then DEFAULT_NET_N.
customer.netN ?? cart.netN ?? DEFAULT_NET_NallowedMethods remains only a method filter, for example ['net30']; the
Net-N day count belongs in paymentTerms.netN.
Props
| Prop | Type | Required | Description |
| -------------- | ----------------- | -------- | ------------------------------------------------------------------------------ |
| sessionId | string | Yes | Throttle checkout session id (cs_*) |
| parentOrigin | string | No | Origin of the page mounting the embed |
| baseUrl | string | No | Override the hosted checkout URL (default: https://checkout.usethrottle.dev) |
| theme | BrandTheme | No | Brand colour + logo forwarded to hosted page |
| onSucceeded | (args) => void | No | Called once on successful payment |
| onFailed | (args) => void | No | Called once on terminal payment failure |
| onCancelled | () => void | No | Called when the user cancels |
| onTelemetry | (event) => void | No | Receives every lifecycle event |
Telemetry events
| event.type | Additional payload | Description |
| -------------- | ------------------------------------------------ | ------------------------------------------ |
| mounted | sessionId, timestamp | Component mounted in the DOM |
| ready | sessionId, timestamp | Hosted iframe fully loaded |
| processing | sessionId, timestamp | Payment authorization in-flight |
| succeeded | sessionId, orderId, paymentId, timestamp | Payment completed successfully |
| failed | sessionId, code, message, timestamp | Terminal payment failure |
| cancelled | sessionId, timestamp | User cancelled checkout |
| step_changed | sessionId, step, timestamp | Checkout step navigation (full embed only) |
Idempotency
onSucceeded and onFailed are terminal events — the underlying iframe can occasionally emit duplicate postMessages on network hiccups or React strict-mode double-renders. ThrottleCheckout maintains a settledRef that ensures only the first terminal event fires the callback. All subsequent duplicates are silently dropped.
Brand theming
theme.primary (a CSS colour string) and theme.logo (an absolute HTTPS URL) are forwarded as ?primary=...&logo=... query params on the hosted checkout iframe src. The hosted page (apps/checkout-web) reads these to apply the merchant's brand.
Build
pnpm --filter @usethrottle/checkout-sdk buildEmits CJS, ESM, and TypeScript declarations for both the browser entrypoint and
@usethrottle/checkout-sdk/server.
