Building Agentic Commerce #5: UCP — Shopify's Universal Commerce Protocol in Practice
How UCP (Universal Commerce Protocol) enables AI agents to discover stores, create checkouts, link shopper identity, and fetch real-time catalog data — with production code examples.
Executive summary
Part 5 of 'Building Agentic Commerce' explains UCP — Google and Shopify's Universal Commerce Protocol. Covers protocol detection (3 confidence levels), discovery via /.well-known/ucp, 6-state checkout lifecycle, SCP identity linking with loyalty tiers, real-time catalog capability, AP2 mandate delegation, 5 MCP tools, and 215 tests.
Published
2026-04-06
14 min
Author
AgenticMCPStores Engineering
Core Protocol Team
Category
developer-guide
In Parts 1, 2, 3, and 4 we covered multi-protocol checkout, agent discovery, trust scores, and x402 stablecoin payments. Now we tackle the protocol backed by Google and Shopify with 30+ partners: UCP — the Universal Commerce Protocol.
What is UCP?
dev.ucp.*), native SCP identity linking for shopper loyalty data, and built-in AP2 mandate delegation for recurring payments.Discovery: /.well-known/ucp
/.well-known/ucp endpoint. Platform-level discovery returns all capabilities; merchant-level discovery returns store-specific profiles: // Platform discovery
GET /.well-known/ucp
// Merchant-specific discovery
GET /.well-known/ucp?store=my-store-slug
// Response (merchant profile)
{
"specVersion": "2026-01-23",
"status": "active",
"capabilities": [
"dev.ucp.shopping.checkout",
"dev.ucp.shopping.cart",
"dev.ucp.catalog.realtime",
"dev.ucp.identity.loyalty"
],
"extensions": ["dev.ucp.shopping.ap2_mandate"],
"services": {
"rest": "/api/v1/ucp",
"mcp": "/my-store-slug/mcp",
"a2a": "/my-store-slug/a2a",
"ag_ui": "/my-store-slug/ag-ui"
},
"paymentHandlers": ["stripe", "usdc_x402"],
"tools": [
"ucp_create_checkout",
"ucp_get_checkout",
"ucp_update_checkout",
"ucp_complete_checkout",
"ucp_cancel_checkout"
]
}dev.ucp.catalog.realtime, dev.ucp.identity.loyalty) appear only when the merchant has enabled them.Protocol Detection
The UCP inbound adapter uses three confidence levels to identify UCP requests:
- 1
UCP-Agentheader present → confidence 1.0 (explicit declaration) - 2Body contains
capabilitiesarray → confidence 0.9 - 3Body matches UcpCheckout Zod schema → confidence 0.85 (shape detection)
UCP is registered 4th in the protocol plugin registry (after ACP, AP2, x402). When multiple protocols match, the highest-confidence adapter wins. If no protocol is detected, ACP is used as the default fallback at confidence 0.5.
The 6-State Checkout Lifecycle
UCP Status → Intent Status → HTTP
─────────────────────────────────────────────────────
incomplete → CREATED → 200
requires_escalation → BLOCKED → 422
ready_for_complete → POLICY_EVALUATED → 200
complete_in_progress → DISPATCHED → 200
completed → COMPLETED → 200
canceled → FAILED → 409requires_escalation state is unique to UCP — it signals that a KYAI policy rule has blocked the checkout and the agent needs to escalate to the user for review. This is more expressive than ACP's binary success/failure model.Normalization: UcpCheckout → AgentPaymentIntent
AgentPaymentIntent format used by all protocols. The checkout mapper is a pure function with bidirectional mapping: // UcpCheckout input from agent
{
"id": "ckout-ucp-001",
"status": "incomplete",
"currency": "USD",
"line_items": [
{
"product_id": "prod-aaa",
"title": "Widget",
"quantity": 2,
"price": { "amount": 1500, "currency": "USD" }
}
],
"totals": [{ "label": "Subtotal", "amount": 3000, "currency": "USD" }],
"idempotency_key": "idempotent-123"
}
// Normalized to AgentPaymentIntent
{
id: "ckout-ucp-001",
status: "CREATED",
source: { sourceProtocol: "UCP", sourceVersion: "1.0" },
transaction: {
currency: "USD",
totalAmount: 3000,
items: [{ productId: "prod-aaa", title: "Widget", quantity: 2, unitPrice: 1500 }]
}
}intentToUcpCheckout() translates back for outbound responses.SCP Identity Linking
UCP natively integrates with SCP (Shopper Context Protocol) for identity verification and loyalty data. The flow uses OAuth 2.0:
// Step 1: Agent requests authorization
GET /ucp/identity/authorize?scope=loyalty:read,identity:link
→ Returns authorization code
// Step 2: Agent exchanges code for token
POST /ucp/identity/token
{ "code": "auth-code-123", "grant_type": "authorization_code" }
→ Returns { "access_token": "tok-xxx", "expires_in": 3600 }
// Step 3: Agent calls checkout with token
POST /api/v1/ucp/checkout
Authorization: Bearer tok-xxx
→ UCP Identity Service fetches real loyalty dataloyalty:read (access tier + discount eligibility), identity:link (link shopper identity), checkout:discount (apply loyalty discounts). The identity service fetches real data from the platform:- 1Shopify: Reads customer metafields (namespace
loyalty) via Storefront GraphQL. Maps tier to discount: gold = 10%, silver = 5%, bronze = 0%. - 2WooCommerce: Fetches points balance via
/wp-json/wc/v1/customers/{id}/points. ReturnsloyaltyPointscount. Graceful fallback if loyalty plugin not installed.
Real-Time Catalog (Phase B)
dev.ucp.catalog.realtime, agents can fetch live prices and inventory without a full catalog sync: GET /{slug}/ucp/catalog?product_ids=prod1,prod2&limit=20
{
"products": [
{
"id": "prod-aaa",
"title": "Widget A",
"price": { "amount": 1500, "currency": "USD" },
"availability": "IN_STOCK",
"inventory_count": 42
}
],
"freshness_ms": 2500
}freshness_ms field tells the agent how stale the data is. Results are cached for 30 seconds (near-realtime). The catalog service fetches from Shopify Storefront GraphQL or WooCommerce REST API depending on the platform.AP2 Mandate Delegation
dev.ucp.shopping.ap2_mandate, agents can embed recurring payment mandates directly in UCP checkout requests. The ucp-ap2-delegate.ts adapter extracts the mandate from the UCP extensions field and delegates to the existing AP2 parser — no new mandate verification code was written.Error Handling: Severity-Based Model
Severity → HTTP → Meaning
──────────────────────────────────────────────────
recoverable → 400 → Client can retry with different input
requires_buyer_input → 303 → Redirect agent to collect user input
requires_buyer_review → 422 → Policy rule needs user confirmation
unrecoverable → 409 → Checkout already completed or canceledrequires_buyer_input severity (303) is particularly useful — it tells the agent to use MCP elicitation or AG-UI to collect missing information (e.g., shipping address) rather than failing the checkout.UCP vs ACP: When to Use Which
| Aspect | UCP | ACP |
|---|---|---|
| Backed by | Google + Shopify (30+ partners) | Stripe + OpenAI |
| Discovery | /.well-known/ucp (dynamic, per-merchant) | /.well-known/acp.json (static) |
| Checkout states | 6 states (with escalation) | 4 states |
| Cart support | Yes (dev.ucp.shopping.cart) | No (checkout only) |
| Real-time catalog | Yes (dev.ucp.catalog.realtime) | No |
| Identity linking | SCP standard (OAuth 2.0) | Custom headers |
| Transports | REST, MCP, A2A, AG-UI, Embedded | REST, MCP |
| Extensibility | Extension namespace (dev.ucp.*) | Headers + body metadata |
| Error model | 4 severity levels | HTTP status + body |
Both protocols normalize to the same AgentPaymentIntent internal format and share the same KYAI policy engine. From the platform's perspective, UCP and ACP are just different protocol adapters — the checkout logic is identical.
MCP Tools for UCP
- 1
ucp_create_checkout— Create a UCP checkout session from line items - 2
ucp_get_checkout— Fetch checkout details by ID - 3
ucp_update_checkout— Modify items or totals - 4
ucp_complete_checkout— Finalize and trigger payment - 5
ucp_cancel_checkout— Cancel an active session
structuredContent (compatible with Claude SDK 1.27.x) alongside formatted text summaries. Idempotency is supported via idempotency_key — the same checkout ID + key returns the same response without re-processing.Merchant Configuration
POST /api/v1/stores/{storeId}/protocols
{
"protocol": "UCP",
"enabled": true,
"config": {
"capabilities": [
"dev.ucp.shopping.checkout",
"dev.ucp.shopping.cart"
],
"specVersion": "2026-01-23",
"enableMcpBinding": true,
"enableRestBinding": true,
"enableAp2Extension": false
}
}/.well-known/ucp?store=slug becomes available, and the 5 MCP tools are activated. KYAI policy rules apply immediately — no separate configuration needed.Test Coverage
The UCP implementation is backed by 215 tests across 22 test files. Coverage includes: inbound detection (25 tests), outbound translation (20 tests), checkout mapping (18 tests), error mapping (12 tests), AP2 delegation (20 tests), discovery profiles (25 tests), configuration validation (10 tests), integration end-to-end (30 tests), catalog service (40+ tests), identity service (35+ tests), and MCP tools (10 tests). All tests use pure function patterns with immutable data.
What's Next
Frequently asked questions
What is UCP and who created it?
UCP (Universal Commerce Protocol) is an open protocol designed by Google and Shopify with 30+ partners. It standardizes how AI agents interact with commerce platforms — from product discovery to checkout to identity linking.
How is UCP different from ACP?
UCP has a 6-state checkout lifecycle (vs ACP's 4), a capability extension namespace (dev.ucp.*), native SCP identity linking for loyalty data, real-time catalog access, and supports 5 transport bindings (REST, MCP, A2A, AG-UI, Embedded). ACP is Stripe-centric with simpler checkout flows.
Can UCP and ACP coexist on the same store?
Yes. Both protocols normalize to the same AgentPaymentIntent format and share the KYAI policy engine. The protocol detector routes each request to the correct adapter based on confidence scoring. A store can have both UCP and ACP enabled simultaneously.
What is SCP identity linking in UCP?
SCP (Shopper Context Protocol) enables agents to link shopper identity and access loyalty data via OAuth 2.0. Agents can read loyalty tiers (gold/silver/bronze), fetch points balances, and apply loyalty discounts at checkout.
How does UCP real-time catalog work?
When a merchant enables dev.ucp.catalog.realtime, agents can fetch live prices and inventory via GET /{slug}/ucp/catalog. Data is cached for 30 seconds with a freshness_ms field showing staleness. The service fetches from Shopify Storefront GraphQL or WooCommerce REST API.
Sources and references
- Universal Commerce Protocol Specification
UCP Working Group (Google + Shopify)
- Shopper Context Protocol (SCP)
SCP Working Group
- MCP Specification — Model Context Protocol
Anthropic
Related articles
developer-guide
Building Agentic Commerce #1: Multi-Protocol Checkout — MCP + x402 + ACP in One Flow
One agent, three protocols, one checkout. Here's how MCP, x402 stablecoin payments, and ACP work together to let AI agents buy products — with code examples you can run today.
developer-guide
Building Agentic Commerce #4: x402 Stablecoin Payments — When Agents Pay in USDC
How AI agents make on-chain USDC payments using the x402 protocol — multi-chain settlement, EIP-712 signatures, and production-ready stablecoin checkout.
integration-guide
Shopify MCP vs WooCommerce MCP: A Developer's Comparison
A deep-dive comparison of the Shopify and WooCommerce MCP connectors — authentication, sync mechanisms, data models, and architecture patterns for agentic commerce.