Avatar

Gary Constable AKA GhostFrog

Builder of AI Agents, Data Pipelines & Automation Systems

Building a Magento 2 UCP Extension (Docker Dev): The Plan for a Best-in-Class Checkout Experience

2026-01-27

If you’ve ever felt like “checkout is where good shopping experiences go to die,” this project is for you.

We’re going to build a UCP adapter module for Magento 2 — a clean integration layer that exposes a UCP Business Profile and implements the UCP Checkout Capability endpoints, all inside Magento/PHP, using the Docker environment I’ve just set up at:

  • http://magento.test/

This post is the tutorial / roadmap for what we’re going to make, why it matters, and how we’ll do it step-by-step.


What is UCP and why should we care?

UCP (Universal Commerce Protocol) is a standard way for AI shopping agents and clients to talk to commerce systems. Instead of scraping pages or juggling bespoke APIs, a UCP-compatible store can expose a predictable set of endpoints that support:

  • creating a checkout session
  • updating it (address, shipping selection, buyer details)
  • completing checkout (placing the order)
  • cancelling

The key outcome: less friction, fewer bugs, and a better user experience — especially when the “shopper” is an AI agent or an assistant-driven flow.


What we’re building (MVP)

We’ll ship an MVP that’s genuinely useful but not over-scoped.

1) A Business Profile at /.well-known/ucp

This is a JSON document that advertises:

  • what UCP capabilities our store supports
  • where the checkout REST endpoints live
  • version + metadata needed for discovery

Think of it like: “Here’s what my store can do, and here’s where to call it.”

2) Checkout Capability endpoints (implemented in Magento Web API)

We’ll implement the core flows as REST endpoints inside Magento. Internally, they’ll map directly to Magento’s native checkout engine:

  • UCP checkout sessionMagento quote
  • “complete” → place order

This is the heart of the project: we’re turning Magento into a UCP-compatible backend without introducing extra services.


The UX goal: “best shopping experience we can”

This project isn’t “just implement some endpoints.”

We want the flow to feel:

  • fast (no unnecessary calls / recalculations)
  • clear (the response tells the client what’s missing and what’s next)
  • resilient (idempotency, safe retries, consistent session state)
  • accurate (totals always match Magento reality: shipping, tax, discounts)
  • extensible (we can add payments, post-purchase, and order status later)

So our definition of “done” isn’t “it returns 200 OK” — it’s “it produces a checkout flow you can trust.”


Important: local dev is HTTP… but UCP expects HTTPS

My local Docker site is currently:

  • http://magento.test/

That’s fine for building and testing logic, but for UCP compliance and realistic integration testing, we’ll add local TLS very early.

What we’ll do: - Option A (preferred): mkcert + local HTTPS in the Docker reverse proxy - Option B: tunnel (ngrok / Cloudflare tunnel) if we need quick external HTTPS

We’ll do the simplest thing that gets us to real HTTPS requests fast.


Architecture: keep it simple

We’re not building a separate Python gateway.

Everything will live in a Magento module, roughly like this:

Module responsibilities

  • Route /.well-known/ucp → return Business Profile JSON
  • Expose REST endpoints under Magento Web API (e.g. /rest/V1/ucp/...)
  • Maintain a mapping table between UCP session IDs and Magento quote IDs
  • Translate request payloads into Magento quote updates:
  • add/remove items
  • set customer email
  • set shipping address
  • choose shipping method
  • totals recollection
  • Place the order safely and return an order reference

Data model

We’ll likely add a small table like:

  • pm_ucp_checkout_session
  • session_id (UCP session id)
  • quote_id
  • status (active/completed/cancelled/expired)
  • timestamps

No over-engineering — just what we need to avoid “where did this quote come from?” chaos.


The build plan (what we’ll do next)

Step 1 — Create the module skeleton

  • registration.php
  • module.xml
  • etc/di.xml
  • etc/webapi.xml
  • ACL only if we build admin tooling later

Step 2 — Serve /.well-known/ucp

Two ways: - static file in pub/.well-known/ucp (fastest) - or a Magento controller + nginx rewrite (more “Magento-native”)

We’ll probably start static to move fast, then switch to dynamic once the endpoints exist.

Step 3 — Implement checkout session creation

Endpoint: POST /checkout-sessions

Magento behavior: - create a quote - add line items (by SKU) - collect totals - return session payload

Step 4 — Implement update + read

Endpoints: - GET /checkout-sessions/{id} - PUT /checkout-sessions/{id}

Magento behavior: - update email / buyer details - update shipping address - recalc shipping rates + totals - return what’s still missing (e.g. “shipping method not selected”)

Step 5 — Implement complete + cancel

Endpoints: - POST /checkout-sessions/{id}/complete - POST /checkout-sessions/{id}/cancel

Magento behavior: - complete: place order using quote management - cancel: deactivate quote + mark session cancelled

Step 6 — Make it production-grade

This is where “best experience” actually happens: - idempotency keys for safe retries - consistent error shape + clear messages - logging with request correlation IDs - strict validation (bad SKU, out of stock, invalid shipping method) - expiry rules for sessions


MVP acceptance criteria (the “we can ship it” checklist)

When we’re done with phase 1, we should be able to say:

  1. GET /.well-known/ucp returns a valid Business Profile JSON.
  2. You can create a UCP checkout session that creates a Magento quote with items.
  3. You can update session details (email/address) and totals update correctly.
  4. You can complete the session and Magento places an order successfully.
  5. You can cancel a session and the quote is safely invalidated.
  6. Everything works over HTTPS locally (not just HTTP).

Why this is worth doing

Magento checkout is powerful but messy to integrate into “new” shopping experiences.

UCP gives us a clean interface layer that: - lets assistants/agents drive checkout safely - removes fragile, bespoke integration glue - improves reliability and consistency

And because we’re building it as a Magento module, we keep deployment straightforward and avoid extra infrastructure.


Next post

Next up, we’ll do the first real implementation step:

  • Create the Magento 2 module
  • Expose the first endpoint
  • Wire up quote creation + session persistence

If you want to follow along locally, make sure your Docker setup can run Magento cleanly on magento.test, and be ready to add local HTTPS early.


Notes / repo structure (placeholder)

When I publish the code, I’ll include:

  • /app/code/Vendor/Ucp/
  • database schema patch for session mapping
  • example curl requests to test the endpoints
  • a minimal Postman collection

(We’ll keep it lean and focused.)


← Back to Blog