Checkout
Accept a payment for an amount you specify, server-to-server — Blitz handles the buyer-facing payment flow, then notifies you by webhook once it completes.
Create a checkout
/api/commerce/integration/checkoutRequires an API key with the checkout:write scope.
curl -X POST https://api.nest.useblitz.co/api/commerce/integration/checkout \
-H "Authorization: Bearer bk_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountMinorUnits": "2500",
"currency": "USD",
"provider": "STRIPE",
"returnUrl": "https://yourstore.com/orders/123/confirmation",
"checkoutMode": "REDIRECT",
"externalOrderRef": "your-internal-order-id",
"idempotencyKey": "unique-per-order"
}'Response (shown here as just the data portion — see Responses & Errors for the full envelope every endpoint wraps this in):
{
"orderId": "pay_...",
"provider": "STRIPE",
"checkoutMode": "REDIRECT",
"redirectUrl": "https://checkout.stripe.com/..."
}Redirect vs. embedded
checkoutMode: "REDIRECT" (the default) returns a redirectUrl — send the buyer there to complete payment; they land back on your returnUrl with ?order={orderId} appended. checkoutMode: "EMBEDDED" (Stripe only — rejected for PayPal) instead returns a clientSecret for Stripe Elements, and no redirect happens unless the payment method itself requires one (e.g. 3DS).
Embedding the hosted checkout page
This is a separate option from checkoutModeabove, and doesn't require the integration API at all. If you have a Blitz-hosted checkout link (e.g. a product checkout link from your merchant dashboard, of the form https://useblitz.co/checkout/{slug}), you can drop that page directly into an <iframe> by appending ?embed=trueto the URL. The embedded version renders without Blitz's page chrome and is served with frame-ancestors *, so it can be framed from any origin. Without ?embed=true, the same page refuses to be framed at all.
Use this when you want Blitz's full hosted checkout UI inline on your page with no integration work. Use checkoutMode: "EMBEDDED" instead when you want to build your own checkout UI around Stripe Elements.
Fields
amountMinorUnits— positive integer string, in minor units (cents for USD).provider—STRIPEorPAYPAL.returnUrl— required, HTTPS. Your own order-confirmation page — reaching it is not itself proof of payment; check real status via the status endpoint below or a webhook.idempotencyKey— strongly recommended. Retrying with the same key returns the existing order instead of creating a duplicate.subscriptionIntervalUnit— optional,"MONTHLY"or"YEARLY". Opts this checkout into recurring billing — see Recurring charges below.
Recurring charges (subscriptions)
Add subscriptionIntervalUnit to the same create call above to opt the order into recurring billing — Stripe only, a request with provider: "PAYPAL" is rejected with a 422. There's no separate "create subscription" call: the first checkout is both the purchase and the subscription setup, and it saves the card for off-session renewal charges.
curl -X POST https://api.nest.useblitz.co/api/commerce/integration/checkout \
-H "Authorization: Bearer bk_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountMinorUnits": "2500",
"currency": "USD",
"provider": "STRIPE",
"returnUrl": "https://yourstore.com/orders/123/confirmation",
"idempotencyKey": "unique-per-order",
"subscriptionIntervalUnit": "MONTHLY"
}'- We bill the saved card automatically on each renewal date — no action needed from you to trigger it.
- Every successful charge (the founding order and every renewal) fires the same
checkout.completedwebhook. A renewal delivery is distinguishable from the founding order by carrying asubscriptionIdfield — the founding order's payload doesn't have one:
{
"payoutId": "pay_...",
"amount": "2500",
"currency": "USD",
"provider": "STRIPE",
"subscriptionId": "cks_..."
}- After 3 consecutive declines the subscription is automatically cancelled — there's no paused/past-due state, and no dunning emails are sent to the buyer.
- There's no proration or plan-change support: cancelling and creating a fresh checkout is the only way to move a buyer to a different interval or amount.
Buyer self-service — unauthenticated, no API key. Possession of the subscriptionId is the credential, same trust model as the order-status endpoint below. cancel is idempotent — cancelling an already-cancelled subscription just returns its current state:
GET https://api.nest.useblitz.co/api/commerce/checkout/subscriptions/:subscriptionId
POST https://api.nest.useblitz.co/api/commerce/checkout/subscriptions/:subscriptionId/cancelsubscriptionIntervalUnit is only valid with provider: "STRIPE" — PayPal has no saved-card off-session charging in this integration, so a PayPal request with a subscription opt-in is rejected outright (422).Check order status
/api/commerce/checkout/orders/:orderId/statusPublic — no API key required. Poll this from your returnUrl, or use a webhook instead.
Returns { status, amountMinorUnits, currency, subscriptionId }. status reaches PAIDonce the payment is confirmed — that's the only signal that should trigger fulfillment on your side, not the redirect itself. subscriptionIdis set once a subscription opt-in on this order has been fulfilled — use it to show the buyer a "manage your subscription" link on your confirmation page.