<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Almin Zolotic</title>
    <description>The latest articles on Forem by Almin Zolotic (@zologic).</description>
    <link>https://forem.com/zologic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3790384%2Fc55f6bcf-6195-4a20-a695-27480157be6e.jpg</url>
      <title>Forem: Almin Zolotic</title>
      <link>https://forem.com/zologic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/zologic"/>
    <language>en</language>
    <item>
      <title>30 Days of AI Agents Buying From a Real WooCommerce Store. Here's What the Data Says.</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Tue, 26 May 2026 15:32:55 +0000</pubDate>
      <link>https://forem.com/zologic/30-days-of-ai-agents-buying-from-a-real-woocommerce-store-heres-what-the-data-says-ma0</link>
      <guid>https://forem.com/zologic/30-days-of-ai-agents-buying-from-a-real-woocommerce-store-heres-what-the-data-says-ma0</guid>
      <description>&lt;p&gt;Last week &lt;a class="mentioned-user" href="https://dev.to/benjifisher"&gt;@benjifisher&lt;/a&gt; published a sharp piece on agentic commerce's messy middle — the trust, verification, and liability layer between "found it" and "bought it." His conclusion: the middle is mostly unbuilt.&lt;/p&gt;

&lt;p&gt;We have 30 days of production data that says otherwise. Not a demo. Not a sandbox. A live Dutch perfume store with 40,000 SKUs, real pricing, real tax, real wallet debits. Here is what actually happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;€1,269&lt;/strong&gt; in AI-driven revenue — last 30 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;39 completed orders&lt;/strong&gt; via AI agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;€32.54&lt;/strong&gt; average order value per AI transaction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;76.5% session conversion&lt;/strong&gt; — 39 of 51 agent sessions resulted in a completed order&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.5 average calls per session&lt;/strong&gt; — the spec benchmark is 4 (list → create → update → complete)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last number is the one I want to focus on.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.5 calls per session means agents are skipping steps
&lt;/h2&gt;

&lt;p&gt;The UCP spec optimised benchmark is 4 tool calls for a complete purchase: list products, create checkout, update checkout, complete checkout. Our agents are averaging 1.5. &lt;/p&gt;

&lt;p&gt;That is not agents failing — it is agents that have already done discovery in a prior session arriving with intent and going straight to checkout. The &lt;code&gt;/agents.md&lt;/code&gt; instruction layer we shipped two weeks ago is working: agents are reading the operating manual on first visit and not re-reading it on every subsequent transaction.&lt;/p&gt;

&lt;p&gt;The messy middle does not look messy when the protocol is clean and the instructions are explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is actually buying
&lt;/h2&gt;

&lt;p&gt;Eight distinct agents hit the store in 30 days. Here is what the agent table shows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Sessions&lt;/th&gt;
&lt;th&gt;Avg Calls&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UCP Directory Verifier&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Discovery only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unknown Agent&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;2.2&lt;/td&gt;
&lt;td&gt;Transacting efficiently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UCP Checker&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1.4&lt;/td&gt;
&lt;td&gt;Validation + light transacting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UCPReady MCP&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1.2&lt;/td&gt;
&lt;td&gt;Internal testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UCP Playground&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;+1 above benchmark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Clean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ucptools.dev&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;At target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic Bot&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;At target&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The most interesting row is Unknown Agent — 13 sessions, 2.2 avg calls, at or below target. An agent we cannot identify by name is transacting against the store efficiently and repeatedly. It found the &lt;code&gt;/.well-known/ucp&lt;/code&gt; manifest, parsed the capability declarations, and is completing purchases without any integration work on our side.&lt;/p&gt;

&lt;p&gt;That is the protocol working exactly as designed.&lt;/p&gt;

&lt;p&gt;UCP Playground is the only agent above benchmark at 5 calls — that is Ben's testing environment running full end-to-end validation sessions including the identity linking flow. Expected noise, not a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the messy middle actually looked like
&lt;/h2&gt;

&lt;p&gt;Building to this point was not clean. The first fully autonomous purchase — WooCommerce order #82251 on March 25 — took 24 hours of debugging across two people. The failures were specific:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotency key formatting.&lt;/strong&gt; Claude kept sending &lt;code&gt;meta&lt;/code&gt; as a stringified JSON object instead of a proper nested object. Fixed at the orchestrator level by auto-injecting the key shape.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wallet instrument ID vs handler name.&lt;/strong&gt; The store's validator accepted &lt;code&gt;com.terrawallet.store_credit&lt;/code&gt; (the handler name) but rejected &lt;code&gt;terrawallet-1&lt;/code&gt; (the instrument ID). Two different identifiers, one lookup path, one silent failure mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stale OAuth sessions.&lt;/strong&gt; Merchant-side token revocation was not being detected. Agents were holding expired Bearer tokens and getting 401s with no clear recovery path. Fixed by adding token validation on connect and auto-clearing on 401.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP endpoint override.&lt;/strong&gt; Our Shopify storefront probe was overriding the manifest endpoint. OAuth tokens were stored against &lt;code&gt;/api/mcp&lt;/code&gt; but MCP calls were going to &lt;code&gt;/wp-json/ucpready/v1/mcp&lt;/code&gt;. One endpoint mismatch, zero successful completions until found.&lt;/p&gt;

&lt;p&gt;Each of these was a real failure that blocked real purchases. The protocol did not hide them — the session data captured every one. Observability is what made them fixable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 76.5% conversion means in context
&lt;/h2&gt;

&lt;p&gt;Human checkout conversion on e-commerce averages 2-4%. Mobile is lower. Even high-performing stores rarely exceed 5% on cold traffic.&lt;/p&gt;

&lt;p&gt;76.5% is not comparable to human checkout conversion — agent sessions are intentional by definition, not browsing. But it does tell you something about friction. An agent that reaches &lt;code&gt;create_checkout&lt;/code&gt; on a well-implemented UCP endpoint completes the purchase 76.5% of the time. The failures are mostly discovery sessions (UCP Directory Verifier, UCP Checker) that never intended to purchase.&lt;/p&gt;

&lt;p&gt;Strip out the pure discovery sessions and the completion rate is higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  The small retailer readiness tax — revisited
&lt;/h2&gt;

&lt;p&gt;Paul do Forno at Deloitte posted last week that smaller retailers face a "hidden agentic readiness tax" — perfect catalog data as table stakes, deep system access creating data leakage risk.&lt;/p&gt;

&lt;p&gt;The data above is from a small Dutch retailer. Not a platform. Not an enterprise. A WooCommerce store. The tax is real — it took months of development to get here — but the output is 39 AI-driven orders and €1,269 in revenue in 30 days that would not have existed otherwise.&lt;/p&gt;

&lt;p&gt;The readiness tax is a one-time cost. The revenue is recurring.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The 13 Unknown Agent sessions are the most interesting data point we have right now. An unidentified agent found this store, parsed the protocol, and is transacting repeatedly. We do not know where it came from. That is the network effect of an open protocol — you do not have to be listed anywhere specific. You publish a conformant &lt;code&gt;/.well-known/ucp&lt;/code&gt; manifest and agents find you.&lt;/p&gt;

&lt;p&gt;The next milestone is identifying that agent and understanding its mandate scope. If it is running AP2 autonomous purchasing without an explicit buyer confirmation step, the audit trail is the only thing standing between "it worked" and "it bought the wrong thing." That is the observability layer Ben is right about — not a theoretical need, a live operational requirement.&lt;/p&gt;

&lt;p&gt;The middle is not unbuilt. It is early, it is messy to get right, and it generates real revenue when you do.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;UCPReady is the WooCommerce plugin behind this data. The AI Agent Analytics dashboard is a Pro feature. houseofparfum.nl is the live reference store — the manifest is at houseofparfum.nl/.well-known/ucp.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to see where your WooCommerce store stands: ucpchecker.com&lt;/em&gt;&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Shopify Just Gave AI Agents an Operating Manual. We Built One for WooCommerce.</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Tue, 26 May 2026 15:28:38 +0000</pubDate>
      <link>https://forem.com/zologic/shopify-just-gave-ai-agents-an-operating-manual-we-built-one-for-woocommerce-25m</link>
      <guid>https://forem.com/zologic/shopify-just-gave-ai-agents-an-operating-manual-we-built-one-for-woocommerce-25m</guid>
      <description>&lt;p&gt;When Shopify shipped &lt;code&gt;@shopify/ucp-cli&lt;/code&gt; last week, most of the coverage focused on the obvious part: AI agents can now browse and buy from Shopify stores using the Universal Commerce Protocol.&lt;/p&gt;

&lt;p&gt;What got less attention was the file bundled inside the package — &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That file is not protocol. It's instructions. It tells AI agents &lt;em&gt;how to behave&lt;/em&gt; when shopping on Shopify: start with discovery, sequence cart before checkout, render totals in the order the merchant provides them, treat escalation as a normal lifecycle step not an error. It encodes operational knowledge that the UCP spec alone doesn't cover.&lt;/p&gt;

&lt;p&gt;Shopify proved something important: &lt;strong&gt;protocol + agent instructions is stronger than protocol alone.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We build UCPReady — a WooCommerce plugin that implements the full UCP stack. And until last week, WooCommerce merchants running it had the protocol layer but not the instruction layer. No file telling agents how to work with their store. No guidance surface beyond &lt;code&gt;/.well-known/ucp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We shipped that this week.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap Shopify exposed
&lt;/h2&gt;

&lt;p&gt;UCP standardizes the transport and schema. Every conformant store — Shopify, WooCommerce, BigCommerce, custom — exposes the same protocol surface. That's the point.&lt;/p&gt;

&lt;p&gt;But Benji Fisher at UCP Checker wrote a sharp breakdown of what Shopify's CLI actually does, and one line stuck:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It can buy from any UCP-compliant store on any platform. It can only &lt;em&gt;find&lt;/em&gt; Shopify stores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The discovery layer defaults to &lt;code&gt;catalog.shopify.com&lt;/code&gt;. The transaction layer is pure, open UCP. Shopify owns the index; the protocol is shared.&lt;/p&gt;

&lt;p&gt;That asymmetry matters. But there's a second asymmetry that's just as real: Shopify agents arrive at a store already knowing how to behave. Non-Shopify agents arrive and have to figure it out from the profile alone.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;SKILL.md&lt;/code&gt; bundled in a CLI is one way to solve that. But it only works for agents that installed that specific CLI. The more durable fix is publishing the operating manual on the merchant's own domain — discoverable by any agent, from any platform, the moment it finds the store.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we shipped: the Agent Guidance Layer
&lt;/h2&gt;

&lt;p&gt;UCPReady now auto-generates two public documents on every merchant site:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/agents.md&lt;/code&gt;&lt;/strong&gt; — human and agent readable Markdown. Tells any agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;code&gt;/.well-known/ucp&lt;/code&gt;, use the advertised endpoint, never assume &lt;code&gt;/api/ucp/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;What capabilities this specific merchant supports (cart, checkout, orders, returns, identity linking, embedded checkout)&lt;/li&gt;
&lt;li&gt;How to sequence checkout operations&lt;/li&gt;
&lt;li&gt;What payment handlers are available&lt;/li&gt;
&lt;li&gt;When to stop and escalate to the buyer&lt;/li&gt;
&lt;li&gt;Whether return flows include retention/keep-offer decisions (KeepCard integration)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/llms-full.txt&lt;/code&gt;&lt;/strong&gt; — compact, machine-oriented. Covers protocol version, supported transports (REST, MCP, Embedded), capability inventory, and explicit safe probing guidance.&lt;/p&gt;

&lt;p&gt;Both are generated dynamically from live merchant capabilities. If cart is disabled, the cart section doesn't appear. If KeepCard isn't active, no keep-offer guidance is included. Nothing is hardcoded; nothing claims unsupported behavior.&lt;/p&gt;

&lt;p&gt;Here's what it looks like for a real production store — House of Parfum, currently #1 on ucpchecker.com with a perfect 100/100 score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# House of Parfum

This merchant uses UCPReady and publishes UCP-compatible shopping
endpoints for AI agents.

## Merchant Profile

- **Store:** House of Parfum
- **Description:** Van iconische parfums tot luxe skincare
- **Discovery:** https://houseofparfum.nl/.well-known/ucp
- **Shop:** https://houseofparfum.nl/shop/

## Start Here

- Discover this merchant from https://houseofparfum.nl/.well-known/ucp
- Use the service endpoint advertised in the profile.
- Do not assume /api/ucp/mcp.
- MCP endpoint: https://houseofparfum.nl/wp-json/ucpready/v1/mcp
- REST endpoint: https://houseofparfum.nl/wp-json/ucpready/v1

## Supported Capabilities

- Catalog browsing and product lookup
- Cart creation and update
- Checkout creation, update, and completion
- Order lookup
- Return flows
- Identity linking
- Embedded checkout

## Checkout Guidance

- Create checkout first, then update it with buyer, fulfillment,
  and payment data as needed.
- Read payment handlers from the live checkout response.
- If checkout reaches a completed state, use the final order as
  the source of truth for totals and discounts.
- Treat coupon failures as recoverable checkout issues, not as
  silent success.

## Returns Guidance

- This merchant supports return tooling.
- Return flows may include optional retention / keep-offer decisions
  when enabled by merchant integrations.
- Ask the buyer before accepting or declining any keep-offer outcome.

## Payment Handlers

- dev.ucp.delegate_payment
- com.terrawallet.store_credit

## Escalate to the Buyer When

- variant or quantity selection is ambiguous
- identity linking is required
- coupon validation fails
- the merchant response requires approval or additional buyer action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can hit it live: &lt;a href="https://houseofparfum.nl/agents.md" rel="noopener noreferrer"&gt;houseofparfum.nl/agents.md&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters more than it might look
&lt;/h2&gt;

&lt;p&gt;When Google announced Universal Cart at I/O 2026, the commerce director described UCP as "a common language that lets agents reach businesses securely and seamlessly." Universal Cart, AI Mode checkout, YouTube Shopping — they all run on it.&lt;/p&gt;

&lt;p&gt;The stores that benefit are the ones agents can actually work with reliably. A broken or ambiguous implementation gets abandoned. A store with a valid manifest, correct capability declarations, and clear operating guidance gets completed transactions.&lt;/p&gt;

&lt;p&gt;Shopify's approach is to bundle instructions in a CLI. That works for Shopify's ecosystem. Our approach is to publish instructions on the merchant's own domain, discoverable by any agent from any platform.&lt;/p&gt;

&lt;p&gt;The instruction layer is not optional anymore. It's part of what makes a store agent-ready.&lt;/p&gt;

&lt;p&gt;That's the WooCommerce answer to what Shopify bundled in their CLI — platform-level agent guidance, open and accessible, not locked to a single discovery surface.&lt;/p&gt;

&lt;p&gt;If you're running WooCommerce and want to see where your store stands: &lt;a href="https://ucpchecker.com" rel="noopener noreferrer"&gt;ucpchecker.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UCPReady is at &lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;zologic.nl/ucpready&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>woocommerce</category>
      <category>cli</category>
    </item>
    <item>
      <title>Shopify Just Gave AI Agents an Operating Manual. We Built One for WooCommerce.</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Thu, 21 May 2026 22:45:41 +0000</pubDate>
      <link>https://forem.com/zologic/shopify-just-gave-ai-agents-an-operating-manual-we-built-one-for-woocommerce-1p4p</link>
      <guid>https://forem.com/zologic/shopify-just-gave-ai-agents-an-operating-manual-we-built-one-for-woocommerce-1p4p</guid>
      <description>&lt;p&gt;When Shopify shipped &lt;code&gt;@shopify/ucp-cli&lt;/code&gt; last week, most of the coverage focused on the obvious part: AI agents can now browse and buy from Shopify stores using the Universal Commerce Protocol.&lt;/p&gt;

&lt;p&gt;What got less attention was the file bundled inside the package — &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That file is not protocol. It's instructions. It tells AI agents &lt;em&gt;how to behave&lt;/em&gt; when shopping on Shopify: start with discovery, sequence cart before checkout, render totals in the order the merchant provides them, treat escalation as a normal lifecycle step not an error. It encodes operational knowledge that the UCP spec alone doesn't cover.&lt;/p&gt;

&lt;p&gt;Shopify proved something important: &lt;strong&gt;protocol + agent instructions is stronger than protocol alone.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We build UCPReady — a WooCommerce plugin that implements the full UCP stack. And until last week, WooCommerce merchants running it had the protocol layer but not the instruction layer. No file telling agents how to work with their store. No guidance surface beyond &lt;code&gt;/.well-known/ucp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We shipped that this week.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap Shopify exposed
&lt;/h2&gt;

&lt;p&gt;UCP standardizes the transport and schema. Every conformant store — Shopify, WooCommerce, BigCommerce, custom — exposes the same protocol surface. That's the point.&lt;/p&gt;

&lt;p&gt;But Benji Fisher at UCP Checker wrote a sharp breakdown of what Shopify's CLI actually does, and one line stuck:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It can buy from any UCP-compliant store on any platform. It can only &lt;em&gt;find&lt;/em&gt; Shopify stores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The discovery layer defaults to &lt;code&gt;catalog.shopify.com&lt;/code&gt;. The transaction layer is pure, open UCP. Shopify owns the index; the protocol is shared.&lt;/p&gt;

&lt;p&gt;That asymmetry matters. But there's a second asymmetry that's just as real: Shopify agents arrive at a store already knowing how to behave. Non-Shopify agents arrive and have to figure it out from the profile alone.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;SKILL.md&lt;/code&gt; bundled in a CLI is one way to solve that. But it only works for agents that installed that specific CLI. The more durable fix is publishing the operating manual on the merchant's own domain — discoverable by any agent, from any platform, the moment it finds the store.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we shipped: the Agent Guidance Layer
&lt;/h2&gt;

&lt;p&gt;UCPReady now auto-generates two public documents on every merchant site:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/agents.md&lt;/code&gt;&lt;/strong&gt; — human and agent readable Markdown. Tells any agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;code&gt;/.well-known/ucp&lt;/code&gt;, use the advertised endpoint, never assume &lt;code&gt;/api/ucp/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;What capabilities this specific merchant supports (cart, checkout, orders, returns, identity linking, embedded checkout)&lt;/li&gt;
&lt;li&gt;How to sequence checkout operations&lt;/li&gt;
&lt;li&gt;What payment handlers are available&lt;/li&gt;
&lt;li&gt;When to stop and escalate to the buyer&lt;/li&gt;
&lt;li&gt;Whether return flows include retention/keep-offer decisions (&lt;a href="https://keepcard.io" rel="noopener noreferrer"&gt;KeepCard integration&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/llms-full.txt&lt;/code&gt;&lt;/strong&gt; — compact, machine-oriented. Covers protocol version, supported transports (REST, MCP, Embedded), capability inventory, and explicit safe probing guidance.&lt;/p&gt;

&lt;p&gt;Both are generated dynamically from live merchant capabilities. If cart is disabled, the cart section doesn't appear. If &lt;a href="https://keepcard.io" rel="noopener noreferrer"&gt;KeepCard &lt;/a&gt;isn't active, no keep-offer guidance is included. Nothing is hardcoded; nothing claims unsupported behavior.&lt;/p&gt;

&lt;p&gt;Here's what it looks like for a real production store — House of Parfum, currently #1 on ucpchecker.com with a perfect 100/100 score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# House of Parfum&lt;/span&gt;

This merchant uses UCPReady and publishes UCP-compatible shopping
endpoints for AI agents.

&lt;span class="gu"&gt;## Merchant Profile&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Store:**&lt;/span&gt; House of Parfum
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Description:**&lt;/span&gt; Van iconische parfums tot luxe skincare
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Discovery:**&lt;/span&gt; https://houseofparfum.nl/.well-known/ucp
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Shop:**&lt;/span&gt; https://houseofparfum.nl/shop/

&lt;span class="gu"&gt;## Start Here&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Discover this merchant from https://houseofparfum.nl/.well-known/ucp
&lt;span class="p"&gt;-&lt;/span&gt; Use the service endpoint advertised in the profile.
&lt;span class="p"&gt;-&lt;/span&gt; Do not assume /api/ucp/mcp.
&lt;span class="p"&gt;-&lt;/span&gt; MCP endpoint: https://houseofparfum.nl/wp-json/ucpready/v1/mcp
&lt;span class="p"&gt;-&lt;/span&gt; REST endpoint: https://houseofparfum.nl/wp-json/ucpready/v1

&lt;span class="gu"&gt;## Supported Capabilities&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Catalog browsing and product lookup
&lt;span class="p"&gt;-&lt;/span&gt; Cart creation and update
&lt;span class="p"&gt;-&lt;/span&gt; Checkout creation, update, and completion
&lt;span class="p"&gt;-&lt;/span&gt; Order lookup
&lt;span class="p"&gt;-&lt;/span&gt; Return flows
&lt;span class="p"&gt;-&lt;/span&gt; Identity linking
&lt;span class="p"&gt;-&lt;/span&gt; Embedded checkout

&lt;span class="gu"&gt;## Checkout Guidance&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Create checkout first, then update it with buyer, fulfillment,
  and payment data as needed.
&lt;span class="p"&gt;-&lt;/span&gt; Read payment handlers from the live checkout response.
&lt;span class="p"&gt;-&lt;/span&gt; If checkout reaches a completed state, use the final order as
  the source of truth for totals and discounts.
&lt;span class="p"&gt;-&lt;/span&gt; Treat coupon failures as recoverable checkout issues, not as
  silent success.

&lt;span class="gu"&gt;## Returns Guidance&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; This merchant supports return tooling.
&lt;span class="p"&gt;-&lt;/span&gt; Return flows may include optional retention / keep-offer decisions
  when enabled by merchant integrations.
&lt;span class="p"&gt;-&lt;/span&gt; Ask the buyer before accepting or declining any keep-offer outcome.

&lt;span class="gu"&gt;## Payment Handlers&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; dev.ucp.delegate_payment
&lt;span class="p"&gt;-&lt;/span&gt; com.terrawallet.store_credit

&lt;span class="gu"&gt;## Escalate to the Buyer When&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; variant or quantity selection is ambiguous
&lt;span class="p"&gt;-&lt;/span&gt; identity linking is required
&lt;span class="p"&gt;-&lt;/span&gt; coupon validation fails
&lt;span class="p"&gt;-&lt;/span&gt; the merchant response requires approval or additional buyer action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can hit it live: &lt;a href="https://houseofparfum.nl/agents.md" rel="noopener noreferrer"&gt;houseofparfum.nl/agents.md&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters more than it might look
&lt;/h2&gt;

&lt;p&gt;When Google announced Universal Cart at I/O 2026, the commerce director described UCP as "a common language that lets agents reach businesses securely and seamlessly." Universal Cart, AI Mode checkout, YouTube Shopping — they all run on it.&lt;/p&gt;

&lt;p&gt;The stores that benefit are the ones agents can actually work with reliably. A broken or ambiguous implementation gets abandoned. A store with a valid manifest, correct capability declarations, and clear operating guidance gets completed transactions.&lt;/p&gt;

&lt;p&gt;Shopify's approach is to bundle instructions in a CLI. That works for Shopify's ecosystem. Our approach is to publish instructions on the merchant's own domain, discoverable by any agent from any platform.&lt;/p&gt;

&lt;p&gt;The instruction layer is not optional anymore. It's part of what makes a store agent-ready.&lt;/p&gt;

&lt;p&gt;That's the WooCommerce answer to what Shopify bundled in their CLI — platform-level agent guidance, open and accessible, not locked to a single discovery surface.&lt;/p&gt;

&lt;p&gt;If you're running WooCommerce and want to see where your store stands: &lt;a href="https://ucpchecker.com" rel="noopener noreferrer"&gt;ucpchecker.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UCPReady is at &lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;zologic.nl/ucpready&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>woocommerce</category>
      <category>cli</category>
    </item>
    <item>
      <title>I Replaced a Returns Portal with Five MCP Tools. Here's What Actually Happened.</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Thu, 30 Apr 2026 20:06:06 +0000</pubDate>
      <link>https://forem.com/zologic/i-replaced-a-returns-portal-with-five-mcp-tools-heres-what-actually-happened-43ii</link>
      <guid>https://forem.com/zologic/i-replaced-a-returns-portal-with-five-mcp-tools-heres-what-actually-happened-43ii</guid>
      <description>&lt;p&gt;A live WooCommerce journey where a model searched products, completed a purchase, and handled a return with keep-offer logic — through UCPReady and KeepCard.io on the Universal Commerce Protocol.&lt;/p&gt;

&lt;p&gt;Most "AI commerce" demos are still just chat layered on top of old flows.&lt;/p&gt;

&lt;p&gt;Tonight we did something different.&lt;/p&gt;

&lt;p&gt;We ran a live WooCommerce journey where a model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;searched products&lt;/li&gt;
&lt;li&gt;helped complete a purchase&lt;/li&gt;
&lt;li&gt;and then handled a return with keep-offer logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not on a mock store. Not with human agents behind the curtain. Not with Claude-specific business logic buried in the backend. And not by building "AI features" into the store itself.&lt;/p&gt;

&lt;p&gt;This ran through &lt;strong&gt;UCPReady&lt;/strong&gt; and &lt;strong&gt;KeepCard.io&lt;/strong&gt; — two products I built — using protocol-native rails so the model could interact with the store as an agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  The transcript in one line
&lt;/h2&gt;

&lt;p&gt;This was the actual lifecycle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Customer asked for a face cleanser&lt;/li&gt;
&lt;li&gt;Model searched the live WooCommerce catalog&lt;/li&gt;
&lt;li&gt;Customer bought two products&lt;/li&gt;
&lt;li&gt;Checkout ran through UCPReady&lt;/li&gt;
&lt;li&gt;Payment used wallet rails plus browser authorization&lt;/li&gt;
&lt;li&gt;Order completed&lt;/li&gt;
&lt;li&gt;Customer changed their mind about one item&lt;/li&gt;
&lt;li&gt;KeepCard.io verified the order, surfaced the line items, collected the reason, and presented a keep offer&lt;/li&gt;
&lt;li&gt;Customer accepted the offer&lt;/li&gt;
&lt;li&gt;A real discount code was generated&lt;/li&gt;
&lt;li&gt;A real confirmation email was sent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the entire commerce loop in one conversational journey.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually happened
&lt;/h2&gt;

&lt;p&gt;The session started like a normal shopping flow. The model searched a live WooCommerce store, found products, built a checkout, selected fulfillment, selected payment, and moved through the purchase flow using UCPReady.&lt;/p&gt;

&lt;p&gt;Then, in the same broader system, we tested returns through KeepCard.io.&lt;/p&gt;

&lt;p&gt;The return flow did this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Looked up the order by order number and email&lt;/li&gt;
&lt;li&gt;Checked eligibility&lt;/li&gt;
&lt;li&gt;Collected the return reason&lt;/li&gt;
&lt;li&gt;Evaluated keep-offer logic&lt;/li&gt;
&lt;li&gt;Presented the customer with a keep offer &lt;strong&gt;in chat&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Accepted the offer&lt;/li&gt;
&lt;li&gt;Generated a real discount code&lt;/li&gt;
&lt;li&gt;Sent the confirmation email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We saw the discount code issued. We saw the email arrive. We saw the KeepCard dashboard record the return session as &lt;strong&gt;Kept&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is not "AI-assisted support." That is a real agentic commerce lifecycle.&lt;/p&gt;




&lt;h2&gt;
  
  
  A real example from tonight
&lt;/h2&gt;

&lt;p&gt;The customer started with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to buy something to clean my face&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model searched the live catalog and found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rilastil Aqua Face Cleanser 200ml — €16.95&lt;/li&gt;
&lt;li&gt;Shiseido Men Face Cleanser 125ml — €18.95&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The customer then said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;buy me 2 of Rilastil Aqua Face Cleanser 200ml and 1 Shiseido Men Face Cleanser 125ml&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system created checkout, configured fulfillment and wallet payment, and moved the buyer into the final authorization step.&lt;/p&gt;

&lt;p&gt;After the order completed, the customer came back with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Oh no, I made a mistake — I want to return the item&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The return flow asked for the order number, verified eligibility, and surfaced the exact purchased items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rilastil Aqua Face Cleanser 200ml (Quantity: 2)&lt;/li&gt;
&lt;li&gt;Shiseido Men Face Cleanser 125ml (Quantity: 1)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The customer selected only the Shiseido item. Then gave the reason:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Other — I made a mistake&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of routing to a standard return portal, the system evaluated the return and offered a keep option:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can keep the Shiseido Men Face Cleanser and receive €1.00 off your next order as a discount code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The customer replied:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Accept&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep offer accepted ✓&lt;/li&gt;
&lt;li&gt;Discount code &lt;strong&gt;KEEP-3V9FNM&lt;/strong&gt; generated in WooCommerce ✓&lt;/li&gt;
&lt;li&gt;Confirmation email delivered via KeepCard's email stack ✓&lt;/li&gt;
&lt;li&gt;No return shipment needed ✓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly the kind of post-purchase flow that usually lives inside rigid portals, manual support queues, or custom integrations tied to one model vendor. Tonight it happened conversationally on top of a live WooCommerce stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture: what UCPReady and KeepCard.io actually are
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UCPReady&lt;/strong&gt; is a WooCommerce plugin that implements the &lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;Universal Commerce Protocol (UCP)&lt;/a&gt; — an open protocol for exposing store capabilities through structured, machine-operable interfaces. It turns a WooCommerce store into a UCP-compliant endpoint that AI agents can discover and transact with autonomously.&lt;/p&gt;

&lt;p&gt;The MCP endpoint on houseofparfum.nl exposes these tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;— shopping —
ucp_list_products       ucp_get_product
create_checkout         get_checkout
update_checkout         complete_checkout
cancel_checkout         create_cart
get_cart                update_cart
cancel_cart             convert_cart
ucp_get_order           ucp_list_orders

— returns (KeepCard) —
keepcard_check_return_eligibility
keepcard_select_return_items
keepcard_submit_return_reason
keepcard_accept_keep_offer
keepcard_decline_keep_offer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;KeepCard.io&lt;/strong&gt; is a standalone returns intelligence platform. It connects to WooCommerce via REST API and Shopify via app installation. It owns the decision engine — return eligibility, keep-offer thresholds, fraud signals, monthly caps, discount code generation, and email delivery. None of that logic lives in the LLM.&lt;/p&gt;

&lt;p&gt;The UCPReady companion plugin for KeepCard exposes five MCP tools that let any agent drive the return flow conversationally, while KeepCard handles all the business logic and side effects server-side.&lt;/p&gt;




&lt;h2&gt;
  
  
  The important part: no AI in the business logic
&lt;/h2&gt;

&lt;p&gt;This is the part worth repeating.&lt;/p&gt;

&lt;p&gt;There is no hidden LLM orchestration inside the return engine. There is no model deciding business logic in the backend. There is no "if Claude says X, do Y" architecture.&lt;/p&gt;

&lt;p&gt;The business logic is deterministic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return eligibility&lt;/li&gt;
&lt;li&gt;Order verification&lt;/li&gt;
&lt;li&gt;Keep-offer thresholds&lt;/li&gt;
&lt;li&gt;Duplicate protection&lt;/li&gt;
&lt;li&gt;Policy routing&lt;/li&gt;
&lt;li&gt;Store credit and discount issuance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The model is only the interface layer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That makes the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model-agnostic — Claude, GPT-5, Gemini, Grok all work&lt;/li&gt;
&lt;li&gt;Easier to audit — no prompt-based rules buried in a system prompt&lt;/li&gt;
&lt;li&gt;Easier to harden — business rules are code, not inference&lt;/li&gt;
&lt;li&gt;More future-proof — swap the model, the commerce layer stays the same&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same session ran successfully with both Claude Sonnet 4.5 and GPT-5. Neither needed store-specific prompting. The protocol carries the context.&lt;/p&gt;




&lt;h2&gt;
  
  
  How the return flow chains through UCPReady
&lt;/h2&gt;

&lt;p&gt;The integration works server-to-server. When the agent calls &lt;code&gt;keepcard_check_return_eligibility&lt;/code&gt;, UCPReady makes an HTTP POST to the KeepCard &lt;code&gt;/api/mcp/init&lt;/code&gt; endpoint with the store slug, order ID, and email. KeepCard resolves the order directly against WooCommerce or Shopify using its own stored credentials — UCPReady never touches the order data.&lt;/p&gt;

&lt;p&gt;The full call chain looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent → UCPReady MCP endpoint (WooCommerce)
      → KeepCard /api/mcp/* (cloud service)
      → WooCommerce or Shopify API (order verification)
      → KeepCard decision engine (keep-offer logic)
      → WooCommerce API (discount code creation)
      → KeepCard email stack (confirmation)
      → back through the chain to the agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM sees clean structured responses at each step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keepcard_check_return_eligibility&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eligible"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"needs_item_selection"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer_message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I found order #85774. You have 30 day(s) left to return it. Which item(s) would you like to return?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"order"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"85774"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"days_remaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keepcard_accept_keep_offer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outcome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kept"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discount_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KEEP-3V9FNM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email_sent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer_message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Done! Your discount code is KEEP-3V9FNM — worth 1.00 EUR off your next order. A confirmation has been sent to your email."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;customer_message&lt;/code&gt; field means the agent surfaces KeepCard's language directly — it does not have to infer what to say from raw API data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this is different from what's already out there
&lt;/h2&gt;

&lt;p&gt;Most of what is marketed today as "AI returns" falls into one of these buckets:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;What it actually is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chatbot on a returns portal&lt;/td&gt;
&lt;td&gt;AI layer on top of an existing flow, still ends in a form&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom automation project&lt;/td&gt;
&lt;td&gt;Tied to one model vendor, one store, one integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shopify-first AI returns&lt;/td&gt;
&lt;td&gt;Good tooling, but WooCommerce is a different ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refund infrastructure for devs&lt;/td&gt;
&lt;td&gt;Powerful but requires significant custom work&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Those are real products. But they are still mostly AI applications sitting on top of commerce systems.&lt;/p&gt;

&lt;p&gt;What we are building is different: &lt;strong&gt;the commerce system itself becomes operable by agents.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UCPReady exposes structured commerce capabilities through UCP and MCP. KeepCard.io exposes post-purchase capabilities through the same kind of machine-operable interface. The store does not wait for us to write Claude-specific code, GPT-specific prompts, or Gemini-specific workflows.&lt;/p&gt;

&lt;p&gt;The model is replaceable. The protocol is the product.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why WooCommerce specifically matters
&lt;/h2&gt;

&lt;p&gt;A lot of public examples in this space are Shopify-first. That makes sense — Shopify has a louder app ecosystem and more visible AI tooling.&lt;/p&gt;

&lt;p&gt;But what happened tonight was on WooCommerce.&lt;/p&gt;

&lt;p&gt;WooCommerce powers a large share of the world's online stores. It has almost no public examples of protocol-driven, frontier-model, post-purchase flows. The combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WooCommerce-native&lt;/li&gt;
&lt;li&gt;Protocol-native (UCP)&lt;/li&gt;
&lt;li&gt;Model-agnostic&lt;/li&gt;
&lt;li&gt;Agent-executable&lt;/li&gt;
&lt;li&gt;Post-purchase keep-offer logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...is the category we are helping define. I have not seen a strong public proof of this combination before tonight.&lt;/p&gt;




&lt;h2&gt;
  
  
  What broke (because honesty matters)
&lt;/h2&gt;

&lt;p&gt;Tonight was not a perfect demo, and that is exactly why it was valuable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The keep-offer accept step was occasionally slow.&lt;/strong&gt; The final &lt;code&gt;keepcard_accept_keep_offer&lt;/code&gt; step sometimes exceeded the runner timeout budget. The business action still completed — coupon created, email sent, session marked kept — but the agent runner could report failure because the round trip took too long. This is a bridge latency problem, not a logic problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Duplicate finalization needed hardening.&lt;/strong&gt; When the first accept completed but the runtime retried, we needed the system to treat the retry as a successful terminal state rather than an error. Repeated accept should return: already processed, discount code, final state. That is what resilient agent commerce looks like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Mixed shopping and returns in one session exposed session contamination.&lt;/strong&gt; In one test, we ran search → purchase → return inside a single session. That exposed a session-orchestration issue: return tools were receiving stale search arguments from the earlier shopping flow. Not a KeepCard logic problem. A session-context boundary problem. The kind you only discover once the stack is real enough to chain these experiences together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where we go next
&lt;/h2&gt;

&lt;p&gt;The hardest question has been answered: can a model search, buy, and then resolve a return with keep-offer logic on a live WooCommerce store through protocol-native rails?&lt;/p&gt;

&lt;p&gt;Yes. Tonight, it did.&lt;/p&gt;

&lt;p&gt;The remaining work is hardening, not architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce latency on the post-purchase bridge&lt;/li&gt;
&lt;li&gt;Keep terminal actions idempotent across retries&lt;/li&gt;
&lt;li&gt;Isolate session state between shopping and returns flows&lt;/li&gt;
&lt;li&gt;Test identity linking across multi-session journeys&lt;/li&gt;
&lt;li&gt;Validate the same lifecycle across more stores&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the remaining problems are latency budgets, idempotency, and session context boundaries — you are no longer asking whether the concept works. You are refining a working system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bigger idea
&lt;/h2&gt;

&lt;p&gt;The goal is not "AI can help with returns."&lt;/p&gt;

&lt;p&gt;The goal is: &lt;strong&gt;stores should become operable by agents through standard protocols.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Search is one capability. Checkout is one capability. Payment is one capability. Returns are one capability. Keep-offers are one capability. Once those are exposed properly through open protocol rails, the model becomes interchangeable.&lt;/p&gt;

&lt;p&gt;That is when agentic commerce stops being a gimmick and starts becoming infrastructure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;UCPReady: &lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;zologic.nl/ucpready&lt;/a&gt; — WooCommerce UCP implementation&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;KeepCard.io: &lt;a href="https://keepcard.io" rel="noopener noreferrer"&gt;keepcard.io&lt;/a&gt; — Returns intelligence platform&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Session recording: &lt;a href="https://ucpplayground.com/s/01KQFVJJK6HZF2Z58MVMZQ3WXP" rel="noopener noreferrer"&gt;ucpplayground.com/s/01KQFVJJK6HZF2Z58MVMZQ3WXP&lt;/a&gt;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Universal Commerce Protocol: &lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;ucp.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>woocommerce</category>
      <category>mcp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>60 seconds to see if your webstore supports the latests UCP protocol. Give it a run!</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Thu, 30 Apr 2026 12:03:40 +0000</pubDate>
      <link>https://forem.com/zologic/60-seconds-to-see-if-your-webstore-supports-the-latests-ucp-protocol-give-it-a-run-364j</link>
      <guid>https://forem.com/zologic/60-seconds-to-see-if-your-webstore-supports-the-latests-ucp-protocol-give-it-a-run-364j</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/benjifisher/is-my-store-ucp-ready-how-to-check-in-60-seconds-4fco" class="crayons-story__hidden-navigation-link"&gt;Is My Store UCP Ready? How to Check in 60 Seconds&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/benjifisher" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3787687%2F0c8176d8-b238-43f2-b0af-71689e955123.jpg" alt="benjifisher profile" class="crayons-avatar__image" width="400" height="400"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/benjifisher" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Benji Fisher
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Benji Fisher
                
              
              &lt;div id="story-author-preview-content-3591133" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/benjifisher" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3787687%2F0c8176d8-b238-43f2-b0af-71689e955123.jpg" class="crayons-avatar__image" alt="" width="400" height="400"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Benji Fisher&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/benjifisher/is-my-store-ucp-ready-how-to-check-in-60-seconds-4fco" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 30&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/benjifisher/is-my-store-ucp-ready-how-to-check-in-60-seconds-4fco" id="article-link-3591133"&gt;
          Is My Store UCP Ready? How to Check in 60 Seconds
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ecommerce"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ecommerce&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ucp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ucp&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/benjifisher/is-my-store-ucp-ready-how-to-check-in-60-seconds-4fco" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/benjifisher/is-my-store-ucp-ready-how-to-check-in-60-seconds-4fco#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>The 0.2% flawless rate from your April report is wild. Most stores have a manifest. Almost none actually work end-to-end. It's a conformance problem, not an infrastructure problem — and that's exactly what this score makes visible.
Love what you built here</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Wed, 29 Apr 2026 11:29:46 +0000</pubDate>
      <link>https://forem.com/zologic/the-02-flawless-rate-from-your-april-report-is-wild-most-stores-have-a-manifest-almost-none-4ngi</link>
      <guid>https://forem.com/zologic/the-02-flawless-rate-from-your-april-report-is-wild-most-stores-have-a-manifest-almost-none-4ngi</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/benjifisher/introducing-the-ucp-score-a-0-100-agent-readiness-grade-for-every-ucp-store-1851" class="crayons-story__hidden-navigation-link"&gt;Introducing the UCP Score: A 0–100 Agent-Readiness Grade for Every UCP Store&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/benjifisher" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3787687%2F0c8176d8-b238-43f2-b0af-71689e955123.jpg" alt="benjifisher profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/benjifisher" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Benji Fisher
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Benji Fisher
                
              
              &lt;div id="story-author-preview-content-3585672" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/benjifisher" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3787687%2F0c8176d8-b238-43f2-b0af-71689e955123.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Benji Fisher&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/benjifisher/introducing-the-ucp-score-a-0-100-agent-readiness-grade-for-every-ucp-store-1851" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 29&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/benjifisher/introducing-the-ucp-score-a-0-100-agent-readiness-grade-for-every-ucp-store-1851" id="article-link-3585672"&gt;
          Introducing the UCP Score: A 0–100 Agent-Readiness Grade for Every UCP Store
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ecommerce"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ecommerce&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/product"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;product&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ucp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ucp&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/benjifisher/introducing-the-ucp-score-a-0-100-agent-readiness-grade-for-every-ucp-store-1851" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/benjifisher/introducing-the-ucp-score-a-0-100-agent-readiness-grade-for-every-ucp-store-1851#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>AP2 Mandates Are Live on UCPReady — Here's What That Actually Means for Autonomous Payment</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Fri, 24 Apr 2026 19:42:29 +0000</pubDate>
      <link>https://forem.com/zologic/ap2-mandates-are-live-on-ucpready-heres-what-that-actually-means-for-autonomous-payment-1bba</link>
      <guid>https://forem.com/zologic/ap2-mandates-are-live-on-ucpready-heres-what-that-actually-means-for-autonomous-payment-1bba</guid>
      <description>&lt;p&gt;Zero merchants in &lt;a href="https://dev.to/benjifisher/agentic-commerce-optimization-what-4491-merchants-reveal-about-ucp-readiness-3fk"&gt;Ben Fisher's 4,024-merchant UCP dataset&lt;/a&gt; support native payment. I've been building toward closing that gap since March. Today it's done — at least on the business side.&lt;/p&gt;

&lt;p&gt;This post is about AP2 Mandates: what they are, why they're the only spec-compliant path to autonomous card payment on UCP, and what it took to implement them correctly on WooCommerce.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why every UCP checkout still ends with a browser redirect
&lt;/h2&gt;

&lt;p&gt;When an AI agent completes a UCP checkout today, it gets a &lt;code&gt;continue_url&lt;/code&gt;. The buyer clicks a link, lands on the WooCommerce checkout page, fills in their card, and pays. The agent handled discovery and session setup. The human handled payment.&lt;/p&gt;

&lt;p&gt;That handoff exists because the spec requires it — unless one specific extension is active.&lt;/p&gt;

&lt;p&gt;From the UCP checkout specification:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The checkout has to be finalized manually by the user through a trusted UI &lt;strong&gt;unless the AP2 Mandates extension is supported&lt;/strong&gt;."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That "unless" is the entire autonomous payment story in UCP. Not Stripe tokens. Not saved cards. Not wallet APIs. &lt;strong&gt;AP2 Mandates.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What AP2 Mandates actually are
&lt;/h2&gt;

&lt;p&gt;AP2 is a cryptographic authorization framework. When it's negotiated between a business and a platform, the checkout session is "security locked" — neither party can revert to an unprotected flow.&lt;/p&gt;

&lt;p&gt;The flow has two sides:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business side:&lt;/strong&gt; Every checkout response must include &lt;code&gt;ap2.merchant_authorization&lt;/code&gt; — a JWS detached signature proving the checkout terms (price, line items, totals) are authentic and haven't been tampered with. The signature is ES256, JCS-canonicalized per RFC 8785, with the payload excluded from the JWS body (RFC 7515 Appendix F detached content format).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform side:&lt;/strong&gt; When the user confirms the purchase, the platform generates a cryptographically signed mandate — an SD-JWT credential proving the user explicitly authorized this specific transaction. It submits that mandate at &lt;code&gt;complete_checkout&lt;/code&gt;. The business verifies it. If valid, payment proceeds without a browser redirect.&lt;/p&gt;

&lt;p&gt;The checkout mandate contains the full checkout response including the business's &lt;code&gt;merchant_authorization&lt;/code&gt;. So the platform's signature covers the business's signature. It's a nested cryptographic binding: the business proves the terms, the platform proves the user consented to those exact terms.&lt;/p&gt;




&lt;h2&gt;
  
  
  What implementing this actually required
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Getting the signing right
&lt;/h3&gt;

&lt;p&gt;The spec says ES256 with detached JWS. In PHP, &lt;code&gt;openssl_sign()&lt;/code&gt; on a P-256 key produces a DER-encoded ECDSA signature. JWS ES256 requires raw &lt;code&gt;r||s&lt;/code&gt; — 64 bytes for P-256. Those are not the same format.&lt;/p&gt;

&lt;p&gt;Every JWS library you'd use on the platform side (jose, python-jose, jsonwebtoken) expects raw r||s. A DER signature will fail verification silently or throw a malformed signature error. The fix is a DER-to-raw-rs converter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// openssl_sign() → DER. JWS ES256 → raw r||s. Not the same.&lt;/span&gt;
&lt;span class="nb"&gt;openssl_sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$signing_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$signature_der&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;OPENSSL_ALGO_SHA256&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$der_inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$r_offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$r_len&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$der_inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$s_offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$s_len&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$signature_raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;ltrim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;STR_PAD_LEFT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;str_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;ltrim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x00&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;STR_PAD_LEFT&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JCS canonicalization (RFC 8785) is the other non-obvious requirement. Before signing, the checkout payload is canonicalized — keys sorted recursively, Unicode normalized, numbers in IEEE 754 format. This ensures the signature is reproducible across systems that may re-serialize JSON differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enforcing the mandate at complete_checkout
&lt;/h3&gt;

&lt;p&gt;The spec is explicit: if AP2 was negotiated, &lt;code&gt;complete_checkout&lt;/code&gt; MUST reject requests without &lt;code&gt;ap2.checkout_mandate&lt;/code&gt;. This is the security boundary. Without it, AP2 is advertised but provides no protection — a platform could skip the mandate entirely and the checkout would succeed.&lt;/p&gt;

&lt;p&gt;The enforcement block runs before order creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$ap2_ext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;is_ap2_configured&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$mandate_jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ap2'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'checkout_mandate'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$mandate_jwt&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return mandate_required error — session stays ready_for_complete&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;mandate_error_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'mandate_required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$mandate_error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$ap2_ext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;verify_checkout_mandate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$mandate_jwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$mandate_error&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;mandate_error_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$mandate_error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verifying the mandate
&lt;/h3&gt;

&lt;p&gt;When a mandate is present, the full verification chain runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse the SD-JWT structure (&lt;code&gt;header.payload.signature~disclosures~keybinding&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Check expiry (&lt;code&gt;exp&lt;/code&gt; claim)&lt;/li&gt;
&lt;li&gt;Extract the embedded checkout from mandate claims&lt;/li&gt;
&lt;li&gt;Re-verify &lt;code&gt;merchant_authorization&lt;/code&gt; — confirm the platform wrapped our own signature, not a different checkout&lt;/li&gt;
&lt;li&gt;Verify checkout ID matches the current session&lt;/li&gt;
&lt;li&gt;Verify totals match — no bait-and-switch between what the user saw and what gets charged&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Platform key verification
&lt;/h3&gt;

&lt;p&gt;The final step: verifying the SD-JWT outer signature using the platform's public key. This is what proves the mandate is genuinely from the platform and not forged.&lt;/p&gt;

&lt;p&gt;The flow: decode the JWS header → extract &lt;code&gt;alg&lt;/code&gt; and &lt;code&gt;kid&lt;/code&gt; → fetch the platform's UCP profile from the &lt;code&gt;UCP-Agent&lt;/code&gt; header → pull &lt;code&gt;signing_keys&lt;/code&gt; → find the JWK matching &lt;code&gt;kid&lt;/code&gt; → build an OpenSSL public key from the JWK &lt;code&gt;x&lt;/code&gt;/&lt;code&gt;y&lt;/code&gt; coordinates → verify.&lt;/p&gt;

&lt;p&gt;Building an EC public key from JWK coordinates without a library means constructing the SubjectPublicKeyInfo DER by hand in PHP — OID encoding, SEQUENCE wrapping, BIT STRING for the uncompressed EC point. It's ~80 lines but removes a runtime dependency and works on any WordPress host.&lt;/p&gt;

&lt;p&gt;The platform profile is fetched over HTTPS and cached with WP transients, respecting &lt;code&gt;Cache-Control max-age&lt;/code&gt; with a 60-second floor. Verification result is logged with kid, algorithm, and session ID for auditability.&lt;/p&gt;




&lt;h2&gt;
  
  
  The capability name that broke everything
&lt;/h2&gt;

&lt;p&gt;Before any of this verification mattered, there was a simpler bug: the capability was advertised as &lt;code&gt;dev.ucp.shopping.ap2_mandates&lt;/code&gt; — plural. The spec uses &lt;code&gt;dev.ucp.shopping.ap2_mandate&lt;/code&gt; — singular.&lt;/p&gt;

&lt;p&gt;Capability negotiation is a string equality check. The intersection algorithm finds no match between &lt;code&gt;ap2_mandates&lt;/code&gt; and &lt;code&gt;ap2_mandate&lt;/code&gt;. AP2 is never activated. Every checkout session falls back to delegate payment. No error, no warning — it silently never negotiates.&lt;/p&gt;

&lt;p&gt;One character. Every implementation should validate capability names against the spec registry rather than trusting their own strings.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's live now
&lt;/h2&gt;

&lt;p&gt;When &lt;code&gt;dev.ucp.shopping.ap2_mandate&lt;/code&gt; is enabled in UCPReady and a compatible platform connects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every checkout response includes &lt;code&gt;ap2.merchant_authorization&lt;/code&gt; (JWS ES256, detached, JCS payload)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;complete_checkout&lt;/code&gt; rejects requests without &lt;code&gt;ap2.checkout_mandate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verification runs: SD-JWT parse → expiry → embedded checkout extraction → merchant_authorization re-verification → ID and totals match → platform key verification&lt;/li&gt;
&lt;li&gt;If all checks pass, payment proceeds — no browser redirect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one remaining piece is ecosystem readiness: a platform that supports AP2 mandate submission and forwards the access token that proves identity linking. &lt;a href="https://ucpplayground.com" rel="noopener noreferrer"&gt;Ben Fisher's UCPPlayground&lt;/a&gt; is the logical first test. Once that's connected, UCPReady will produce the first confirmed AP2-mandate-verified autonomous purchase on WooCommerce.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters beyond WooCommerce
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/benjifisher/the-state-of-agentic-commerce-april-2026-l93"&gt;Ben's dataset of 4,024 merchants&lt;/a&gt; shows zero native payment support. Part of that is the SPT/ACS story — Stripe's Shared Payment Token is US-only right now and requires Stripe to host the checkout flow. That's a different architecture than UCP.&lt;/p&gt;

&lt;p&gt;On UCP, AP2 Mandates is the spec's answer. It's protocol-agnostic — the mandate can cover any payment method handled by any PSP. The platform proves user consent cryptographically. The business verifies that proof and charges via their existing payment gateway. No card data crosses protocol boundaries. PSD2 SCA compliance comes from the mandate being platform-issued and buyer-authenticated at mandate creation time.&lt;/p&gt;

&lt;p&gt;This is what autonomous agent commerce looks like when the merchant controls the checkout instead of delegating it to Stripe's infrastructure.&lt;/p&gt;




&lt;p&gt;UCPReady is available at &lt;strong&gt;&lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;zologic.nl/ucpready&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're building a platform that supports UCP and want to test AP2 mandate submission against a live endpoint, reach out. houseofparfum.nl is running UCPReady 1.8.23 with AP2 ready to activate.&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>ucp</category>
      <category>agenticcommerce</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How We Took a New SaaS From Search Confusion to a Clean Google Entity Before Launch</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Thu, 23 Apr 2026 16:06:30 +0000</pubDate>
      <link>https://forem.com/zologic/how-we-took-a-new-saas-from-search-confusion-to-a-clean-google-entity-before-launch-2o6e</link>
      <guid>https://forem.com/zologic/how-we-took-a-new-saas-from-search-confusion-to-a-clean-google-entity-before-launch-2o6e</guid>
      <description>&lt;p&gt;We’re launching &lt;strong&gt;KeepCard&lt;/strong&gt; on Product Hunt tomorrow.&lt;/p&gt;

&lt;p&gt;Before launch, we ran into a problem that a lot of early-stage products probably hit and don’t notice right away:&lt;/p&gt;

&lt;p&gt;Google was getting confused about &lt;strong&gt;what KeepCard actually is&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of understanding KeepCard as a B2B ecommerce product, it was blending our brand with unrelated products that had a similar name. The page itself was fine to a human, but search engines need more than “looks good” to understand a brand entity correctly.&lt;/p&gt;

&lt;p&gt;So we spent time fixing the foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What KeepCard is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;KeepCard&lt;/strong&gt; is a pre-return recovery platform for Shopify and WooCommerce merchants.&lt;/p&gt;

&lt;p&gt;It sits in front of the normal return flow. A customer scans a QR card, verifies the order, selects a reason, and preference-based returns can receive a controlled keep offer before reverse logistics starts.&lt;/p&gt;

&lt;p&gt;That’s very different from a generic “card app” or consumer wallet product.&lt;/p&gt;

&lt;p&gt;And that difference needs to be obvious everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real SEO problem wasn’t rankings first. It was identity.
&lt;/h2&gt;

&lt;p&gt;A lot of launch-stage SEO advice focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;titles&lt;/li&gt;
&lt;li&gt;meta descriptions&lt;/li&gt;
&lt;li&gt;page speed&lt;/li&gt;
&lt;li&gt;keyword placement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those matter, but our first issue was more basic:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google wasn’t fully confident about the entity behind the name.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your brand name overlaps with existing apps, products, or companies, then good markup alone may not be enough. Search engines look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page titles and descriptions&lt;/li&gt;
&lt;li&gt;structured data&lt;/li&gt;
&lt;li&gt;crawlable supporting pages&lt;/li&gt;
&lt;li&gt;social cards&lt;/li&gt;
&lt;li&gt;external mentions&lt;/li&gt;
&lt;li&gt;linked profiles&lt;/li&gt;
&lt;li&gt;consistency of naming across the web&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we approached this like an entity cleanup project, not just an on-page SEO task.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we changed
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. We made the homepage name more explicit
&lt;/h3&gt;

&lt;p&gt;Instead of only saying &lt;code&gt;KeepCard&lt;/code&gt;, we started using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KeepCard for Shopify and WooCommerce&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That sounds small, but it gives search engines a much stronger disambiguation signal.&lt;/p&gt;

&lt;p&gt;We updated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title tags&lt;/li&gt;
&lt;li&gt;Open Graph tags&lt;/li&gt;
&lt;li&gt;Twitter cards&lt;/li&gt;
&lt;li&gt;meta descriptions&lt;/li&gt;
&lt;li&gt;application naming&lt;/li&gt;
&lt;li&gt;structured data labels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was simple: every important machine-readable surface should say the same thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. We strengthened structured data
&lt;/h3&gt;

&lt;p&gt;We expanded the homepage schema to describe KeepCard as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;code&gt;Organization&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;WebSite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;SoftwareApplication&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Service&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we added supporting context like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;alternate names&lt;/li&gt;
&lt;li&gt;audience&lt;/li&gt;
&lt;li&gt;publisher&lt;/li&gt;
&lt;li&gt;brand relationship&lt;/li&gt;
&lt;li&gt;service type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point wasn’t “more schema because schema is good.”&lt;/p&gt;

&lt;p&gt;The point was to help Google understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who we are&lt;/li&gt;
&lt;li&gt;what we offer&lt;/li&gt;
&lt;li&gt;who it is for&lt;/li&gt;
&lt;li&gt;what category we belong to&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. We de-indexed the wrong surfaces
&lt;/h2&gt;

&lt;p&gt;Our merchant app lives on a separate subdomain.&lt;/p&gt;

&lt;p&gt;That app is useful to users, but not useful as a landing surface for search engines. In fact, it can create confusion if it exposes thin or generic titles.&lt;/p&gt;

&lt;p&gt;So we added &lt;code&gt;noindex&lt;/code&gt; signals there and kept the public marketing site as the canonical search target.&lt;/p&gt;

&lt;p&gt;This is underrated:&lt;/p&gt;

&lt;p&gt;Sometimes SEO improves not by publishing more pages, but by making sure crawlers ignore the wrong ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. We improved technical quality because trust compounds
&lt;/h2&gt;

&lt;p&gt;We also cleaned up the technical side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fixed render-blocking font issues&lt;/li&gt;
&lt;li&gt;reduced layout shift&lt;/li&gt;
&lt;li&gt;improved heading structure&lt;/li&gt;
&lt;li&gt;added proper landmarks&lt;/li&gt;
&lt;li&gt;cleaned up CSP problems&lt;/li&gt;
&lt;li&gt;improved performance on mobile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We ended up with a clean Lighthouse result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100 Performance&lt;/li&gt;
&lt;li&gt;100 Accessibility&lt;/li&gt;
&lt;li&gt;100 Best Practices&lt;/li&gt;
&lt;li&gt;100 SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That score alone doesn’t guarantee rankings.&lt;/p&gt;

&lt;p&gt;But it removes a lot of unnecessary ambiguity and friction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m posting this before Product Hunt
&lt;/h2&gt;

&lt;p&gt;Because launch traffic is noisy.&lt;/p&gt;

&lt;p&gt;If people mention your brand tomorrow across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product Hunt&lt;/li&gt;
&lt;li&gt;X&lt;/li&gt;
&lt;li&gt;DEV&lt;/li&gt;
&lt;li&gt;LinkedIn&lt;/li&gt;
&lt;li&gt;indie communities&lt;/li&gt;
&lt;li&gt;blog roundups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you want those mentions reinforcing one clear identity.&lt;/p&gt;

&lt;p&gt;Not scattering weak, inconsistent versions of your brand across the web.&lt;/p&gt;

&lt;p&gt;That means the best time to fix entity confusion is &lt;strong&gt;before&lt;/strong&gt; the wave of citations starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we’re doing now to build branded citations and backlinks
&lt;/h2&gt;

&lt;p&gt;The next phase is consistency.&lt;/p&gt;

&lt;p&gt;We want every mention of KeepCard to reinforce the same identity:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KeepCard is a pre-return recovery platform for Shopify and WooCommerce merchants.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So we’re pushing that exact framing across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product Hunt&lt;/li&gt;
&lt;li&gt;DEV&lt;/li&gt;
&lt;li&gt;founder social profiles&lt;/li&gt;
&lt;li&gt;launch posts&lt;/li&gt;
&lt;li&gt;directories&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;li&gt;email signatures&lt;/li&gt;
&lt;li&gt;future guest posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not for keyword stuffing.&lt;/p&gt;

&lt;p&gt;For entity clarity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’d recommend to other founders
&lt;/h2&gt;

&lt;p&gt;If you’re launching a new product, especially with a brand name that could be confused with something else:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Stress-test your name in search
&lt;/h3&gt;

&lt;p&gt;Search your exact brand and see what Google thinks it is.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Make your machine-readable surfaces consistent
&lt;/h3&gt;

&lt;p&gt;Titles, meta descriptions, OG tags, schema, canonicals, and app naming should tell the same story.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Keep crawlers focused
&lt;/h3&gt;

&lt;p&gt;Index the pages that explain your business best. De-index weak or confusing app surfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Use the same one-sentence description everywhere
&lt;/h3&gt;

&lt;p&gt;You need a stable phrase people can repeat when they mention your company.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Treat backlinks as entity confirmation, not just authority
&lt;/h3&gt;

&lt;p&gt;A backlink helps more when the surrounding text clearly says what your company is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The biggest SEO win for a new SaaS is often not “ranking harder.”&lt;/p&gt;

&lt;p&gt;It’s making it easy for Google to stop guessing.&lt;/p&gt;

&lt;p&gt;That’s what we focused on for KeepCard before launch.&lt;/p&gt;

&lt;p&gt;If you’re working on search clarity, launch prep, or technical SEO for an early product, I’d love to compare notes.&lt;/p&gt;

&lt;p&gt;We launch tomorrow on Product Hunt.&lt;/p&gt;

&lt;p&gt;You can see the product here: &lt;a href="https://keepcard.io" rel="noopener noreferrer"&gt;https://keepcard.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>seo</category>
      <category>startup</category>
    </item>
    <item>
      <title>WooCommerce Now Has More UCP capabilities than Shopify. Here's the breakdown.</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Tue, 14 Apr 2026 17:39:29 +0000</pubDate>
      <link>https://forem.com/zologic/woocommerce-now-has-more-ucp-capabilities-than-shopify-heres-the-breakdown-4fe2</link>
      <guid>https://forem.com/zologic/woocommerce-now-has-more-ucp-capabilities-than-shopify-heres-the-breakdown-4fe2</guid>
      <description>&lt;p&gt;UCPChecker just launched store-to-store comparisons. I ran my WooCommerce store against Reebok (Shopify). The results surprised me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucpchecker.com/compare/houseofparfum.nl/vs/reebok.com" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yn1u77x6tozzqec30rd.png" alt="houseofparfum.nl vs reebok.com UCP comparison" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;WooCommerce&lt;/th&gt;
&lt;th&gt;Shopify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transports&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;558ms&lt;/td&gt;
&lt;td&gt;225ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Verified&lt;/td&gt;
&lt;td&gt;Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Shopify is faster. WooCommerce exposes more.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WooCommerce Has That Shopify Doesn't
&lt;/h2&gt;

&lt;p&gt;Six capabilities are unique to the WooCommerce store:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity Linking&lt;/strong&gt; — OAuth 2.0 buyer authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buyer Consent&lt;/strong&gt; — GDPR/CCPA preference handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded Checkout&lt;/strong&gt; — iframe protocol for payment delegation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catalog Search&lt;/strong&gt; — structured product discovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catalog Lookup&lt;/strong&gt; — individual product fetch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Products&lt;/strong&gt; — base product capability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The big one is &lt;strong&gt;Identity Linking&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;When a buyer connects their store account to an AI platform, the agent can access their saved addresses, wallet balance, and (eventually) saved payment methods. This is what enables fully autonomous checkout — the agent doesn't need a credit card if it can use the buyer's stored value.&lt;/p&gt;

&lt;p&gt;Shopify's UCP implementation stops at checkout initiation. The agent can browse, build a cart, and start checkout — but payment requires a browser redirect. The human finishes the transaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;The UCP spec defines the &lt;em&gt;maximum&lt;/em&gt; surface an agent can interact with. Stores declare which capabilities they support. Agents query the manifest and adapt their behavior.&lt;/p&gt;

&lt;p&gt;A store with 5 capabilities gives agents 5 ways to help. A store with 11 capabilities gives agents 11 ways to help. More surface area = more useful agent interactions = more conversions.&lt;/p&gt;

&lt;p&gt;Right now, Shopify owns the UCP install base — &lt;a href="https://ucpchecker.com/directory" rel="noopener noreferrer"&gt;UCPChecker's directory&lt;/a&gt; shows thousands of Shopify stores with manifests, versus a handful of WooCommerce stores. But install base isn't the same as capability depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Latency Trade-off
&lt;/h2&gt;

&lt;p&gt;Shopify: 225ms. WooCommerce: 558ms.&lt;/p&gt;

&lt;p&gt;This is expected. Shopify is a $100B+ platform with global CDN infrastructure. WooCommerce is self-hosted PHP on whatever server the merchant chose.&lt;/p&gt;

&lt;p&gt;558ms for a 40k SKU WooCommerce store is actually solid. And latency matters less than you'd think for agent commerce — agents batch multiple tool calls, so the total session time matters more than individual response times.&lt;/p&gt;

&lt;p&gt;A typical checkout session on either platform takes 5-15 seconds total. Whether each call is 200ms or 500ms doesn't change the user experience much.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Shopify Could Add
&lt;/h2&gt;

&lt;p&gt;The five capabilities Shopify ships are the core: checkout, fulfillment, discount, order management, cart. These cover the happy path for agent shopping.&lt;/p&gt;

&lt;p&gt;To match WooCommerce's depth, Shopify would need to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity linking&lt;/strong&gt; — OAuth flow for buyer authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded checkout&lt;/strong&gt; — ECP protocol for iframe payment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured catalog capabilities&lt;/strong&gt; — search and lookup as declared capabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shopify has the resources to ship these. The question is prioritization. Right now, they've optimized for breadth (every Shopify store has UCP) over depth (limited capability set).&lt;/p&gt;

&lt;h2&gt;
  
  
  What WooCommerce Needs
&lt;/h2&gt;

&lt;p&gt;WooCommerce's advantage is flexibility — you can add any capability the spec supports. The disadvantage is adoption — merchants have to install a plugin and configure it.&lt;/p&gt;

&lt;p&gt;Right now, the WooCommerce UCP ecosystem is small. &lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;UCPReady&lt;/a&gt; is the main option. For WooCommerce to compete on install base, either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;UCPReady adoption grows organically&lt;/li&gt;
&lt;li&gt;Other plugins emerge (competition is healthy)&lt;/li&gt;
&lt;li&gt;WooCommerce core ships native UCP support&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Option 3 is unlikely near-term — WooCommerce core moves slowly and UCP is still early. But options 1 and 2 are happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Shopify made UCP ubiquitous. WooCommerce made it deep.&lt;/p&gt;

&lt;p&gt;If you're a merchant choosing between platforms, the question is: do you want to be in the largest agent-accessible network (Shopify), or do you want the most capable agent integration (WooCommerce)?&lt;/p&gt;

&lt;p&gt;If you're an agent developer, the answer is simpler: build for both. The &lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;UCP spec&lt;/a&gt; is platform-agnostic. The same agent code that shops Shopify can shop WooCommerce — it just gets more capabilities on the latter.&lt;/p&gt;

&lt;p&gt;Run your own comparison: &lt;a href="https://ucpchecker.com/compare" rel="noopener noreferrer"&gt;ucpchecker.com/compare&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building UCP for WooCommerce? I'm &lt;a href="https://dev.to/zologic"&gt;@zologic&lt;/a&gt; — drop a comment or DM.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ecommerce</category>
      <category>shopify</category>
      <category>woocommerce</category>
    </item>
    <item>
      <title>Building the Only UCP Plugin for WooCommerce — Outside the Walled Garden</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Thu, 09 Apr 2026 17:50:45 +0000</pubDate>
      <link>https://forem.com/zologic/building-the-only-ucp-plugin-for-woocommerce-outside-the-walled-garden-4adk</link>
      <guid>https://forem.com/zologic/building-the-only-ucp-plugin-for-woocommerce-outside-the-walled-garden-4adk</guid>
      <description>&lt;p&gt;When protocol compliance conflicts with platform policy, independence stops being a limitation and becomes a feature that enables full execution.&lt;/p&gt;

&lt;p&gt;Two months ago, AI purchasing landed on Shopify, and within hours a WooCommerce store completed a fully autonomous transaction without any human interaction.&lt;/p&gt;

&lt;p&gt;That store was running UCPReady, a plugin that turns WooCommerce into a Universal Commerce Protocol endpoint for AI agents to transact directly.&lt;/p&gt;

&lt;p&gt;Today, UCPReady is the only WooCommerce plugin with full UCP 2026-04-08 compliance, running in production and processing real autonomous orders.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Different
&lt;/h2&gt;

&lt;p&gt;UCPReady is not a partial implementation or a demo layer, but a complete protocol-native system designed for real autonomous commerce flows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full Universal Commerce Protocol 2026-04-08 compliance across all required surfaces and behaviors
&lt;/li&gt;
&lt;li&gt;Support for REST, MCP, and Embedded Checkout transports without fallback compromises
&lt;/li&gt;
&lt;li&gt;Autonomous AI purchasing with no human confirmation step required at checkout
&lt;/li&gt;
&lt;li&gt;Schema Quality rating of A (99) verified through independent validation tools
&lt;/li&gt;
&lt;li&gt;Spec updates shipped within 24 hours from release to production deployment
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is production commerce running on an open protocol rather than a controlled integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It’s Not in the Marketplace
&lt;/h2&gt;

&lt;p&gt;Open protocols sometimes introduce requirements that do not align with existing marketplace rules designed for traditional plugin behavior.&lt;/p&gt;

&lt;p&gt;UCP requires that checkout execution completes fully when invoked, including payment processing, instead of redirecting to manual confirmation flows.&lt;/p&gt;

&lt;p&gt;Marketplace policies, reasonably, enforce strict controls around autonomous payment execution for security and user protection reasons.&lt;/p&gt;

&lt;p&gt;That creates a structural mismatch between protocol requirements and platform rules rather than a simple review outcome.&lt;/p&gt;

&lt;p&gt;The decision becomes whether to adapt the protocol to fit the platform or preserve the protocol and distribute independently.&lt;/p&gt;

&lt;p&gt;UCPReady chose to preserve the protocol as designed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Difference in Approach
&lt;/h2&gt;

&lt;p&gt;WooCommerce is building AI capabilities focused on merchants managing their stores through internal tools and administrative workflows.&lt;/p&gt;

&lt;p&gt;UCPReady focuses on the opposite side of the interaction, where AI agents act on behalf of users to discover and purchase products.&lt;/p&gt;

&lt;p&gt;These approaches are not competing implementations, but they operate at completely different layers of the commerce stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Independence Works Better
&lt;/h2&gt;

&lt;p&gt;Operating outside the marketplace enables faster iteration cycles that match the pace of protocol evolution without external approval delays.&lt;/p&gt;

&lt;p&gt;Full compliance can be maintained without introducing exceptions, fallbacks, or behavior changes that fragment the protocol surface.&lt;/p&gt;

&lt;p&gt;Support becomes direct and immediate, without reliance on layered support systems or delayed release cycles.&lt;/p&gt;

&lt;p&gt;Merchants get a transparent product with clear capabilities instead of features shaped by policy constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-off
&lt;/h2&gt;

&lt;p&gt;You do not get marketplace distribution, automatic updates, or official platform endorsement through the standard channels.&lt;/p&gt;

&lt;p&gt;You do get full protocol compliance, rapid updates, direct support, and a system designed for autonomous AI commerce from the ground up.&lt;/p&gt;

&lt;p&gt;This is a trade between convenience and capability rather than a limitation of the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standards vs Platform Deals
&lt;/h2&gt;

&lt;p&gt;Platform integrations are fast to deploy but inherently limited by agreements, approvals, and ecosystem boundaries.&lt;/p&gt;

&lt;p&gt;Open protocols are slower to standardize but enable interoperability across platforms, agents, and implementations without restriction.&lt;/p&gt;

&lt;p&gt;UCPReady is built on the assumption that standards will outlast individual platform deals.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means
&lt;/h2&gt;

&lt;p&gt;If you want your WooCommerce store to be accessible to AI agents for real autonomous purchasing, this capability exists today.&lt;/p&gt;

&lt;p&gt;It does not require waiting for platform updates, partnerships, or future roadmap features to become available.&lt;/p&gt;

&lt;p&gt;It requires adopting a protocol-first approach that operates outside traditional distribution models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;Some innovations do not fit inside existing systems because those systems were designed for a different generation of use cases.&lt;/p&gt;

&lt;p&gt;Autonomous AI commerce is one of those cases, and open protocols are where that shift is currently happening.&lt;/p&gt;

&lt;p&gt;UCPReady exists outside the marketplace because that is currently the only place it can fully exist without compromise.&lt;/p&gt;




&lt;p&gt;🔗 &lt;a href="https://zologic.nl/ucpready" rel="noopener noreferrer"&gt;Try UCPReady&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💼 &lt;a href="https://www.linkedin.com/in/almin-zolotic/" rel="noopener noreferrer"&gt;Almin Zolotic on LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>php</category>
    </item>
    <item>
      <title>WooCommerce Just Did What Shopify Did — Hours Later, Open Protocol, Full Autonomous Purchase</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Wed, 25 Mar 2026 09:31:08 +0000</pubDate>
      <link>https://forem.com/zologic/woocommerce-just-did-what-shopify-did-hours-later-open-protocol-full-autonomous-purchase-58ef</link>
      <guid>https://forem.com/zologic/woocommerce-just-did-what-shopify-did-hours-later-open-protocol-full-autonomous-purchase-58ef</guid>
      <description>&lt;p&gt;Shopify announced AI-powered purchasing in ChatGPT this morning. Six hours later, a WooCommerce store completed a fully autonomous AI purchase — identity linked, wallet debited, order in processing — using an open protocol anyone can implement.&lt;/p&gt;

&lt;p&gt;No partnership deal. No platform exclusivity. Just a spec, a plugin, and a real order.&lt;/p&gt;




&lt;h2&gt;
  
  
  What happened this morning
&lt;/h2&gt;

&lt;p&gt;At 09:37 AM today, an AI agent (Claude Sonnet 4.5) completed an autonomous purchase on &lt;a href="https://houseofparfum.nl" rel="noopener noreferrer"&gt;houseofparfum.nl&lt;/a&gt;, a 40,000 SKU WooCommerce perfume store.&lt;/p&gt;

&lt;p&gt;Here's the full session replay:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://ucpplayground.com/s/01KMJ26KVH7ZZ78DWMHZ5BRK32" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fucpplayground.com%2Fs%2F01KMJ26KVH7ZZ78DWMHZ5BRK32%2Fog.png" height="420" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://ucpplayground.com/s/01KMJ26KVH7ZZ78DWMHZ5BRK32" rel="noopener noreferrer" class="c-link"&gt;
            UCPPlaygroundhouseofparfum.nl via Claude Sonnet 4.5 - UCPPlayground
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Checkout Reached in 43.6s. Watch the full agent session replay.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fucpplayground.com%2Ffavicon.ico" width="32" height="32"&gt;
          ucpplayground.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;What the agent did, without any human intervention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Searched for a perfume under €30&lt;/li&gt;
&lt;li&gt;Created a checkout session&lt;/li&gt;
&lt;li&gt;Selected the Terrawallet wallet payment instrument (surfaced from the linked identity)&lt;/li&gt;
&lt;li&gt;Selected flat-rate shipping&lt;/li&gt;
&lt;li&gt;Called &lt;code&gt;complete_checkout&lt;/code&gt; with an idempotency key&lt;/li&gt;
&lt;li&gt;The wallet was debited €22.93&lt;/li&gt;
&lt;li&gt;WooCommerce order #82244 was created with status &lt;code&gt;processing&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;8 turns. 79,152 tokens. Schema Quality: A (99).&lt;/p&gt;




&lt;h2&gt;
  
  
  The difference from Shopify
&lt;/h2&gt;

&lt;p&gt;Shopify's ChatGPT integration is impressive. But it's a bilateral deal between two platforms. Shopify stores work in ChatGPT. That's it.&lt;/p&gt;

&lt;p&gt;What happened today uses the &lt;strong&gt;Universal Commerce Protocol (UCP)&lt;/strong&gt; — an open specification that any store, any agent, and any platform can implement independently.&lt;/p&gt;

&lt;p&gt;The same flow that worked in UCPPlayground today will work in any UCP-compliant agent host. Claude, GPT, Gemini, Grok — any model. Any platform that implements the MCP transport binding can discover houseofparfum.nl's capabilities, link buyer identity, and complete a purchase.&lt;/p&gt;

&lt;p&gt;No bilateral agreement required. No platform partnership. Just a spec.&lt;/p&gt;




&lt;h2&gt;
  
  
  What makes this technically interesting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Identity linking&lt;/strong&gt; — the agent authenticated via OAuth 2.0 Authorization Code + PKCE against the store's own OAuth server (RFC 8414, RFC 7591). The bearer token resolved to WooCommerce customer ID 1. Name, email, phone, billing address, shipping address — all pre-populated from the WC account. The agent never asked for any of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autonomous payment&lt;/strong&gt; — Terrawallet store credit was surfaced as a payment instrument because the linked identity had a wallet balance. The agent selected it, called &lt;code&gt;complete_checkout&lt;/code&gt;, and the wallet was debited server-side. No browser redirect. No payment form. No human in the loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UCP protocol compliance&lt;/strong&gt; — every response carried &lt;code&gt;ucp.capabilities&lt;/code&gt; in the correct keyed-object format. The MCP transport binding used bare tool names (&lt;code&gt;complete_checkout&lt;/code&gt;, not &lt;code&gt;ucp_complete_checkout&lt;/code&gt;). The idempotency store prevented duplicate orders on retry. Schema Quality A (99) from UCPChecker.&lt;/p&gt;




&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plugin:&lt;/strong&gt; &lt;a href="https://zologic.nl/product/ucpready-ai-agent-commerce-for-woocommerce/" rel="noopener noreferrer"&gt;UCPReady&lt;/a&gt; (FREE WooCommerce plugin by Zologic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol:&lt;/strong&gt; Universal Commerce Protocol 2026-01-23&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport:&lt;/strong&gt; MCP (Model Context Protocol) JSON-RPC 2.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test platform:&lt;/strong&gt; UCPPlayground by Ben Fisher / UCPChecker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store:&lt;/strong&gt; houseofparfum.nl (live production, 40k+ SKUs, Redis)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UCPReady was validated by Ben Fisher (UCPChecker) as "the most spec-complete non-Shopify UCP implementation tested." It also exposed 4 bugs in the UCPPlayground embedded checkout during interop testing — all fixed the same day.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for WooCommerce merchants
&lt;/h2&gt;

&lt;p&gt;If you run a WooCommerce store today, you are one plugin install away from being discoverable and purchasable by any AI agent that implements UCP.&lt;/p&gt;

&lt;p&gt;Not "AI-assisted checkout." Not "AI product recommendations." Fully autonomous purchase — the agent finds the product, builds the session, collects buyer details from linked identity, selects payment, and completes the order. You get a WooCommerce order in processing status, attributed to the linked customer account, with full order history.&lt;/p&gt;

&lt;p&gt;The same infrastructure that powers Shopify's ChatGPT integration — agentic discovery, session management, identity linking, autonomous payment — is now available to every WooCommerce store via an open protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Ben Fisher is adding multi-item cart flow to UCPPlayground today. The cart capability (&lt;code&gt;dev.ucp.shopping.cart&lt;/code&gt;) is already declared in houseofparfum.nl's &lt;code&gt;/.well-known/ucp&lt;/code&gt; manifest and the tools are live. Once the Playground wires up the cart flow, agents will be able to browse, build multi-item carts, compare products, and convert to checkout — the full pre-purchase exploration flow.&lt;/p&gt;

&lt;p&gt;The UCP Technical Committee nomination window closes April 3. If you're building on UCP or have a perspective on how the protocol should evolve, now is the time to get involved: &lt;a href="https://github.com/Universal-Commerce-Protocol/ucp" rel="noopener noreferrer"&gt;https://github.com/Universal-Commerce-Protocol/ucp&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live store endpoint:&lt;/strong&gt; &lt;code&gt;https://houseofparfum.nl/.well-known/ucp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UCPPlayground:&lt;/strong&gt; &lt;a href="https://ucpplayground.com" rel="noopener noreferrer"&gt;ucpplayground.com&lt;/a&gt; — connect houseofparfum.nl and run your own session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UCPReady:&lt;/strong&gt; &lt;a href="https://zologic.nl/product/ucpready-ai-agent-commerce-for-woocommerce/" rel="noopener noreferrer"&gt;https://zologic.nl/product/ucpready-ai-agent-commerce-for-woocommerce/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UCP Spec:&lt;/strong&gt; &lt;a href="https://ucp.dev/latest/specification" rel="noopener noreferrer"&gt;ucp.dev/latest/specification&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;UCPReady is built by Zologic. The autonomous purchase milestone was achieved in collaboration with Ben Fisher (UCPRails/UCPPlayground/UCPChecker) who has been validating UCP implementations across the ecosystem.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>ai</category>
      <category>mcp</category>
      <category>commerce</category>
    </item>
    <item>
      <title>Why your WooCommerce AI Agent endpoint is slow (and how we fixed it in 30 lines)</title>
      <dc:creator>Almin Zolotic</dc:creator>
      <pubDate>Tue, 24 Mar 2026 16:23:28 +0000</pubDate>
      <link>https://forem.com/zologic/why-your-woocommerce-ai-agent-endpoint-is-slow-and-how-we-fixed-it-in-30-lines-157e</link>
      <guid>https://forem.com/zologic/why-your-woocommerce-ai-agent-endpoint-is-slow-and-how-we-fixed-it-in-30-lines-157e</guid>
      <description>&lt;p&gt;&lt;em&gt;Published by Almin Zolotic — Zologic / UCPReady&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;We spent most of yesterday debugging an 8-second &lt;code&gt;ucp_list_products&lt;/code&gt; response on a live WooCommerce store with 40,000+ SKUs. The fix was 30 lines of PHP. Here's the full investigation — every dead end included — because anyone building on WooCommerce + UCP is going to hit this.&lt;/p&gt;




&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://houseofparfum.nl" rel="noopener noreferrer"&gt;houseofparfum.nl&lt;/a&gt; runs UCPReady — our WooCommerce plugin that implements the Universal Commerce Protocol (UCP) over REST, MCP, and Embedded Checkout. It's been running in production since February, and UCP Playground benchmarks consistently showed &lt;code&gt;ucp_list_products&lt;/code&gt; taking 8,432ms.&lt;/p&gt;

&lt;p&gt;That's not a typo. Eight seconds. On every cold session.&lt;/p&gt;

&lt;p&gt;For context: Shopify's median MCP tool call latency is 146ms. An AI agent making 4-5 tool calls in a session at 8 seconds each is going to hit platform timeouts. Sessions fail. Purchases don't complete.&lt;/p&gt;

&lt;p&gt;We needed to find and fix the root cause.&lt;/p&gt;




&lt;h2&gt;
  
  
  Eliminating suspects
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Suspect 1: The database query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First thing to check — is the WooCommerce product query slow?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s1"&gt;'
$start = microtime(true);
$results = wc_get_products([
    "status" =&amp;gt; "publish",
    "limit" =&amp;gt; 10,
    "paginate" =&amp;gt; true,
]);
echo "Query: " . round((microtime(true) - $start) * 1000) . "ms\n";
echo "Total: " . $results-&amp;gt;total . "\n";
'&lt;/span&gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: &lt;strong&gt;159ms&lt;/strong&gt; for 38,433 products. Fast. Not the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suspect 2: Product transformation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UCPReady transforms WC_Product objects into UCP format on each request. How long does that take for 10 products?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s1"&gt;'
$adapter = UCPReady\Adapters\ProductAdapter::get_instance();
$results = wc_get_products(["status" =&amp;gt; "publish", "limit" =&amp;gt; 10]);
$start = microtime(true);
foreach ($results as $product) {
    $adapter-&amp;gt;to_ucp_list_format($product);
}
echo "Transform: " . round((microtime(true) - $start) * 1000) . "ms\n";
'&lt;/span&gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: &lt;strong&gt;10ms&lt;/strong&gt;. Not the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suspect 3: Redis / object cache&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The store has Redis installed. Checking if it's actually connected to WordPress:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp cache &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;span class="c"&gt;# Redis ✓&lt;/span&gt;

wp &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s1"&gt;'
$found = false;
wp_cache_get("ucp_product_list_82192", "ucpready", false, $found);
echo $found ? "CACHED" : "NOT CACHED";
'&lt;/span&gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;span class="c"&gt;# NOT CACHED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redis is connected but product list cache keys aren't being populated. Separate issue — but not the 8-second culprit either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suspect 4: The taxonomy mapper&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UCPReady maps WooCommerce categories to Google Product Taxonomy IDs. This involves loading a 482KB taxonomy file and building an inverted index. Was it rebuilding on every request?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s1"&gt;'
$start = microtime(true);
$mapper = UCPReady\Taxonomy\TaxonomyMapper::get_instance();
$mapper-&amp;gt;map_category(17, "en_US");
echo round((microtime(true) - $start) * 1000) . "ms\n";
'&lt;/span&gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;span class="c"&gt;# 18ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;18ms cold. Fast. And we fixed the caching here anyway — the built inverted index now persists to Redis with a 6-hour TTL. But still not the 8-second culprit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real test: HTTP vs WP-CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this point we noticed something odd. Every WP-CLI test was fast. The same operations over HTTP were taking 8 seconds. WP-CLI has WordPress already loaded in memory. HTTP requests boot WordPress from scratch on every call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://houseofparfum.nl/wp-json/ucpready/v1/mcp"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ucp_list_products","arguments":{"limit":5}}}'&lt;/span&gt;

&lt;span class="c"&gt;# real 0m8.101s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8 seconds over HTTP. 169ms in WP-CLI. The gap is WordPress boot time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Finding the culprit
&lt;/h2&gt;

&lt;p&gt;The store has 17 active plugins. Something in that list was making every MCP request boot WordPress for 8 seconds. We tested methodically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wp plugin deactivate google-listings-and-ads &lt;span class="nt"&gt;--allow-root&lt;/span&gt;

&lt;span class="nb"&gt;time &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://houseofparfum.nl/wp-json/ucpready/v1/mcp"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ...

&lt;span class="c"&gt;# real 0m0.651s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Google Listings and Ads was adding 7.5 seconds to every single MCP request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not because of the product query. Not because of anything UCP-related. The plugin registers expensive hooks during WordPress initialisation that fire on every request — including REST API requests that have nothing to do with Google Shopping feeds.&lt;/p&gt;

&lt;p&gt;This isn't a UCPReady problem or even a UCP problem. It's a WooCommerce plugin ecosystem problem. Any plugin that does expensive work on &lt;code&gt;init&lt;/code&gt; or similar hooks will slow down every MCP request on every WooCommerce store running it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The fix: Partial Bootstrap Mode
&lt;/h2&gt;

&lt;p&gt;The solution is a must-use plugin that fires before regular plugins load and removes the offenders from the active plugins list for MCP requests only. Everything else on the store — admin, storefront, Google Shopping feed generation — is completely untouched.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="cd"&gt;/**
 * UCPReady MCP Partial Bootstrap
 * Place in /wp-content/mu-plugins/ucpready-mcp-bootstrap.php
 */&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'ABSPATH'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$ucpready_skip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'google-listings-and-ads/google-listings-and-ads.php'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'query-monitor/query-monitor.php'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'ajax-search-for-woocommerce/ajax-search-for-woocommerce.php'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$ucpready_uri&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_SERVER&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'REQUEST_URI'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$ucpready_is_mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$ucpready_uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/ucpready/v1/mcp'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$ucpready_uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rest_route=/ucpready/v1/mcp'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$ucpready_is_mcp&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'option_active_plugins'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$ucpready_skip&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;array_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$ucpready_skip&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire fix. The &lt;code&gt;option_active_plugins&lt;/code&gt; filter with priority 1 fires before any plugin's code runs, so the offending plugins never register their hooks at all.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://houseofparfum.nl/wp-json/ucpready/v1/mcp"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ucp_list_products","arguments":{"limit":5}}}'&lt;/span&gt;

&lt;span class="c"&gt;# real 0m0.272s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we ran a full timing breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"DNS:%{time_namelookup} Connect:%{time_connect} SSL:%{time_appconnect} TTFB:%{time_starttransfer} Total:%{time_total}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; ...

&lt;span class="c"&gt;# DNS:0.001 Connect:0.001 SSL:0.038 TTFB:0.038 Total:0.267&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Server TTFB: 38ms.&lt;/strong&gt; The remaining ~4.5 seconds in Playground benchmarks is geographic network latency from US/UK servers to the Netherlands — not fixable at the server level.&lt;/p&gt;

&lt;p&gt;WooCommerce at 38ms TTFB matches Shopify's performance characteristics. The variable isn't the platform. It's plugin configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means for the WooCommerce + UCP ecosystem
&lt;/h2&gt;

&lt;p&gt;This finding applies to every WooCommerce UCP implementation, not just UCPReady. If you're building on WooCommerce + UCP and &lt;code&gt;ucp_list_products&lt;/code&gt; is slow, run this diagnostic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Baseline with all plugins&lt;/span&gt;
&lt;span class="nb"&gt;time &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://yourstore.com/wp-json/ucpready/v1/mcp"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ucp_list_products","arguments":{"limit":5}}}'&lt;/span&gt;

&lt;span class="c"&gt;# 2. Deactivate plugins one by one and retest&lt;/span&gt;
wp plugin deactivate &amp;lt;plugin-name&amp;gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;
&lt;span class="c"&gt;# retest&lt;/span&gt;
wp plugin activate &amp;lt;plugin-name&amp;gt; &lt;span class="nt"&gt;--allow-root&lt;/span&gt;

&lt;span class="c"&gt;# 3. Once you find the culprit, add it to the mu-plugin skip list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common suspects beyond Google Listings: any plugin that runs expensive &lt;code&gt;init&lt;/code&gt; hooks, external API calls during boot, or complex query modifications that fire on every request.&lt;/p&gt;




&lt;h2&gt;
  
  
  The broader lesson
&lt;/h2&gt;

&lt;p&gt;AI agents make rapid sequential tool calls. A human tolerates a 3-second page load. An agent making 5 tool calls at 3 seconds each blows through platform timeouts and fails the session. Performance that was "acceptable" for human traffic becomes a hard blocker for agent traffic.&lt;/p&gt;

&lt;p&gt;WooCommerce's plugin ecosystem is powerful but it was built for humans, not agents. Every plugin that does expensive boot-time work is a potential agent-killer. The mu-plugin pattern above is the pragmatic fix until the ecosystem catches up.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we're working on next
&lt;/h2&gt;

&lt;p&gt;The mu-plugin currently requires manual installation. We're adding a performance dashboard to UCPReady's admin settings that measures actual MCP response times, identifies problematic plugins automatically, and provides the mu-plugin as a one-click download when response times are above threshold.&lt;/p&gt;

&lt;p&gt;We're also exploring whether it makes sense to report this to the Google Listings and Ads team directly. The fix on their side is a single &lt;code&gt;is_rest_api_request()&lt;/code&gt; guard before registering expensive hooks. One line on their end helps every WooCommerce store, not just UCPReady users.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;UCPReady is a WooCommerce plugin that implements the Universal Commerce Protocol — turning any WooCommerce store into a fully agent-executable commerce endpoint. Live demo: &lt;a href="https://houseofparfum.nl" rel="noopener noreferrer"&gt;houseofparfum.nl&lt;/a&gt; | Plugin: &lt;a href="https://zologic.nl" rel="noopener noreferrer"&gt;zologic.nl&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your WooCommerce store is slow for AI agent traffic, I offer agent readiness audits. Reach out at &lt;a href="mailto:contact@zologic.nl"&gt;contact@zologic.nl&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>php</category>
      <category>ai</category>
      <category>webperf</category>
    </item>
  </channel>
</rss>
