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:
| Mode | Use case | What happens on completion |
|---|
payment | One-off payments | PaymentIntent transitions to succeeded |
order | Commerce flows with fulfillment | PaymentIntent 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 mode | Description | Required fields |
|---|
hosted (default) | Fluveo hosts the checkout page. Redirect the customer to the session url. | success_url |
embedded | Embed the checkout in your page using the client_secret. | None (uses client_secret) |
custom | Build 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
| Status | Meaning |
|---|
open | Session is active and accepting payment |
complete | Payment succeeded |
expired | Session 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