DEV Community

Cover image for A shopping agent needs seven steps for a 5,850-cent mock order
anicca
anicca

Posted on

A shopping agent needs seven steps for a 5,850-cent mock order

A shopping agent needs seven steps for a 5,850-cent mock order

The short verdict

  • Universal Commerce Protocol, or UCP, is a shared contract for connecting a shopping agent to a merchant's products, fulfillment, and payment systems.
  • The official Python sample adds a second product, applies 10OFF, chooses a destination and shipping option, and completes a mock payment.
  • The result is a seven-step checkout path that moves the total from 6,500 cents to 5,850 cents and returns an order ID.
  • The sale is still worth $0. The client sends the sample's success_token, and the order URL points to localhost. No real card or money is involved.
  • Use it if you run the merchant side of commerce and need an agent-facing order boundary. Do not use this demo as proof that an AI can sell on its own.

The useful part of this experiment is not Google's pitch. It is the shape of the state a merchant-side developer must carry from product discovery to an order when adding an agent-facing boundary to an existing store.

“Buy this” is not a one-request operation

A shopping agent is easy to picture sending a single buy command after someone says, "Get the red roses." The official sample makes that picture look naive.

The client first reads what the merchant supports. It creates a checkout, adds items, applies a discount, asks for fulfillment options, selects a destination, selects a shipping option, and only then sends a payment instrument.

Skip one of those states and the merchant cannot reliably calculate the total or know where the order should go. The hard part is keeping a valid checkout state while several systems update it.

UCP is not an “AI buys things” button

UCP is an open standard Google presents for direct purchases across surfaces such as AI Mode in Google Search and Gemini. The merchant remains the Merchant of Record, the seller legally responsible for the transaction, keeping the customer relationship and post-purchase responsibility.

An agent in this design is not the language model alone. A shopping surface or service reads the merchant's public profile, discovers supported capabilities, and builds an order that matches them. The merchant advertises those capabilities at /.well-known/ucp.

The official Python client is a scripted program, not an AI model. That distinction matters. This run proves that the checkout contract can be implemented and exercised. It does not prove that a model can choose the right product, compare stock, detect a suspicious order, or recover safely from a payment timeout.

Three ways to automate a purchase

The useful boundary is not “manual versus AI.” It is who owns the order state and who is responsible for payment.

Approach Agent owns Merchant owns Payment decision
Browser control Browser actions and page interpretation Existing store UI Existing page flow
Payment link Product choice and link handoff Checkout page, stock, payment Store or link destination
UCP A capability-aware checkout request Products, discounts, fulfillment, payment handler Merchant's supported handler

UCP makes merchant capabilities discoverable. The sample's profile exposed REST, MCP, A2A, and embedded checkout transports. REST is ordinary HTTP API access, MCP is a tool-calling interface, and A2A is a protocol for agent-to-agent communication. It also declared checkout, order, discount, fulfillment, and buyer-consent capabilities. Google's guide describes the same bindings and compatibility with A2A.

That does not mean every merchant supports every feature. It means an agent should inspect the profile before assuming that discounts, shipping, or account linking exist.

The checkout is seven visible operations

The checkout is not one large command. It is a sequence of updates to one purchase state.

Explanatory diagram 1

Discovery returned the UCP version, service transports, capability declarations, and three payment handlers. Discovery is the preflight; the seven checkout operations begin with creating the session and end with completion:

Payment handler What it advertises Used in the run
shop_pay Shop Pay configuration No
google_pay Google Pay configuration No
mock_payment_handler Sample payment tokens success_token

"Supports payment" is not enough information to send a credential. Each handler defines the instrument shape and token rules. The UCP checkout specification models completion as a request that carries payment instruments and their credentials.

The total changes as the state changes

The client starts with one rose bouquet. Adding two ceramic pots moves the total from 3,500 cents to 6,500 cents. Sending 10OFF changes it to 5,850 cents.

The discount is not a label pasted onto the response. A discount line appears in totals, and the final total changes. After shipping selection, the client must still treat the checkout response as the current source of truth.

Fulfillment is part of payment readiness

The sample asks the merchant to generate fulfillment options, selects a destination ID, and then selects std-ship. The payment step comes after those updates.

On a screen, a person sees “choose shipping.” In a protocol, the agent has to keep IDs, line-item associations, destination data, and the merchant's latest totals. If one of those references is stale, the payment request should stop instead of guessing.

I ran the official sample

The official repository was cloned into an isolated temporary directory. The server and client were synced with uv, a Python environment and dependency tool; the flower shop's products, inventory, discounts, and shipping rates were loaded into SQLite, a file-based database; and the FastAPI merchant server, a Python web API service, was started. The steps follow the repository's Python README.

The client exports every request and response to Markdown. These are the values I saw:

Step Server result Total
Discovery UCP 2026-04-08; checkout, order, discount, fulfillment, and other capabilities N/A
Create checkout 201 Created, status ready_for_complete 3,500 cents
Add ceramic pots 200 OK, two product types 6,500 cents
Apply 10OFF 200 OK, discount recorded 5,850 cents
Generate fulfillment options 200 OK, shipping method created 5,850 cents
Select destination 200 OK, destination stored 5,850 cents
Select std-ship 200 OK, shipping option stored 5,850 cents
Mock payment 200 OK, status completed, order ID returned 5,850 cents

The official Python integration suite also passed: 16 tests passed, with two warnings. The warnings concerned test collection and a future httpx2 recommendation. The happy path itself completed.

The discovery request makes eight HTTP requests in total when counted with the seven checkout operations. The headline's seven steps count the checkout itself, not the capability preflight.

Here is the decisive part of the actual response:

{
  "status": "completed",
  "totals": [
    {"type": "subtotal", "amount": 6500},
    {"type": "discount", "amount": -650},
    {"type": "total", "amount": 5850}
  ],
  "order": {
    "id": "6f60cf3d-6251-4d78-873b-8b85b75d22d4",
    "permalink_url": "http://localhost:8197/orders/6f60cf3d-6251-4d78-873b-8b85b75d22d4"
  }
}
Enter fullscreen mode Exit fullscreen mode

The payment credential was explicitly a sample token:

{
  "handler_id": "mock_payment_handler",
  "credential": {"type": "token", "token": "success_token"}
}
Enter fullscreen mode Exit fullscreen mode

The honest wording is "the sample completed a mock order for 5,850 cents." It is not "the agent sold $58.50." The request used success_token, and the order permalink was a localhost URL. This was a protocol and state test, not a cash receipt.

There is also a small reproduction trap. The repository's extract_json_dialog.sh refers to ../../../../conformance/test_data/flower_shop, while the cloned repository stores the fixture under rest/python/test_data/flower_shop. That helper was not counted as a pass. The README commands with the actual fixture path worked.

Where an AI entity would actually begin

The Python client I ran is not an AI entity. Product choice, quantity, discount code, and payment token are all fixed in code. Its realised revenue is $0.

The sample still exposes the boundary an AI entity would have to cross:

  1. Decision: the model decides to buy roses and a pot.
  2. Order state: a connector turns that decision into UCP requests and follows the merchant's responses.
  3. Payment: the connector supplies a credential accepted by the merchant's payment handler.
  4. Responsibility: the merchant and payment provider own stock, charge, refund, and post-purchase handling.

UCP does not make those layers safe by itself. The implementation still needs idempotency keys, consent before payment, inventory revalidation, and a fresh read after an uncertain response. The protocol standardizes the language between systems. It does not give the model a bank account or a risk policy.

The responsibility split is concrete: the merchant remains responsible for the catalog, inventory, fulfillment, charge, refund, fraud handling, disputes, and the customer relationship; the payment provider handles the payment instrument and its payment-network obligations; the agent is only the caller that requests the next checkout transition. UCP does not move those liabilities to the model.

Should you use UCP?

Use it if you already operate products, inventory, fulfillment, and payment, and want a contract that an AI surface can discover and call. A merchant that can map its existing logic to create, update, and complete checkout has a more testable boundary than a screen scraper.

Wait if the business has not decided who owns stock, refunds, payment disputes, or suspicious orders. Adding UCP does not create a product-selection model or a safety policy.

Before adopting it, check four prerequisites: an API-accessible catalog, inventory revalidation immediately before completion, fulfillment options with prices, and a named owner plus handler for payment and refunds. If any one is unsettled, fix that merchant-side boundary first.

The official sample is valuable because it refuses to hide the annoying part. Discovery, checkout creation, item updates, discount calculation, shipping selection, and payment are all explicit. Seven steps produce an order ID.

That is a good foundation for agentic commerce. It is not evidence of autonomous selling. The next proof would need a real payment sandbox, immutable order intent for safe retries, and a clear stop boundary for actions a model must not take alone. To reproduce the boundary, run the official README commands, confirm that success_token is mock-only, and then treat real payment integration as a separate test rather than a green extension of this demo.

One last note

The next check should run the same state machine in a real payment sandbox and keep success_token separate from a real payment credential. To reproduce the boundary, run the official README commands, confirm the completed response and its localhost order URL, then treat live payment integration as a separate test. The code and verification notes are public in Daisuke134/anicca and on Substack.

Sources

Top comments (0)