Skip to main content
UCP checkout is a two-step flow: the agent first creates a cart session and receives shipping options, then confirms the order with a payment token from your payment service provider (PSP). Your backend owns all payment logic — UCP defines the request and response shape, not the payment infrastructure. This design means you can integrate whichever PSP you already use.

How the checkout flow works

Agent                               Your backend
  │                                      │
  ├─ POST /ucp/checkout ────────────────►│  (cart + shipping address)
  │◄──── checkout_id, shipping options ──┤
  │                                      │
  ├─ POST /ucp/checkout/:id/confirm ────►│  (shipping choice + payment token)
  │◄──── order_id, confirmation ─────────┤
  │                                      │
  ├─ GET /ucp/orders/:order_id ─────────►│  (status check)
  │◄──── order status, tracking ─────────┤

Step 1: Cart creation

The agent sends a POST to /ucp/checkout with the cart items and shipping address:
// POST /ucp/checkout
{
  "items": [
    {
      "product_id": "prod_123",
      "variant_id": "var_123_10_black",
      "quantity": 1
    }
  ],
  "shipping_address": {
    "name": "Jane Smith",
    "street": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94102",
    "country": "US"
  }
}
Your backend responds with a checkout session ID, shipping options, tax, and an expiry timestamp:
{
  "checkout_id": "chk_abc123",
  "subtotal": { "amount": 12999, "currency": "USD" },
  "shipping_options": [
    {
      "id": "standard",
      "name": "Standard Shipping (5-7 days)",
      "cost": { "amount": 599, "currency": "USD" }
    },
    {
      "id": "express",
      "name": "Express Shipping (2 days)",
      "cost": { "amount": 1499, "currency": "USD" }
    }
  ],
  "tax": { "amount": 1170, "currency": "USD" },
  "expires_at": "2026-04-10T12:30:00Z"
}

Cart request fields

items
array
required
Array of cart line items. Each item must include product_id, variant_id (if applicable), and quantity.
items[].product_id
string
required
The id of the product from your catalog endpoint.
items[].variant_id
string
The id of the specific variant. Required for products with variants — omit only for products with no options.
items[].quantity
integer
required
Number of units. Must be a positive integer.
shipping_address
object
required
Customer’s shipping address. Used to calculate applicable shipping options and tax.
shipping_address.name
string
required
Recipient’s full name.
shipping_address.street
string
required
Street address including house number.
shipping_address.city
string
required
City name.
shipping_address.state
string
required
State, province, or region code (e.g. "CA", "NY").
shipping_address.zip
string
required
Postal or ZIP code.
shipping_address.country
string
required
ISO 3166-1 alpha-2 country code (e.g. "US", "GB", "IN").

Step 2: Order confirmation

The agent sends the customer’s chosen shipping option and a payment token obtained from your PSP’s client-side SDK:
// POST /ucp/checkout/:checkout_id/confirm
{
  "shipping_option_id": "standard",
  "payment_method": {
    "type": "card",
    "token": "tok_visa_4242"
  }
}
Your backend processes the payment and returns the confirmed order:
{
  "order_id": "order_xyz789",
  "status": "confirmed",
  "total": { "amount": 14768, "currency": "USD" },
  "estimated_delivery": "2026-04-17",
  "confirmation_number": "ORD-2026-XYZ789"
}

Payment provider integration

UCP is payment-provider-agnostic. Integrate the PSP you already use.
Create a PaymentIntent when the agent confirms the order:
const paymentIntent = await stripe.paymentIntents.create({
  amount: total.amount,
  currency: total.currency.toLowerCase(),
  payment_method: paymentToken,
  confirm: true,
  return_url: `https://yourstore.com/orders/${orderId}`
})

if (paymentIntent.status === 'succeeded') {
  // Fulfill the order
}

Error responses

Return structured error objects so agents can relay accurate information to the customer and, where possible, recover automatically.

Payment failure

{
  "error": {
    "code": "payment_failed",
    "message": "Payment method declined. Please try another card.",
    "retryable": true
  }
}

Out of stock at confirmation

{
  "error": {
    "code": "out_of_stock",
    "message": "Running Shoes — Size 10 Black is no longer available.",
    "items": ["var_123_10_black"],
    "retryable": false
  }
}

Invalid shipping address

{
  "error": {
    "code": "invalid_address",
    "message": "Shipping address could not be validated.",
    "fields": ["zip"],
    "retryable": true
  }
}
Write error message values as human-readable sentences. The agent will read them directly and relay them to the customer. “Size 10 Black is sold out” is far more useful than "variant_unavailable".

Security requirements

Never store raw card numbers or full payment details in your systems. Always use tokenized payment methods from your PSP’s client-side SDK.
  • Serve all checkout endpoints over HTTPS
  • Validate all incoming request fields — item IDs, quantities, addresses — before processing
  • Implement idempotency keys to prevent duplicate orders if the agent retries a request
  • Re-check inventory availability at confirmation time, not just at cart creation
  • Never handle raw card data directly; accept only PSP-issued payment tokens

Best practices

Inventory can change in the minutes between cart creation and order confirmation. Always check stock again before processing the payment — not just when the cart session is opened.
Cart sessions should expire after 15–30 minutes. Include expires_at in your cart response so agents know when the session becomes invalid. If an agent tries to confirm an expired session, return a clear error with code: "session_expired".
Error messages are read directly by the AI agent and presented to the customer. Descriptive messages reduce confusion and help agents offer next steps (e.g. suggesting an alternative size or payment method).
Once an order is placed, push fulfillment and tracking updates via webhook so the customer receives proactive shipping status inside the AI conversation — without needing to check their email.

Next steps

ACP checkout guide

Implement ChatGPT Instant Checkout via the Agent Commerce Protocol.

Razorpay agentic payments

UPI-native agentic payments for Indian merchants.