Create a one-time purchase order from an existing checkout session and return a hosted PSP payment URL.
POST /v1/actions/onetime-order/create-order
Authentication: Session Token — see Customer Endpoints (customer or shopper role)
Checkout Flow
The merchant first calls Create Checkout Session to lock product version, pricing, and currency, and receives a sessionId
The buyer is sent to the hosted checkout page (or your own page if you handle the UI), where they confirm billing details
This endpoint is called to finalize the order — the server snapshots the price, calculates tax against billingDetail, writes the order, and creates the PSP checkout
The buyer is redirected to the returned checkoutUrl to complete payment
Price snapshot : the price is frozen at order creation time; later product price changes do not affect this order
Tax calculation : tax is computed from billingDetail (country, state for US/CA, business + VAT for EU)
PSP fault tolerance : if the PSP call fails, the order is rolled back so you can safely retry
Email normalization : buyerEmail is server-normalized with trim().toLowerCase() before tax calculation, order storage, session writeback, and PSP calls — Foo@Bar.COM and foo@bar.com are treated as the same buyer
Request Body
Field Type Required Description checkoutSessionIdstring Yes Checkout session ID returned by Create Checkout Session billingDetailobject Conditional Buyer billing detail (see below). Required unless already pre-filled on the session buyerEmailstring Conditional Buyer email. Required unless already pre-filled on the session; ignored when the session token carries a buyer identity buyerIpstring No Buyer IP address (used to refine tax calculation) successUrlstring No Override the success redirect URL configured on the session
storeId, productId, and currency are already locked on the checkout session — passing them in the body is ignored.
Billing Detail Object
Field Type Required Description countrystring Yes ISO 3166-1 alpha-2 country code isBusinessboolean Yes Whether this is a business purchase postcodestring No Postal or ZIP code statestring Conditional Required for US and CA businessNamestring Conditional Required when isBusiness is true taxIdstring Conditional Required for EU countries when isBusiness is true (VAT number)
Example Request
TypeScript (SDK)
TypeScript (Manual)
cURL
wget
import { WaffoPancake } from "@waffo/pancake-ts" ;
const client = new WaffoPancake ({
sessionToken: window . WAFFO_SESSION_TOKEN , // injected by the merchant's portal
environment: "prod" ,
});
const result = await client . orders . createOnetime ({
checkoutSessionId: "cs_550e8400-e29b-41d4-a716-446655440000" ,
buyerEmail: "customer@example.com" ,
billingDetail: {
country: "US" ,
isBusiness: false ,
state: "CA" ,
},
successUrl: "https://example.com/thank-you" ,
});
console . log ( result . checkoutUrl ); // "https://checkout.stripe.com/c/pay/cs_xxx"
Success Response (200)
{
"data" : {
"checkoutUrl" : "https://checkout.stripe.com/c/pay/cs_xxx"
}
}
Response Fields
Field Type Description checkoutUrlstring Hosted PSP payment URL — redirect the buyer here to complete payment
Errors
Retry policy: Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).
Status errors[0].messageWhat it means Recommended handling 400 Invalid JSON bodyRequest body is not valid JSON Fix the body, resubmit 400 Missing required field: checkoutSessionIdcheckoutSessionId was not providedFix the body, resubmit 400 Session product type mismatch: expected onetimeThe session was created for a subscription product Create a new one-time session and retry 400 Environment mismatch between request and sessionX-Environment differs from the session’s environmentUse the matching environment, resubmit 400 Missing billingDetail: provide in request body or pre-fill in checkout sessionNeither the request nor the session carries billingDetail Provide billingDetail, resubmit 400 State is required for US/CAbillingDetail validation failedFix billingDetail, resubmit 400 Missing buyerEmail: provide in request body or pre-fill in checkout sessionNeither the request nor the session carries a buyer email Provide buyerEmail, resubmit 401 Authentication failedSession token invalid, expired, or malformed Re-mint the session token via Issue Session Token 403 Session does not belong to this storeThe session was created for a different store Use a session belonging to the caller’s store 409 Checkout session invalid, please re-enter checkoutSession does not exist or has expired Create a new checkout session and restart the flow 500 Internal server errorUnexpected server-side failure Retry with exponential backoff (start 5s, max 3 attempts)