Skip to main content
Create a subscription order from a pre-built checkout session. Returns the PSP checkout URL — redirect the buyer there to complete payment and start the subscription.
POST /v1/actions/subscription-order/create-order
Authentication: Session Token — see Customer Endpoints (customer or shopper role)

Behavior

  • Price snapshot — The subscription price is frozen at order creation (price_snapshot); two-phase pricing (regularPhase + optional specialPhase for trials) is supported.
  • Billing period mappingweekly -> week/1, monthly -> month/1, quarterly -> month/3, yearly -> year/1.
  • PSP fault tolerance — If the PSP call fails, the local order is canceled and the error is surfaced.
  • Session pre-fillbillingDetail and buyerEmail from the request body override any pre-filled values on the session; if both are missing the request is rejected with 400.
  • Email normalizationbuyerEmail is normalized with trim().toLowerCase() before use.
The following fields are sourced from the session and must NOT be sent in the request body: storeId, productId, billingPeriod, currency. They are ignored if provided.

Request Body

FieldTypeRequiredDescription
checkoutSessionIdstringYesCheckout session ID returned by create-checkout-session
billingDetailobjectConditionalBuyer billing info; required if not pre-filled on the session
billingDetail.countrystringYes (if billingDetail present)ISO 3166-1 alpha-2 country code
billingDetail.isBusinessbooleanYes (if billingDetail present)Whether the buyer is a business
billingDetail.postcodestringNoPostal code
billingDetail.statestringRequired for US/CAState / province code
billingDetail.businessNamestringRequired if isBusiness=trueLegal business name
billingDetail.taxIdstringRequired for EU business buyersVAT / tax ID (e.g. DE123456789)
buyerEmailstringConditionalBuyer email; required if not pre-filled on the session
buyerIpstringNoBuyer IP address (used for tax calculation)
successUrlstringNoPost-checkout redirect URL; overrides the session-level value

Example Request

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.createSubscriptionOrder({
  checkoutSessionId: "cs_550e8400-e29b-41d4-a716-446655440000",
  billingDetail: {
    country: "DE",
    isBusiness: true,
    businessName: "Acme GmbH",
    taxId: "DE123456789",
  },
  buyerEmail: "customer@example.com",
  successUrl: "https://myapp.com/subscription/success",
});

console.log(result.checkoutUrl);

Success Response (200)

{
  "data": {
    "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_xxx"
  }
}

Response Fields

FieldTypeDescription
checkoutUrlstringPSP checkout 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).
Statuserrors[0].messageWhat it meansRecommended handling
400Invalid JSON bodyRequest body is not valid JSONFix the request body, then resubmit
400Missing required field: checkoutSessionIdcheckoutSessionId was not providedFix the request body, then resubmit
400Session product type mismatch: expected subscriptionThe session was created for a non-subscription productUse a session created for a subscription product
400Environment mismatch between request and sessionRequest X-Environment does not match the session environmentAlign the request environment with the session
400Session missing subscription information (productVersionId or billingPeriod)Session is malformed — missing required subscription fieldsRecreate the checkout session
400Missing billingDetail: provide in request body or pre-fill in checkout sessionNeither the body nor the session contains billingDetailProvide billingDetail in the body, then resubmit
400State is required for US/CAbillingDetail.state is required for US / CA buyersAdd billingDetail.state, then resubmit
401Authentication failedSession token invalid, expired, or malformedRe-mint the session token via Issue Session Token
403Session does not belong to this storeThe session belongs to a different storeVerify the session’s store ownership
409Checkout session invalid, please re-enter checkoutSession does not exist or has expiredRe-create the checkout session
500Internal server errorUnexpected server-side failureRetry with exponential backoff (start 5s, max 3 attempts)