UCP Checkout Sessions: A Deep Dive
Protocols & Implementation

UCP Checkout Sessions: A Deep Dive

A comprehensive technical guide to implementing checkout sessions in Universal Commerce Protocol—from session creation to order completion.

In this article

Checkout sessions are the core transactional mechanism in Universal Commerce Protocol. They represent the stateful journey from “add to cart” to “order confirmed”—but designed for AI agents rather than human shoppers.

This deep dive covers the complete lifecycle, implementation patterns, and edge cases you’ll encounter in production.

Session Lifecycle Overview

Session Lifecycle

Sessions move through discrete states:

  • created — Session initialized with cart items
  • address_set — Shipping address provided, rates calculated
  • shipping_selected — Shipping method chosen
  • payment_pending — Ready for payment initiation
  • payment_processing — Payment in progress
  • completed — Order placed successfully
  • expired — Session timed out without completion
  • abandoned — Explicitly cancelled

Creating a Session

Sessions begin when an agent adds items to cart:

POST /api/ucp/checkout/sessions
Content-Type: application/json
{
"items": [
{
"product_id": "SKU-RUNNER-PRO-001",
"variant_id": "size-10-color-black",
"quantity": 1
},
{
"product_id": "SKU-SOCKS-CUSHION-003",
"quantity": 2
}
],
"locale": "en-US",
"currency": "USD"
}

Response Structure

{
"session_id": "cs_live_a1b2c3d4e5f6",
"status": "created",
"created_at": "2026-01-05T14:30:00Z",
"expires_at": "2026-01-05T15:30:00Z",
"items": [
{
"line_id": "li_001",
"product_id": "SKU-RUNNER-PRO-001",
"variant_id": "size-10-color-black",
"name": "CloudRunner Pro Marathon Shoe",
"quantity": 1,
"unit_price": 17999,
"line_total": 17999,
"available": true,
"image_url": "https://store.com/images/runner-pro.jpg"
},
{
"line_id": "li_002",
"product_id": "SKU-SOCKS-CUSHION-003",
"name": "Performance Cushion Socks (3-pack)",
"quantity": 2,
"unit_price": 1599,
"line_total": 3198,
"available": true,
"image_url": "https://store.com/images/socks.jpg"
}
],
"totals": {
"subtotal": 21197,
"discount": 0,
"shipping": null,
"tax": null,
"total": 21197
},
"currency": "USD",
"requires": ["shipping_address"]
}

Key Implementation Notes

Inventory validation is critical. Check availability before confirming items. Return clear errors if products are out of stock or discontinued.

Session expiration prevents stale carts. 60 minutes is typical, but adjust based on your checkout complexity.

Updating Sessions

Sessions are modified through PATCH requests. Each update recalculates totals.

Adding Shipping Address

PATCH /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6
Content-Type: application/json
{
"shipping_address": {
"recipient": "John Smith",
"line1": "123 Market Street",
"line2": "Apt 4B",
"city": "San Francisco",
"region": "CA",
"postal_code": "94105",
"country": "US",
"phone": "+14155551234"
}
}

Response now includes shipping options:

{
"session_id": "cs_live_a1b2c3d4e5f6",
"status": "address_set",
"shipping_address": { /* address object */ },
"shipping_options": [
{
"id": "standard",
"name": "Standard Shipping",
"description": "5-7 business days",
"price": 799,
"estimated_delivery": {
"min_days": 5,
"max_days": 7
}
},
{
"id": "express",
"name": "Express Shipping",
"description": "2-3 business days",
"price": 1499,
"estimated_delivery": {
"min_days": 2,
"max_days": 3
}
},
{
"id": "overnight",
"name": "Overnight Shipping",
"description": "Next business day",
"price": 2999,
"estimated_delivery": {
"min_days": 1,
"max_days": 1
}
}
],
"totals": {
"subtotal": 21197,
"discount": 0,
"shipping": null,
"tax": null,
"total": 21197
},
"requires": ["shipping_selection"]
}

Selecting Shipping Method

PATCH /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6
Content-Type: application/json
{
"shipping_selection": "express"
}

Response now includes calculated taxes:

{
"session_id": "cs_live_a1b2c3d4e5f6",
"status": "shipping_selected",
"shipping_selection": {
"id": "express",
"name": "Express Shipping",
"price": 1499
},
"totals": {
"subtotal": 21197,
"discount": 0,
"shipping": 1499,
"tax": 1872,
"total": 24568
},
"requires": ["payment"]
}

Applying Discount Codes

PATCH /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6
Content-Type: application/json
{
"discount_code": "WELCOME20"
}

Validation response if invalid:

{
"error": {
"code": "invalid_discount",
"message": "Code WELCOME20 has expired",
"field": "discount_code"
}
}

Payment Initiation

When all requirements are satisfied, agents can initiate payment:

POST /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6/pay
Content-Type: application/json
{
"payment_method": "card",
"payment_token": "tok_visa_4242424242424242",
"billing_address": {
"line1": "123 Market Street",
"city": "San Francisco",
"region": "CA",
"postal_code": "94105",
"country": "US"
}
}

Successful Payment Response

{
"session_id": "cs_live_a1b2c3d4e5f6",
"status": "completed",
"order": {
"order_id": "ORD-2026-01-05-789456",
"order_number": "FP-789456",
"status": "confirmed",
"created_at": "2026-01-05T14:45:00Z",
"totals": {
"subtotal": 21197,
"discount": 0,
"shipping": 1499,
"tax": 1872,
"total": 24568
},
"items": [ /* line items */ ],
"shipping_address": { /* address */ },
"tracking_url": "https://store.com/orders/FP-789456/track",
"estimated_delivery": "2026-01-08"
},
"payment": {
"id": "pay_a1b2c3d4",
"status": "captured",
"amount": 24568,
"method": "card",
"last_four": "4242"
}
}

Handling 3D Secure

If the payment requires additional authentication:

{
"session_id": "cs_live_a1b2c3d4e5f6",
"status": "payment_action_required",
"payment": {
"id": "pay_a1b2c3d4",
"status": "requires_action",
"action": {
"type": "three_d_secure",
"redirect_url": "https://acs.bank.com/3ds/challenge/...",
"return_url": "https://store.com/api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6/3ds-return"
}
}
}

Agents handle 3DS by directing the user to complete authentication, then polling the session for status updates.

sequenceDiagram
  participant Agent
  participant Store
  Agent->>Store: POST /checkout/sessions (items)
  Store-->>Agent: created + totals
  Agent->>Store: PATCH shipping_address
  Store-->>Agent: address_set + shipping options
  Agent->>Store: PATCH shipping_selection
  Store-->>Agent: shipping_selected + tax
  Agent->>Store: POST /pay (payment token)
  Store-->>Agent: completed + order

The happy path: four calls take a session from created to completed.

Error Handling

Inventory Changes During Checkout

{
"error": {
"code": "item_unavailable",
"message": "One or more items are no longer available",
"details": [
{
"line_id": "li_001",
"product_id": "SKU-RUNNER-PRO-001",
"issue": "out_of_stock",
"available_quantity": 0
}
]
}
}

Price Changes During Checkout

{
"error": {
"code": "price_changed",
"message": "Prices have changed since session creation",
"details": [
{
"line_id": "li_002",
"previous_price": 1599,
"current_price": 1799
}
],
"action_required": "confirm_price_change"
}
}

Payment Failures

{
"error": {
"code": "payment_declined",
"message": "Your card was declined",
"decline_code": "insufficient_funds",
"retry_allowed": true
}
}

Session Management Best Practices

1. Idempotency

Use idempotency keys to prevent duplicate operations:

POST /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6/pay
Idempotency-Key: pay_attempt_abc123

If the same key is sent twice, return the original response instead of processing again.

2. Optimistic Locking

Include version numbers to detect concurrent modifications:

{
"session_id": "cs_live_a1b2c3d4e5f6",
"version": 4,
// ... rest of session
}

Reject updates where the provided version doesn’t match:

PATCH /api/ucp/checkout/sessions/cs_live_a1b2c3d4e5f6
If-Match: "4"

3. Session Recovery

Store enough state to recover from failures:

{
"recovery": {
"can_retry_payment": true,
"items_reservable": true,
"original_session_id": "cs_live_a1b2c3d4e5f6",
"recovery_expires_at": "2026-01-05T16:30:00Z"
}
}

4. Rate Limiting

Implement per-session rate limits to prevent abuse:

  • 100/hour session creations per IP
  • 30/minute session updates per session
  • 5/hour payment attempts per session

Testing Checkout Sessions

Test Card Numbers

NumberBehavior
4242424242424242Succeeds
4000000000000002Declines
4000000000003220Requires 3DS
4000000000009995Insufficient funds

Test Scenarios Checklist

  • Successful checkout end-to-end
  • Inventory changes mid-checkout
  • Price changes mid-checkout
  • Session expiration handling
  • Payment decline and retry
  • 3D Secure flow completion
  • Discount code validation
  • International shipping address
  • Multi-item cart modifications

Implementing checkout sessions? Our open-source SFCC cartridge includes a complete reference implementation. Questions? Get in touch.

Share this article:

Written by

ForkPoint Team

The ForkPoint team brings 12+ years of e-commerce expertise, having built tools trusted by 25,000+ developers worldwide (as of 2025).

KEEP READING

Related Articles

Why We Open Sourced Our UCP Cartridge

Why We Open Sourced Our UCP Cartridge

We open-sourced our UCP cartridge for Salesforce Commerce Cloud because agentic commerce adoption requires the whole ecosystem to move — not just well-resourced enterprises. An MIT-licensed, productio ...

Read Article
Introducing the First Open-Source UCP Cartridge for SFCC

Introducing the First Open-Source UCP Cartridge for SFCC

The ucp-sfcc cartridge is the first open-source, MIT-licensed implementation of Universal Commerce Protocol (UCP) for Salesforce Commerce Cloud. It enables SFCC merchants to expose a UCP discovery man ...

Read Article
What is Universal Commerce Protocol? A Technical Primer

What is Universal Commerce Protocol? A Technical Primer

Universal Commerce Protocol (UCP) is an open standard developed by Google, Shopify, and 20+ partners that enables AI agents to discover products, compare options, and complete purchases on behalf of s ...

Read Article
Get Your Readiness Score Book Demo