Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fluveo.com/llms.txt

Use this file to discover all available pages before exploring further.

A Checkout Session represents a single checkout attempt. It bundles line items, creates a PaymentIntent, and handles the payment flow. This guide covers every option available when creating and managing sessions.

Modes

Checkout Sessions support two modes:
ModeUse caseWhat happens on completion
paymentOne-off paymentsPaymentIntent transitions to succeeded
orderCommerce flows with fulfillmentPaymentIntent succeeds and an Order is created

Create a session in payment mode

curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "line_items": [
      {
        "price": "price_3fg6hj9km1np",
        "quantity": 2
      }
    ],
    "success_url": "https://yourstore.com/success?session_id={CHECKOUT_SESSION_ID}",
    "cancel_url": "https://yourstore.com/cart"
  }'

Create a session in order mode

curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "order",
    "line_items": [
      {
        "price": "price_3fg6hj9km1np",
        "quantity": 1
      },
      {
        "price": "price_9ab3cd5ef7gh",
        "quantity": 3
      }
    ],
    "success_url": "https://yourstore.com/order-confirmed",
    "cancel_url": "https://yourstore.com/cart",
    "customer": "cus_a1b2c3d4e5"
  }'

UI modes

The ui_mode parameter controls how the checkout interface is rendered:
UI modeDescriptionRequired fields
hosted (default)Fluveo hosts the checkout page. Redirect the customer to the session url.success_url
embeddedEmbed the checkout in your page using the client_secret.None (uses client_secret)
customBuild your own checkout UI. Use the client_secret to interact with the session.None (uses client_secret)

Hosted mode

curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "ui_mode": "hosted",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "success_url": "https://yourstore.com/success",
    "cancel_url": "https://yourstore.com/cart"
  }'
The response includes a url field — redirect your customer there to complete the payment.

Embedded mode

curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "ui_mode": "embedded",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ]
  }'
The response includes a client_secret field instead of a url. Use this secret to mount the embedded checkout component in your frontend.

Line items

Each line item references either an existing price or includes inline price_data:

Using an existing price

{
  "price": "price_3fg6hj9km1np",
  "quantity": 2
}

Using inline price data

{
  "price_data": {
    "currency": "usd",
    "product": "prod_8mn4qr7vw2xz",
    "unit_amount": 2500
  },
  "quantity": 1
}
All line items in a session must use the same currency. Mixing currencies will return a validation error.

Customer handling

You can associate a session with an existing customer or collect a new customer email:
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "customer": "cus_a1b2c3d4e5",
    "success_url": "https://yourstore.com/success"
  }'
Or use customer_email for guest checkout:
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "customer_email": "jane@example.com",
    "customer_creation": "always",
    "success_url": "https://yourstore.com/success"
  }'
Set customer_creation to "always" to create a customer record even for guest checkouts.

Payment intent configuration

Customize the underlying PaymentIntent with payment_intent_data:
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "payment_intent_data": {
      "capture_method": "manual",
      "description": "Order #12345",
      "metadata": {
        "internal_order_id": "12345"
      }
    },
    "success_url": "https://yourstore.com/success"
  }'

Shipping

Shipping options

Offer shipping rates for the customer to choose from:
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "order",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "shipping_options": [
      {
        "name": "Standard Shipping",
        "amount": 500,
        "currency": "usd",
        "delivery_estimate": {
          "minimum": { "unit": "business_day", "value": 5 },
          "maximum": { "unit": "business_day", "value": 7 }
        }
      },
      {
        "name": "Express Shipping",
        "amount": 1500,
        "currency": "usd",
        "delivery_estimate": {
          "minimum": { "unit": "business_day", "value": 1 },
          "maximum": { "unit": "business_day", "value": 2 }
        }
      }
    ],
    "success_url": "https://yourstore.com/order-confirmed",
    "cancel_url": "https://yourstore.com/cart"
  }'

Shipping address collection

Collect the customer’s shipping address during checkout:
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "order",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "shipping_address_collection": {
      "allowed_countries": ["US", "CA", "GB"]
    },
    "success_url": "https://yourstore.com/order-confirmed"
  }'
When line items reference products with shippable: true, shipping address collection is automatically enabled — you don’t need to set shipping_address_collection explicitly. If you do set it, your configuration takes precedence.
When the checkout completes in order mode, the shipping address, billing address, selected shipping method, and shipping cost are automatically captured on the resulting Order.

Session expiration

Sessions expire by default after 1 year. Set a custom expiration (minimum 30 minutes from now):
curl -X POST https://api.leanrails.com/v1/checkout/sessions \
  -u "sk_test_xxx:" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "mode": "payment",
    "line_items": [
      { "price": "price_3fg6hj9km1np", "quantity": 1 }
    ],
    "expires_at": 1742029200,
    "success_url": "https://yourstore.com/success"
  }'
You can also expire a session manually:
curl -X POST https://api.leanrails.com/v1/checkout/sessions/cs_5ab7cd9ef1gh/expire \
  -u "sk_test_xxx:" \
  -H "Idempotency-Key: $(uuidgen)"
When a session expires (automatically or manually), the associated PaymentIntent is canceled.

Retrieve a session

curl https://api.leanrails.com/v1/checkout/sessions/cs_5ab7cd9ef1gh \
  -u "sk_test_xxx:"

List sessions

curl "https://api.leanrails.com/v1/checkout/sessions?limit=5&status=open" \
  -u "sk_test_xxx:"

List line items

Retrieve the line items for a specific session:
curl https://api.leanrails.com/v1/checkout/sessions/cs_5ab7cd9ef1gh/line_items \
  -u "sk_test_xxx:"
Response:
{
  "object": "list",
  "data": [
    {
      "id": "csli_1ab2cd3ef4gh",
      "object": "item",
      "price": "price_3fg6hj9km1np",
      "quantity": 2,
      "amount_subtotal": 99800,
      "amount_total": 99800,
      "currency": "usd",
      "description": "Ergonomic Standing Desk"
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "url": "/v1/checkout/sessions/cs_5ab7cd9ef1gh/line_items"
}

Session statuses

StatusMeaning
openSession is active and accepting payment
completePayment succeeded
expiredSession expired before payment was completed

Next steps

  • Learn about Checkout Links for shareable, no-code payment URLs
  • Set up Webhooks to handle checkout.session.completed events
  • Use your own fulfillment workflow after receiving checkout.session.completed