angeo / module-ucp-checkout
UCP checkout for Magento 2 (dev.ucp.shopping.checkout + discount + fulfillment + order with webhooks, spec 2026-08-25). AI agents create, update and cancel real checkout sessions over REST and see live shipping rates; payment is handed off to the store's own checkout page via continue_url. No card d
Package info
github.com/angeo-dev/module-ucp-checkout
Type:magento2-module
pkg:composer/angeo/module-ucp-checkout
Requires
- php: ~8.1.0||~8.2.0||~8.3.0||~8.4.0||~8.5.0
- ext-json: *
- angeo/module-ucp: ^2.2
- magento/framework: >=103.0.6 <104
- magento/module-catalog: >=104.0.6 <105
- magento/module-checkout: >=100.4.6 <101
- magento/module-configurable-product: >=100.4.6 <101
- magento/module-customer: >=103.0.6 <104
- magento/module-directory: >=100.4.6 <101
- magento/module-quote: >=101.2.6 <102
- magento/module-sales: >=103.0.6 <104
- magento/module-store: >=101.1.6 <102
Requires (Dev)
- bitexpert/phpstan-magento: ^0.43
- magento/magento-coding-standard: ^40.0 || ^41.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.5
Suggests
- angeo/module-ucp-catalog: UCP catalog search and lookup — agents find the items they then put in a checkout
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-15 17:40:46 UTC
README
AI agents build the order. The buyer pays on your own checkout.
This module adds the UCP checkout capability (dev.ucp.shopping.checkout,
spec 2026-08-25) with the discount and fulfillment extensions to Magento 2. Any agent that
speaks UCP (the protocol behind Google AI Mode and Gemini checkout) can
create a checkout session over REST, add items,
set the buyer, a coupon code and a shipping address, pick one of your live
shipping rates, and see live totals. When the buyer is ready,
the agent sends them to continue_url: their cart opens on your store with
the address and shipping method already set, and they pay as usual.
No card data, no payment handler, no PCI scope.
How it works
| Operation | Endpoint | What happens |
|---|---|---|
| Create Checkout | POST {endpoint}/checkout-sessions |
New guest quote with the items → 201 |
| Get Checkout | GET {endpoint}/checkout-sessions/{id} |
Current items, totals, status |
| Update Checkout | PUT {endpoint}/checkout-sessions/{id} |
Full replacement: lines, buyer, discount code, shipping |
| Complete Checkout | POST {endpoint}/checkout-sessions/{id}/complete |
requires_escalation + continue_url — never charges |
| Cancel Checkout | POST {endpoint}/checkout-sessions/{id}/cancel |
Session and quote closed |
| Get Order | GET {endpoint}/orders/{order number} |
Order status, shipments, refunds (order capability) |
| continue_url | GET /ucp/checkout/continue/{token} |
Loads the cart in the buyer's browser → /checkout |
{endpoint} is https://your-store/ucp/v1 by default.
Status:
incomplete— something the agent can fix: no email, an unavailable item, a quantity out of stock. Messages say what and where (path).requires_escalation— everything the API can collect is there. The rest (shipping method, payment) happens on your checkout viacontinue_url.completed— the buyer placed the order.order.idandorder.permalink_urlare filled in (an observer oncheckout_submit_all_aftercloses the loop).canceled— cancelled by the agent or expired (default 6 hours).
Shipping (fulfillment extension): one shipping method with one
destination and one group (supports_multi_group: false). The agent writes
the address in fulfillment.methods[0].destinations[0] (postal address
fields; the region may be a code like IL or a name). The response lists your
live Magento rates for that address as groups[0].options, cheapest first,
each with its price. The agent chooses one with groups[0].selected_option_id
and it appears as the fulfillment total. Countries outside Allowed
Countries and unknown option ids come back as recoverable errors with a
path. An Update without fulfillment clears the address and the rate
(full replacement). Pickup is not offered.
Orders (order capability): when the buyer has placed the order, the agent
can read it at GET {endpoint}/orders/{order number}: line status
(processing, partial, fulfilled, removed), shipments with tracking, refunds,
cancellation and totals. Only the platform whose UCP-Agent profile created
the checkout gets the order; others get 404. Use Inbound Signature Mode =
required so the profile is proven by a signature.
Order webhooks: if the platform's own profile declares
capabilities["dev.ucp.shopping.order"][].config.webhook_url, the store
POSTs the full order to it on create, shipment, refund and cancellation.
Each call is signed (RFC 9421 + Content-Digest) with your store key and
carries Webhook-Id and Webhook-Timestamp. A cron job sends every minute
and retries after 1 min, 5 min, 30 min, 2 h and 12 h. Signing needs the
private key in app/etc/env.php, as angeo:ucp:keys:generate prints it:
'ucp' => ['signing_keys' => ['<kid>' => '-----BEGIN PRIVATE KEY-----...']],
ES256, ES384 and Ed25519 keys work. The kid must also be published in the profile.
Item ids: gid://magento/ProductVariant/{id} (as returned by
angeo/module-ucp-catalog),
gid://magento/Product/{id} for simple products, or a plain SKU. Configurable
children are added through their parent, so the order looks the same as one a
shopper built.
Idempotency-Key on create, update, complete and cancel: the same key with
the same body replays the stored response; with a different body you get
409. Keys are kept for 24 hours.
Version negotiation: UCP-Agent: profile="…"; version="…". Versions this
store serves are accepted; others get 422.
Requirements
- Magento Open Source, Mage-OS or Adobe Commerce 2.4.6+ (PHP 8.1 – 8.5)
angeo/module-ucp2.2.0+
Install
composer require angeo/module-ucp-checkout bin/magento module:enable Angeo_UcpCheckout bin/magento setup:upgrade bin/magento cache:flush
Configure
Stores → Configuration → Angeo → UCP
- Capabilities → Checkout: Yes. Optional: Capabilities → Order, Extensions → Discount and Extensions → Fulfillment: Yes.
- Transport → REST Endpoint URL: leave empty (
{baseUrl}/ucp/v1), or enter your own HTTPS URL — the module answers on its path too. - Checkout Sessions: legal links (terms, privacy, refund — sent in every checkout), session lifetime, limits.
- Check the profile:
bin/magento angeo:ucp:validate curl -s https://your-store/.well-known/ucp | jq '.ucp.capabilities | keys'
Exclude /ucp/ from full-page cache (Varnish, LiteSpeed, Cloudflare). The
responses send Cache-Control: no-store.
Try it
curl -s -X POST https://your-store/ucp/v1/checkout-sessions \ -H 'Content-Type: application/json' \ -H 'UCP-Agent: profile="https://agent.example/profile"' \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"line_items":[{"item":{"id":"24-MB02"},"quantity":1}], "buyer":{"email":"jane@example.com"}}' | jq '{id, status, totals, continue_url}'
Conformance
The official UCP conformance suite tests completion with payment too. This module does not do those on purpose (see Not included), so a full run will not be 77/77. Discovery, version negotiation, the create/get/update/cancel lifecycle, idempotency and shipping options are the parts it is built to pass.
Checkout over MCP
Agents that use MCP instead of REST: install
angeo/module-ucp-checkout-mcp.
It adds the same five checkout operations as MCP tools.
Not included (yet)
- Payment through the agent (payment handlers, AP2, card credentials).
- Pickup, multiple destinations or packages per checkout.
- Signed-in customer checkouts over the API (identity linking).
License
MIT. Made by angeo.dev.