Skip to content

Checkout session


id: woocommerce-woo-store-checkoutsession owner: woocommerce method: POST path: /wp-json/headlesswp/v1/store/checkout-session title: Checkout session usedBySite: true

POST /wp-json/headlesswp/v1/store/checkout-session

Creates a checkout session via the HWP WooCommerce checkout bridge.

Auth + CSRF

  • Auth: public (guest checkout can be enabled by plugin settings).
  • Proxy nonce required: yes.
  • CSRF: required at the site proxy boundary.
  • The site sends requests through /api/secure/**, and X-WP-Nonce is attached by the secure request builder for this mutating endpoint. See request builder.

Request schema

Query parameters (optional):

  • ref (string): affiliate ref ID for tracking cookies.
  • campaign (string): optional campaign slug for tracking cookies.
  • utm_source (string): optional non-affiliate UTM source attribution value.
  • utm_medium (string): optional non-affiliate UTM medium attribution value.
  • utm_campaign (string): optional non-affiliate UTM campaign attribution value.
  • utm_content (string): optional non-affiliate UTM content attribution value.

JSON object fields accepted by the fixture controller:

  • items (required): array of 1..30 objects.
    • productId (required, integer > 0)
    • quantity (required, integer 1..50)
    • variationId (optional, integer > 0)
  • couponCode (optional, string)
  • couponCodes (optional, string[])
  • returnUrl (required for token_handoff; optional for redirect_to_woo; http/https URL)
  • cancelUrl (optional, http/https URL)
  • notes (optional, string)
  • paymentToken (optional, string; required only for token handoff strategy)
  • customer (optional object; shape depends on auth + checkout account creation settings)
  • billingAddress (optional object)
  • shippingAddress (optional object)
  • strategy (optional string)

Notes:

  • items is mandatory; missing/invalid payloads return VALIDATION_FAILED with fieldErrors.
  • Unknown top-level fields are rejected by the controller allowlist policy.
  • The sales site sends only upstream-supported request fields and does not include any local checkout mode field.
  • The sales site sends affiliate attribution via query params only and never includes an attribution field in the JSON body.
  • Attribution query params (ref, campaign, utm_source, utm_medium, utm_campaign, utm_content) are forwarded through the secure proxy allowlist when present.
  • Affiliate attribution retains precedence for Woo order attribution meta. When ref is present, Woo attribution fields are stamped from affiliate data.
  • Non-affiliate orders with any UTM query params stamp Woo order attribution with source_type=utm and the provided UTM values.
  • Non-affiliate orders without UTM query params default Woo attribution source_type to typein.

Response schema

Success envelope:

{
  "data": {
    "checkoutUrl": "https://...",
    "orderId": "123" 
  },
  "meta": {
    "correlationId": "...",
    "correlation_id": "...",
    "request_id": "...",
    "timestamp": "2025-01-01T00:00:00Z"
  }
}
  • orderId may be null.

  • meta follows the standard HWP response envelope fields.

  • This endpoint supports both redirect_to_woo and token_handoff strategies.

  • Token handoff uses a two-step Stripe PaymentIntent flow under the hood: create (payment_intents) then confirm (payment_intents/{id}/confirm).

  • returnUrl is required for token handoff because some Stripe configurations require return_url during confirm.

  • When returnUrl is provided, token handoff forwards it to Stripe as return_url on the confirm call.

  • utm_source, utm_medium, utm_campaign, and utm_content query params are accepted for both affiliate and non-affiliate checkouts.

  • Token handoff order creation stamps Woo attribution meta before gateway processing: affiliate requests keep precedence (source_type=referral, utm_source=affiliatewp, utm_medium=affiliate, campaign/content from referral context); non-affiliate requests with UTM query params set source_type=utm; non-affiliate requests without UTM query params default _wc_order_attribution_source_type to typein (Direct in Woo admin).

  • Valid marketing UTM values are also persisted on the order as additive HeadlessWP meta (marketingUtmSource, marketingUtmMedium, marketingUtmCampaign, marketingUtmContent) so campaign context is retained even when affiliate attribution takes precedence.

Token handoff success example:

{
  "data": {
    "orderId": 123,
    "mode": "token_handoff",
    "strategy": "token_handoff",
    "provider": "stripe",
    "paymentStatus": "paid",
    "status": "succeeded"
  },
  "meta": {
    "correlationId": "...",
    "correlation_id": "...",
    "request_id": "...",
    "timestamp": "2025-01-01T00:00:00Z"
  }
}

Error envelope:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Validation failed.",
    "details": {}
  },
  "meta": {
    "correlationId": "...",
    "correlation_id": "...",
    "request_id": "...",
    "timestamp": "2025-01-01T00:00:00Z"
  }
}

Token handoff gateway error example (sanitized):

Safe Stripe fields for token handoff failures:

  • details.gatewayError.code (string): sanitized Stripe error code when available.
  • details.gatewayError.decline_code (string | null): sanitized Stripe decline code when available (for example insufficient_funds, lost_card).
  • details.gatewayError.code = "fraud" maps to payment_fraud_blocked for customer-safe checkout copy.
  • lost_card, stolen_card, fraudulent, and merchant_blacklist decline codes map to payment_card_declined_generic to avoid leaking sensitive decline details.
  • The headless site can show deterministic Stripe decline messaging only for token_handoff failures, because redirect_to_woo completes payment on WordPress and does not expose Stripe decline details to the headless site in time for checkout messaging.
{
  "error": {
    "code": "CHECKOUT_FAILED",
    "message": "Checkout failed.",
    "details": {
      "safeReason": "stripe_error",
      "phase": "checkout_session",
      "step": "stripe_request",
      "gatewayError": {
        "type": "invalid_request_error",
        "code": "parameter_invalid_empty",
        "decline_code": null,
        "param": "payment_method",
        "message": "Payment method is required."
      },
      "gatewayRequestId": "req_123"
    }
  }
}

Error codes

Fixture-backed codes seen for this endpoint:

  • CHECKOUT_NOT_IMPLEMENTED
  • CHECKOUT_DISABLED
  • CHECKOUT_STRIPE_NOT_CONFIGURED
  • VALIDATION_FAILED
  • CHECKOUT_FAILED
  • CSRF_FAILED
  • RATE_LIMITED
  • NOT_AUTHENTICATED
  • IDEMPOTENCY_KEY_REUSE_CONFLICT