Appearance
Universal Commerce Protocol Adapter (UCP)
Status: Implemented (Phase 1: Checkout, Phase 2: Order Webhooks, Phase 3: Identity Linking).
Purpose
UCP is the external commerce adapter. It implements the Universal Commerce Protocol (UCP spec v2026-01-11) so that external platforms — AI agents, apps, search engines, and marketplaces — can transact with g3nretailstack merchants through a single standardized API. UCP translates protocol-level calls into internal service operations, primarily SCM for order creation and CRM for customer identity.
The UCP specification is an open standard backed by Google, Shopify, Walmart, Target, Etsy, Wayfair, Visa, Mastercard, PayPal, and others. It defines a common API contract between platforms (the consumer-facing surface) and businesses (the merchant of record).
Goals
- Give any UCP-compliant platform a zero-integration path to transact with a merchant.
- Support capability negotiation so merchants control what is exposed (checkout, order webhooks, identity linking).
- Provide signed webhook delivery so platforms receive real-time order lifecycle events.
- Enable identity linking so platforms can associate their users with merchant customer records.
Non-goals
- UCP does not own product truth (owned by PVM/PMC).
- UCP does not own pricing (owned by PPM).
- UCP does not own inventory (owned by ICS).
- UCP does not own the sales order after creation (owned by SCM).
- UCP does not own customer records (owned by CRM).
- UCP does not process payments. Payment handlers are declared in the capability profile but are currently stubbed; payment_status is always
none.
System-of-record boundaries
- UCP owns platform credentials, checkout sessions, webhook delivery records, and identity links (tokens + auth codes).
- SCM owns the sales order once checkout/complete succeeds. UCP holds a reference (
scm_order_guid) but does not modify the order after creation. - CRM owns customer records. UCP reads customer data for identity linking but does not write to CRM.
- OFM is referenced for orgcode-to-org resolution during capability discovery.
Capability negotiation
Every organization publishes a UCP profile at GET /.well-known/ucp?orgcode=X. The profile declares which capabilities are enabled and what currencies are supported. A platform reads this profile to know what operations are available before making any calls.
Capabilities are set by the merchant admin via POST /config/set:
- checkout — cart-to-order session model.
- order — HMAC-signed webhook delivery for 20 order lifecycle event types.
- identity — OAuth 2.0 identity linking between platform users and CRM customers.
When identity linking is enabled, the profile includes the OAuth Authorization Server Metadata URL (RFC 8414) so platforms can discover token and revocation endpoints automatically.
Auth model
UCP uses three auth modes, each for a different caller type:
- Admin auth — standard session/API key auth (same as all other services). Used for platform CRUD, config, webhook configuration, and identity link management. Requires
ucp_adminorownerrole. - Platform auth —
client_id+client_secretin the request body. Used for checkout operations, token exchange, and token revocation. Credentials are issued by admins via/platform/register; the secret is shown once and stored as a SHA-256 hash. - Bearer auth —
Authorization: Bearer <token>header. Used for identity-linked operations (userinfo). Tokens are opaque strings; the system SHA-256 hashes them for DDB lookup.
Core business entities
- Platform — a registered external platform with credentials, scopes, and webhook configuration.
- Checkout session — a temporary cart-to-order session with line items, buyer info, pricing, and a finite-state lifecycle.
- Webhook delivery — a record of an outbound HMAC-signed event delivered (or pending retry) to a platform's callback URL.
- Identity link — a binding between a platform and a CRM customer, with scopes and active/revoked status.
- Auth code — a short-lived (10-minute) authorization code for the OAuth identity linking flow.
- Access token — a 1-hour opaque token that grants bearer access to identity-linked customer data.
- Refresh token — a 30-day opaque token that can be exchanged for a new access token.
Lifecycle and status models
Checkout session FSM
incomplete → requires_escalation → ready_for_complete → complete_in_progress → completed
│ │ │
└── canceled ←─┘──────────────────────┘- A session starts as
incompleteuntil buyer info and line items are present. ready_for_completemeans the session can be finalized.complete_in_progressis set while the SCM order is being created.completedis terminal — the SCM order exists.canceledis terminal — can be reached from any non-terminal state.
Identity link lifecycle
- A link is created as
activewhen a platform exchanges an auth code for tokens. - An admin can revoke a link, setting status to
revokedwith arevoked_attimestamp. - Tokens associated with a revoked link will fail on the next validation attempt.
Webhook delivery lifecycle
- A delivery starts as
pendingwith attempt_count=0. - On successful HTTP delivery (2xx), status moves to
delivered. - On failure, the delivery is re-queued with exponential backoff (30s base, 900s max, up to 5 attempts).
- After 10 consecutive failures across all deliveries for a platform, the platform's
webhook_statusis set topaused. deadis terminal — maximum attempts exhausted.
End-to-end workflows
Platform onboarding
- Merchant admin registers a platform:
POST /platform/registerwith caption and scopes. - System returns
client_idandclient_secret— the secret is shown once only. - Admin configures capabilities:
POST /config/setwithcapabilities: ["checkout", "order", "identity"]. - Admin sets webhook config:
POST /webhook/config/setwith event types and callback URL. - Admin tests webhook delivery:
POST /webhook/testsends a test event to the callback URL. - Platform verifies profile:
GET /.well-known/ucp?orgcode=Xreturns enabled capabilities.
Checkout flow (platform-initiated)
- Platform creates a checkout session with line items and optional buyer:
POST /checkout/create. - Platform updates the session as needed (full cart replacement):
POST /checkout/update. - When the session status is
ready_for_complete, the platform finalizes:POST /checkout/complete. - UCP calls SCM to create the sales order. On success,
scm_order_guidis returned and the session iscompleted. - On failure, the session reverts to
ready_for_completewith an error message. - The platform can cancel at any time:
POST /checkout/cancel.
Order webhook delivery
- SCM emits order lifecycle events to the
scm-eventsEventBridge bus (e.g.,order-placed,shipment-created,return-requested). - UCP's event ingest Lambda receives events filtered by
channel_code === 'ucp'. - For each registered platform with matching webhook event subscriptions, a signed delivery is created.
- The delivery is sent as an HTTP POST to the platform's
callback_urlwith HMAC-SHA256 signature headers. - Failed deliveries are retried with exponential backoff via a scheduled retry Lambda (every 2 minutes).
- After 10 consecutive failures, the platform is auto-paused. Admins can re-enable via
/webhook/config/set.
Identity linking (admin-mediated OAuth 2.0)
- Admin issues an authorization code:
POST /identity/authorizewith{platform_guid, customer_guid}.- Validates the platform is active and the customer exists in CRM.
- Returns a 10-minute authorization code. Optionally accepts a PKCE
code_challenge(S256).
- Admin provides the code to the platform out-of-band (email, dashboard, API).
- Platform exchanges the code for tokens:
POST /identity/tokenwithgrant_type: authorization_code.- Validates client credentials, verifies PKCE if code_challenge was set, consumes the code (single use).
- Creates the identity link and returns
access_token(1h) +refresh_token(30d).
- Platform accesses customer info:
POST /identity/userinfowithAuthorization: Bearer <token>.- Returns customer fields (email, phone, name, customer_code) scoped by the token's scopes.
- Platform refreshes expired tokens:
POST /identity/tokenwithgrant_type: refresh_token.- Issues a new access token; old access token is invalidated.
- Platform revokes tokens:
POST /identity/revokewith the token value (RFC 7009 — always returns 200). - Admin can list links (
POST /identity/link/list) or revoke a link (POST /identity/link/revoke).
Webhook event types (20)
Order lifecycle events delivered to platforms:
| Category | Events |
|---|---|
| Order | order.created, order.placed, order.fulfilled, order.cancelled, order.closed, order.line_cancelled |
| Fulfillment | fulfillment.shipment_created, fulfillment.shipment_updated, fulfillment.shipment_cancelled, fulfillment.delivered |
| Return | return.requested, return.authorized, return.received, return.inspected, return.resolved |
| Adjustment | adjustment.refund |
| Promise | promise.quoted, promise.reserved, promise.allocated, promise.committed |
Webhook headers: x-ucp-event-type, x-ucp-event-id, x-ucp-signature, x-ucp-signature-alg: hmac-sha256, x-ucp-timestamp.
Identity scopes
| Scope | Grants |
|---|---|
ucp:checkout_session | Access to checkout session data for the linked customer |
ucp:order_read | Read access to order data for the linked customer |
ucp:customer_read | Read access to customer profile (email, phone, name, customer_code) |
Cross-service dependencies
| Service | Direction | Purpose |
|---|---|---|
| USM/UAS/OFM | Read | Admin auth (session validation, member resolution) |
| OPS | Read | Maintenance mode check |
| SCM | Write | Order creation on checkout/complete (via internal-invoke) |
| SCM | Read (EventBridge) | Subscribe to scm-events bus for order lifecycle webhooks |
| OFM | Read (GSI2) | orgcode → org_guid resolution for capability profile |
| CRM | Read (DDB) | Customer lookup for identity linking |
Events emitted
UCP emits events to the ucp-events EventBridge bus:
| Event | Trigger |
|---|---|
platform-registered | New platform created |
platform-secret-rotated | Client secret rotated |
platform-revoked | Platform revoked |
checkout-session-created | New checkout session |
checkout-session-updated | Cart/buyer updated |
checkout-session-completed | SCM order created |
checkout-session-canceled | Session canceled |
webhook-config-updated | Webhook configuration changed |
webhook-fanout-completed | Webhook delivery batch finished |
identity-code-issued | Authorization code created |
identity-linked | Token exchange completed (identity linked) |
identity-token-revoked | Access/refresh token revoked |
identity-link-revoked | Identity link revoked by admin |
Performance posture
- Checkout CRUD: p95 < 500ms (Tier B).
- Checkout complete (includes SCM call): p95 < 2s (Tier C).
- Profile/discovery: p95 < 200ms (Tier A, cached 5 min / 1 hour).
- Identity authorize/token: p95 < 500ms (Tier C).
- Identity userinfo: p95 < 300ms (Tier B).
- Webhook delivery: 6-second timeout per attempt.
Failure posture
- Checkout complete failure: session reverts to
ready_for_completewith error_message; platform can retry. - Webhook delivery failure: exponential backoff retry (30s → 900s, 5 attempts); auto-pause after 10 consecutive failures.
- Identity code expiry: 10-minute TTL; platform must request a new code from the admin.
- Access token expiry: 1-hour TTL; use refresh token to obtain a new access token.
- Refresh token expiry: 30-day TTL; admin must re-authorize (new code flow).
- Auth code replay: codes are single-use; replaying a consumed code returns an error.
- PKCE mismatch: wrong
code_verifieris rejected; a new code must be issued.
Stubs (future)
- Payment handlers — the capability profile declares payment_methods as an empty array and payment_status is always
none. Payment processing will be added when a PSP integration is defined.