Expresso Store AI

Let AI shopping agents browse your CartThrob store and send buyers straight to your own checkout.

Buy Now

Agentic commerce for Expresso Store 6 on ExpressionEngine 7. Current release: 1.0.0-rc.1 (release candidate) · Add-on slug: es_ai · By tripleNERDscore, LLC

Expresso Store AI lets AI agents shop your Store catalog and lets your own merchant agents help run the store, without handing payment or store control to a third party.

  • Buyer agents can search products, build carts, prepare checkouts and read the orders they placed. They connect over UCP REST, MCP or A2A.
  • Shoppers always pay on your site. When an agent completes a checkout, the shopper gets a secure link to your native Store checkout. Your existing gateways, shipping and tax rules handle the rest.
  • Merchant agents get 25 scoped tools for products, variants, inventory, promotions, orders, fulfillment, refunds and reports. Every tool is covered by policies, approvals, an audit trail and snapshot revert where it applies.
  • Order webhooks send signed, encrypted, retried status, fulfillment and refund updates to the platform that placed the order.
  • Natural-language shopping is optional. It is off by default and supports Anthropic or OpenAI-compatible providers.
  • Licensing works offline. It never contacts a license server, and license status never interrupts checkout.

Contents#

  1. How it works
  2. Requirements
  3. Installation
  4. Web server routing
  5. Configuration walkthrough
  6. Endpoints
  7. Buyer integration guide
  8. Checkout handoff
  9. Orders and webhooks
  10. Merchant agents
  11. Approvals, activity and revert
  12. Control panel reference
  13. Scheduled maintenance and CLI
  14. Optional natural-language shopping
  15. Licensing
  16. Security
  17. Privacy and data retention
  18. Troubleshooting
  19. Limitations and scope
  20. Upgrading and uninstalling
  21. Changelog
  22. Support

How it works#

 Buyer agent ──REST / MCP / A2A──▶  Expresso Store AI  ──native pricing──▶  Store 6
   (platform)                        │  catalog index                       (rolled back,
                                     │  carts & checkouts                    no shadow orders)
                                     │
                                     └─ complete ─▶ secure handoff link ─▶ Shopper pays in
                                                                           your native checkout
                                                                                 │
 Platform webhook ◀── signed order events (outbox) ◀── order linked ◀───────────┘

 Merchant agent ──MCP / A2A──▶ scoped tools ──▶ policy ──▶ auto / approval / deny ──▶ native write + audit
  • Catalog. You choose which channels are exposed. The add-on keeps a public index of visible products, prices and variants, and reconciles it on a schedule.
  • Pricing. Cart and checkout quotes run through Store's own pricing, tax and shipping inside a database transaction that is always rolled back. No persistent shadow orders are created, listed or reported.
  • Payment. Agents never submit payment credentials. Completing a checkout returns a browser handoff link. The shopper finishes and pays in your normal Store checkout.
  • Orders. When a handed-off checkout becomes a native order, the add-on links it to the originating platform. It then delivers signed order events through a durable outbox.
  • Merchant operations. Merchant tools run as a configured EE service member, so native revisions and authorship are real. Each call is checked against client scopes and policy before anything changes.

Normal human checkout is not affected. It creates no agent links and sends no webhooks.

Requirements#

ComponentRequirement
PHP64-bit PHP 8.1 or later (validated on 8.1 and 8.3)
ExpressionEngineEE 7 (validated on 7.5.26)
StoreExpresso Store 6 (validated on 6.0.2)
DatabaseMySQL/MariaDB with InnoDB for native Store and add-on tables (validated on MariaDB 11.4)
PHP extensionsbcmath, sodium, openssl, curl, mbstring, json, pdo_mysql, plus everything EE/Store need
Web serverApache or Nginx (both validated), with HTTPS and TLS 1.3 on a canonical, publicly reachable origin
EEA working EE encryption key and a writable EE file cache
CronAbility to run eecli.php commands on a schedule

Store configuration constraints

  • The Store currency's display decimals must equal the ISO currency exponent. For example, USD needs 2 and JPY needs 0.
  • Each site supports one currency and guest pricing. Member-only offers and per-customer-limited discounts are not exposed to agents.

Coexistence: only one commerce AI dispatcher can own the /.well-known/ucp and agent card paths. If another commerce AI add-on is installed, such as CartThrob AI on a CartThrob site, disable it before you activate this add-on. The installer detects this conflict from registrations alone and does not touch the other add-on.

The installer runs a preflight check and reports any missing capability before it changes anything.

Installation#

Back up first. Back up the site database, the system/user/addons directory and your EE encryption key before you install or update. Encrypted add-on data cannot be recovered without that key.

  1. Verify the download. Check the archive against its published checksum:
    sha256sum -c es_ai-1.0.0-rc.1.zip.sha256
  2. Extract the archive into your site root, keeping the path system/user/addons/es_ai. The archive already contains the prefixed, production-ready dependencies, so don't run Composer inside the add-on.
  3. Install in the control panel: Developer → Add-ons → Expresso Store AI → Install. The installer creates the add-on's 19 tables and registers its native Store hooks.
  4. Add trusted configuration to system/user/config/config.php:
    // Canonical public HTTPS origin, with trailing slash.
    $config['es_ai_public_origin'] = 'https://shop.example/';
    
    // Base path for protocol routes. Must match CP → Runtime settings.
    $config['es_ai_base_path'] = '/ucp';
  5. Route the discovery and protocol paths to EE. See Web server routing.
  6. Configure the add-on by following the configuration walkthrough.

Safe defaults after install: all transports are off, checkout handoff is off and merchant agent writes are paused. Nothing is exposed until you turn it on.

Web server routing#

Send these paths to EE's front controller (index.php):

  • /.well-known/ucp
  • /.well-known/agent-card.json
  • /ucp/*, or your custom base path

These requests must arrive unchanged:

  • Keep the original HTTP method, URI and raw body.
  • Pass through the Authorization, X-API-Key, UCP-Agent, Signature, Signature-Input, Content-Digest, Request-Id and Idempotency-Key headers.
  • Exempt these paths from any HTML, login, caching or "maintenance mode" middleware.
  • Allow request bodies of at least 2 MiB at the proxy. The add-on can then reject oversized requests with a structured JSON error instead of a proxy error page.

Apache

# If PHP runs as CGI/FastCGI, Authorization is otherwise stripped
CGIPassAuth On

RewriteEngine On
RewriteRule ^\.well-known/(ucp|agent-card\.json)$ index.php [L,QSA]
RewriteRule ^ucp(/.*)?$ index.php [L,QSA]

Nginx

location = /.well-known/ucp              { try_files $uri /index.php$is_args$args; }
location = /.well-known/agent-card.json  { try_files $uri /index.php$is_args$args; }
location ^~ /ucp/                        { try_files $uri /index.php$is_args$args; }

client_max_body_size 2m;

Proxies and TLS: the add-on works out HTTPS and the hostname from the configured origin and the actual connection. It does not trust public X-Forwarded-* headers. Terminate TLS 1.3 in a way that EE sees as HTTPS, or keep the proxy on a trusted private hop.

Logs and analytics: handoff links (/ucp/continue/…) and invoice permalinks contain bearer tokens. Remove them from access logs, analytics, error trackers and support exports.

Configuration walkthrough#

All settings live under Add-ons → Expresso Store AI. Work through these steps in order and check the Dashboard after each one.

1. Catalog mapping#

On the Mapping page, choose which channels agents can see. For each channel, set:

  • the assigned Store field
  • the public HTTPS product URL pattern
  • description and media fields
  • visibility
  • the physical or digital flag

Native SKU, price and stock come from Store directly and need no mapping. Then Reindex.

  • Variation, Single-SKU and Text modifiers follow Store's native data.
  • Text modifiers, such as engraving, are completed by the shopper on your site during checkout. Template input: modifiers are not supported. Use real Store Text modifiers instead.
  • Guest-visible native sales apply. Exact stock counts stay hidden unless you enable them.

2. Checkout handoff#

On the Handoff page, set:

  • Checkout URL: your existing Store checkout page, on the same origin.
  • Privacy and Terms links, which are shown to agents and shoppers.
  • Cart behavior: whether the agent cart replaces or merges with the shopper's existing Store cart.
  • Attribution field (optional): an order custom field that records the originating platform.
  • Invoice permalink: a path containing ORDER_HASH. Leave it blank to inherit Store's Order Invoice Path.

Add the notice tag to your native checkout template:

{exp:es_ai:handoff_notice}

Run a test purchase through your checkout, then enable handoff.

3. Order mapping#

On the Orders page, map your Store statuses to shipped, delivered and canceled. Optionally map a status-message field and custom tracking fields. These mappings drive the order events sent to platforms.

Canceling an order only changes its status. It does not refund or restock.

4. Buyer platforms and access#

  • Under Runtime settings, choose a buyer authentication mode:
    • Platform signature or registered key (signature_or_key, default)
    • Registered platform key only (key_only)
  • Under Buyer access, add platform-profile allow and deny lists and set separate rate capacities. Deny always wins.
  • Register API clients for platforms that use keys. Keys look like esai_live_…. Copy a new key immediately. Only a hash is stored, so a lost key can't be shown again.

5. Merchant agents#

  • Under Agents, set a valid EE service member. Merchant writes run as this member, so revisions and authorship are real.
  • Create merchant API clients with the minimum scopes they need, a policy and optional allowed IP ranges.
  • Try tools in the Test console in preview mode first.
  • When you're satisfied, resume agent writes. They start paused.

6. License, transports and health#

  • Paste your license on the License page.
  • Enable the transports you want (REST, MCP, A2A, orders) under Runtime settings.
  • Confirm the Dashboard shows healthy discovery, TLS, cron freshness, payment and shipping methods.
  • Set up the scheduled tasks.

Endpoints#

Paths assume the default base path /ucp.

SurfaceMethod and path
UCP discovery (business profile)GET /.well-known/ucp
A2A Agent CardGET /.well-known/agent-card.json?version=0.3 or ?version=1.0
Catalog searchPOST /ucp/v1/catalog/search
Catalog lookupPOST /ucp/v1/catalog/lookup
Product detailPOST /ucp/v1/catalog/product
Create cartPOST /ucp/v1/carts
Read or update cartGET / PUT /ucp/v1/carts/{id}
Cancel cartPOST /ucp/v1/carts/{id}/cancel
Create checkoutPOST /ucp/v1/checkout-sessions
Read or update checkoutGET / PUT /ucp/v1/checkout-sessions/{id}
Complete checkout (returns handoff)POST /ucp/v1/checkout-sessions/{id}/complete
Cancel checkoutPOST /ucp/v1/checkout-sessions/{id}/cancel
Read owned orderGET /ucp/v1/orders/{id}
Buyer MCPPOST /ucp/mcp
Merchant MCPPOST /ucp/admin/mcp
A2A JSON-RPC (buyer and merchant)POST /ucp/a2a
Shopper handoff (browser)GET /ucp/continue/{token}

Protocol versions

ProtocolSupported versions
UCP2026-08-25
MCP2026-07-28, plus the documented legacy revisions
A2A0.3.0 (default) and 1.0.0, each with its own wire format

All buyer transports share the same services, so a cart created over REST behaves the same over MCP or A2A.

Buyer integration guide#

This section is for platform developers who connect a buyer agent to a store running Expresso Store AI.

Discovery#

Fetch GET /.well-known/ucp to get the business profile: capabilities, endpoints, policies and public signing keys. A2A clients fetch the versioned Agent Card instead.

Authentication#

Every buyer request carries a UCP-Agent header that names your canonical HTTPS platform profile. The store fetches and negotiates against that profile. Then authenticate in one of these ways:

  • RFC 9421 HTTP message signature: the Signature, Signature-Input and Content-Digest headers, covering method, authority, path, query, required headers and a digest of the body. This works in signature_or_key mode.
  • Registered API key: Authorization: Bearer esai_live_… or X-API-Key: esai_live_…. This works in both modes.

esai_test_… keys are rejected on production sites.

Required REST headers#

HeaderWhenFormat
UCP-AgentEvery requestPlatform profile reference
Request-IdEvery requestUUID
Idempotency-KeyEvery mutation (create, update, complete, cancel)UUID
Content-Type: application/jsonRequests with a body—

Query strings are not accepted on commerce endpoints. Reads must not send a body.

Idempotency and retries#

  • Retry with the same Idempotency-Key and identical body. You get the stored result back and nothing runs twice.
  • Use a new key only for a genuinely new operation.
  • If the store reports an operation as still in progress or its outcome as unknown, the reservation stays held so it can't repeat. Wait, then read the resource. Don't resend it under a new key.

Buyer tools (MCP and A2A)#

The buyer MCP server and A2A buyer skills cover the same operations as REST:

ToolPurpose
search_catalogSearch visible products
lookup_catalogLook up products or variants by identifier
get_productFull product and variant detail
create_cart, get_cart, update_cart, cancel_cartCart lifecycle
create_checkout, get_checkout, update_checkout, cancel_checkoutCheckout lifecycle: addresses, fulfillment, totals
complete_checkoutFinalize and receive the shopper handoff link
get_orderRead an order your platform placed

Ownership#

Carts, checkouts and orders belong to the platform profile and client identity that created them. A resource that belongs to someone else, has expired or doesn't exist gets the same "not found" response. This keeps resource IDs from leaking information.

Errors#

Errors are structured JSON with a stable code, for example https_required, invalid_idempotency_key, request_too_large, method_not_allowed, unsupported_media_type or capabilities_incompatible. Rate-limited responses include Retry-After.

Checkout handoff#

  1. The agent builds a cart and checkout and calls complete.
  2. The response contains a short-lived, single-purpose handoff link.
  3. The shopper opens the link. The add-on loads the agent's cart into the shopper's native Store cart, replacing or merging it as you configured, and redirects to your checkout URL.
  4. {exp:es_ai:handoff_notice} shows the shopper a notice that an agent prepared the cart.
  5. The shopper enters payment details and pays through your normal Store gateway.
  6. Store creates the native order. The add-on links it to the platform and queues an order event.

Details

  • Handoff cookies are host-only, Secure, HttpOnly, SameSite=Lax and last 15 minutes. Handoff responses are no-store and no-referrer.
  • Expired or canceled checkouts can't be revived. The shopper sees an accessible expiry page.
  • With Manual authorization, an order can be complete but still unpaid, and events report it as unpaid. A Manual purchase reports as paid.
  • If a gateway callback was missed, reconcile it without charging again. See es_ai:reconcile_payment.

Orders and webhooks#

  • Platforms read their own orders with GET /ucp/v1/orders/{id} or get_order.
  • Status, fulfillment and refund changes become order events. They're stored encrypted in an outbox and delivered to the platform's webhook, signed with your business signing key.
  • Each event keeps a stable identity across retries. Delivery reserves an attempt before sending, so a crash can't cause duplicate sends.
  • Webhook destinations must use public DNS, a trusted certificate and TLS 1.3. Private, metadata or redirecting destinations are refused.
  • The order data sent to platforms includes items, totals, fulfillment and adjustments. It excludes buyer identity, addresses, free-text customization and gateway credentials.

Watch failed-delivery counts on the Dashboard. Don't reset attempt counters. Fix the destination and let the outbox retry.

Merchant agents#

Merchant agents connect to Merchant MCP (POST /ucp/admin/mcp) or A2A with a merchant API key. A platform signature never grants merchant authority. Extended Agent Cards list only the tools a client's scopes allow.

Tools#

ToolScopeWritesDefault
store_summaryreports:read—auto
store_sales_reportreports:read—auto
store_search_productscatalog:read—auto
store_get_productcatalog:read—auto
store_create_productcatalog:write✓auto (created with a non-open status)
store_update_productcatalog:write✓auto
store_set_product_statuscatalog:write✓approval
store_manage_variantscatalog:write✓auto
store_set_pricepricing:write✓auto within threshold, otherwise approval
store_get_inventoryinventory:read—auto
store_list_low_stockinventory:read—auto
store_set_inventoryinventory:write✓auto
store_adjust_inventoryinventory:write✓auto
store_list_ordersorders:read—auto
store_get_orderorders:read—auto
store_update_order_statusorders:write✓auto (approval if it sends customer email)
store_cancel_orderorders:write✓approval
store_add_fulfillmentfulfillment:write✓auto
store_refund_orderrefunds:write✓always approval
store_create_discountdiscounts:write✓approval
store_update_discountdiscounts:write✓approval
store_create_salepricing:write✓always approval
store_update_salepricing:write✓always approval
store_create_coupondiscounts:write✓Alias of store_create_discount
store_update_coupondiscounts:write✓Alias of store_update_discount

Write calls must include either:

  • "dry_run": true, which previews the real native before/after diff and the policy decision without changing anything, or
  • "idempotency_key": "<uuid>", which performs a live write.

Money is always sent in integer minor units, for example price_minor: 1999 for 19.99. Percentages are decimal strings.

All tools return { ok, data, meta, errors }.

Policies#

Each merchant client has a policy (JSON). Policies can narrow site-wide limits but never widen them:

{
  "tools": {
    "store_set_price": "approval",
    "store_adjust_inventory": "auto",
    "store_cancel_order": "deny"
  },
  "allowed_channels": [1, 3],
  "allowed_hours": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
  "price_change_percent": 10,
  "refund_cap_minor": 5000,
  "daily_refund_cap_minor": 20000,
  "max_writes_per_hour": 60
}
KeyMeaning
toolsSets a tool to auto, approval or deny. Read tools accept only auto or deny.
allowed_channelsChannel IDs the client may touch
allowed_hoursHours of the day (0–23, UTC) when the client may act
price_change_percentRegular price changes within this percentage (0–100) run automatically. Larger changes wait for approval.
refund_cap_minorMaximum single refund, in minor units
daily_refund_cap_minorMaximum refunds per day, in minor units
max_writes_per_hourWrite rate limit
signature_requiredtrue requires signed requests as well as the key
profile_urlBinds the client to a signing profile URL

Unknown keys are rejected.

  • Refunds and sales always need approval, whatever the override says.
  • Refund caps use exact minor units and add up across all clients. A client override can't raise them.
  • Status changes that trigger native customer email default to approval, and the preview names the email templates.

The pause switch#

The global pause stops all agent writes, including approvals that are already queued. Human revert stays available while writes are paused.

Approvals, activity and revert#

Approvals. Each pending item shows the client, proposed arguments, before/after diff, the policy rule that triggered it and any email templates involved.

  • Approve runs the operation immediately, after rechecking authorization, limits and fresh native state.
  • If the product, transaction or template changed since the preview, the approval is stale. Ask the agent for a new preview.
  • Reject records your note.
  • Pending approvals expire after 72 hours by default.
  • A2A clients see input-required while an approval is pending, then the final result.
  • To approve refunds, a user also needs CP access to Store's Orders module.

Refunds

  • Partial refunds are verified with Store's Dummy and Manual gateways. Manual only records the adjustment.
  • Other gateways keep Store's native full-refund behavior until they're separately verified.
  • If a refund's outcome is uncertain, check the native transaction in Store before trying again. Never retry a refund that might have run under a new idempotency key.

Activity. Filter the audit log by operation, client, result and transport.

Revert. Eligible product, inventory and promotion writes show Review revert. A revert restores the saved native snapshot only if the current data still matches what the agent left. It warns you about orders placed since the change. Revert can't undo refunds, sent customer emails, order status changes or external shipments.

Control panel reference#

PageWhat it's for
DashboardHealth: Store and currency configuration, discovery, TLS, cron freshness, payment and shipping methods, failed notifications, alerts
MappingCatalog channels and fields; reindex and reconcile
HandoffCheckout URL, legal links, cart behavior, attribution, invoice permalink
OrdersStatus and tracking-field mapping
Buyer accessPlatform allow and deny lists, rate capacities, platform API clients
AgentsMerchant clients, scopes, policies, IP ranges, service member, pause switch
ApprovalsPending agent operations
ActivityAudit log, revert review
Signing keysBusiness signing key rotation with overlap
Test consolePreview or run buyer and merchant tools as a chosen client
Runtime settingsTransports, auth mode, base path, TTLs, retention
LanguageOptional natural-language provider settings
LicenseActivate, check or remove your commercial license

The Test console previews by default. Merchant previews show the real native diff and policy decision, while buyer previews only check the schema. It doesn't test network signatures or IP restrictions.

Scheduled maintenance and CLI#

Run these from the site root with the correct PHP binary and site ID:

ScheduleCommandPurpose
Every minutephp system/ee/eecli.php es_ai:outbox --site=1 --limit=25Reconcile linked orders and deliver due webhooks
Every 5 minutesphp system/ee/eecli.php es_ai:reconcile --site-id=1 --batch-size=100Catalog reconciliation
Dailyphp system/ee/eecli.php es_ai:prune --site=1 --limit=500Bounded retention cleanup
After mapping changesphp system/ee/eecli.php es_ai:reindex --site-id=1 --batch-size=100Full catalog rebuild
As neededphp system/ee/eecli.php es_ai:keys list --site=1Show public business signing keys
As neededphp system/ee/eecli.php es_ai:keys rotate --site=1Rotate signing keys (the old public key stays published during the grace period)
As neededphp system/ee/eecli.php es_ai:reconcile_payment --order=123 --site=1 [--refresh-profile]Recover a missed native payment callback without charging

Example crontab:

* * * * *   cd /var/www/shop && php system/ee/eecli.php es_ai:outbox --site=1 --limit=25
*/5 * * * * cd /var/www/shop && php system/ee/eecli.php es_ai:reconcile --site-id=1 --batch-size=100
15 3 * * *  cd /var/www/shop && php system/ee/eecli.php es_ai:prune --site=1 --limit=500

Notes

  • --order takes the native Store order primary key, not the order number.
  • Prune processes a bounded batch. Run it again to clear a large backlog. It never deletes native Store orders or payments.
  • es_ai:keys rotates webhook and business signing keys only. It has nothing to do with your license.

Optional natural-language shopping#

Off by default. When enabled, signed-in buyer traffic can send plain text, and the add-on turns it into validated buyer actions.

Configure under Language:

  • Provider: Anthropic or any OpenAI-compatible Chat Completions endpoint
  • Model name and API key. The key is stored encrypted.
  • Output and context token budgets, plus a daily spend cap
  • Current input and output prices in USD cents per million tokens. Round up. No model names or prices are built in.
  • A system prompt with your shipping, returns and contact policies

Guardrails

  • Only buyer tools are offered, and complete_checkout is never one of them. Merchant tools are never available.
  • Provider output must pass schema validation and the normal ownership checks. Prompts can't override the tool allowlist.
  • Each call reserves its maximum cost against the daily budget first. Malformed output, timeouts and spent budgets fall back to structured instructions.
  • Raw prompts, provider errors and keys are not logged.

Your responsibilities

  • Shopper text is sent to the provider you chose. Say so in your privacy policy.
  • Spend accounting uses the prices you enter. Set spending limits in your provider account as well if you need a guaranteed billing ceiling.

Licensing#

Expresso Store AI uses offline, Ed25519-signed licenses that cover es_ai only. A CartThrob AI license is separate.

Activate: paste your license key on the License page. The add-on checks:

  • the issuer and signature
  • the product
  • the exact hostname
  • the issue and expiry dates
  • any local revocation list

The key is stored encrypted and never shown again.

What license status affects: a missing, expired, revoked or wrong-host license shows a status in the control panel. It never stops buyer checkout, merchant operations or order events.

Common situations

SituationWhat to do
RenewalActivate the replacement key you receive. It keeps the same license ID with a new expiry.
Moving domainsRequest a replacement key for the new hostname. Until you have it, status shows wrong_host.
Staging siteLicenses can list several exact production and staging hostnames. Ask when you purchase.
Removing a licenseUse Remove on the License page. No commerce data is affected.

No license server is contacted and no telemetry is sent.

Security#

Authentication and ownership

  • Every buyer request is authenticated before anything changes. Ownership is tied to the platform profile plus the client identity.
  • Merchant authority needs a merchant key. Platform signatures can't grant it.
  • API keys are shown once and stored only as peppered hashes. You can restrict merchant keys by IP, using the real peer address.
  • Signatures cover method, authority, path, query, required headers and the body digest. The add-on checks the raw body exactly as received.

Writes

  • Every mutation reserves durable idempotency state before it acts. An interrupted operation stays reserved, so it can never turn into a repeat charge or repeat write.
  • Merchant writes are serialized per resource. Native writes compare fresh snapshots under database locks.
  • Approvals store arguments, diffs and notes encrypted, and recheck everything right before running.

Outbound requests (profile fetches, webhooks, language providers)

  • Requests refuse URLs with embedded credentials, private and metadata addresses, unsafe DNS answers, redirects and proxies.
  • Connections pin the resolved public address and verify the TLS certificate.
  • Size, header and time limits apply to every request.

Money uses exact decimal strings and integer minor units with bcmath, never floats.

Control panel

  • EE's native forms supply CSRF protection.
  • Add-on admin permissions control access to configuration, secrets, approvals and audit records.
  • Secret fields are never shown again, and sensitive pages are sent no-store.

Your checklist

  • ☐ TLS 1.3 on the public origin
  • ☐ Authorization and signature headers reach EE unchanged
  • ☐ Handoff and invoice URLs removed from logs and analytics
  • ☐ EE encryption key backed up securely
  • ☐ Merchant keys use minimum scopes, and IP ranges where possible
  • ☐ Third-party shipping, payment and item extensions tested on staging. A rollback can't undo their external emails or network calls.
  • ☐ Manual refund work in Store's CP coordinated with agents. The native CP doesn't take the add-on's locks.

Privacy and data retention#

What's stored (all scoped to the site):

  • Catalog index: mapped, visible product content, prices and variants.
  • Carts and checkouts: buyer identity, addresses, choices and priced snapshots. Encrypted with the EE key.
  • Order links: native and public order IDs, platform and webhook destination, snapshot hash and sequence. Invoice URLs, event payloads and tracking are encrypted.
  • Merchant audit: snapshots, arguments, diffs and notes. Encrypted, and visible to add-on admins.
  • Secrets: API keys are stored as hashes. Provider keys and license tokens are encrypted settings.
  • Logs: IDs and failure codes only. No secrets, raw prompts or raw gateway errors.

Default retention, configurable in Runtime settings and enforced by es_ai:prune:

DataDefault
Finished private resources and delivered notifications30 days
Buyer audit records90 days
Merchant audit records730 days
Pending approvals72 hours

After the retention period, old linked checkouts are minimized: personal and priced details are removed, but a small encrypted ownership record stays so order reads and order updates keep working. Unresolved payments, uncertain writes and undelivered notifications are kept for manual recovery. Retention is deliberately not a blind deletion deadline.

Your responsibilities: native Store orders follow your own retention policy. You're also responsible for legal disclosures, data-subject requests across providers and backups, and protecting the EE encryption key. Losing that key makes encrypted add-on data unrecoverable.

Troubleshooting#

SymptomLikely cause and fix
/.well-known/ucp returns 404 or HTMLThe path isn't routed to EE, or the transport is disabled. Check routing and Runtime settings.
https_requiredEE doesn't see the request as HTTPS. Fix TLS termination; forwarded headers aren't trusted.
Authentication fails with a valid keyThe Authorization header is being stripped. On Apache CGI/FastCGI, add CGIPassAuth On.
Signature verification failsA proxy changed the body, path or signed headers. Pass the request through unchanged.
invalid_idempotency_key / invalid_requestIdempotency-Key or Request-Id is missing or isn't a UUID, or a query string was sent.
request_too_large (or proxy 413)Raise the proxy body limit to at least 2 MiB so the add-on can respond.
Products missing from searchThe channel isn't mapped, the entry isn't visible or open, or a reindex is needed.
Prices differ from the storefrontThe offer is member-only or per-customer-limited and isn't exposed to agents.
Handoff link says expiredThe link or checkout passed its TTL. The agent should create a new checkout.
Order paid but platform not updatedCron isn't running es_ai:outbox, or a payment callback was missed. Check cron freshness, then run es_ai:reconcile_payment.
Webhooks failingThe destination isn't public, uses an untrusted certificate, lacks TLS 1.3 or redirects. Fix it and let retries continue.
Merchant writes do nothingWrites are paused, or the service member isn't set. Check the Agents page.
Approval marked staleNative data changed after the preview. Ask the agent for a new dry run.
Install blocked by a dispatcher conflictAnother commerce AI add-on owns the discovery paths. Disable it first.
License shows wrong_hostThe hostname doesn't exactly match the license. Request a replacement key.

Limitations and scope#

This is a release candidate. Not included in v1:

  • Agent-completed payment or payment-capture tools. Shoppers always pay in the browser.
  • Identity or account linking
  • Multiple currencies, or member-specific pricing
  • Server-Sent Events (SSE) and A2A push notifications

Verification status

  • Validated locally on PHP 8.1 and 8.3 with Apache and Nginx, with independent UCP SDK, MCP Inspector and official A2A SDK clients.
  • Deployed third-party platform acceptance is not yet verified. Confirm with a specific platform before claiming support for it.
  • The official UCP conformance suite hasn't run successfully against this build. Independent SDK checks are separate evidence.
  • Partial refunds are verified only for the Dummy and Manual gateways.
  • Language-provider adapters are contract-tested but haven't been tested live against a merchant's own account.
  • Accessibility has automated WCAG 2.2 AA checks on covered CP views. No manual audit has been done.

Upgrading and uninstalling#

Upgrade

  1. Back up the database, add-on files and EE encryption key.
  2. Replace system/user/addons/es_ai with the new release.
  3. Run the update in Add-ons. Keys, settings and data are kept.
  4. Check the Dashboard and the changelog for any new settings.

Uninstall

  1. Export any audit or order-link records you need to keep.
  2. Uninstall through EE's normal add-on flow and confirm data removal.

This removes the add-on's tables and hooks. Native Store products, orders and payments are untouched. Pricing never created persistent shadow orders, so there's nothing extra to clean up. Remove the {exp:es_ai:handoff_notice} tag and the routing rules afterward.

Changelog#

1.0.0-rc.1#

  • Buyer REST, MCP (current and legacy) and A2A 0.3 and 1.0 over shared UCP services; native browser handoff.
  • Owned order reads; status, fulfillment and refund projection; signed, encrypted outbox with reconciliation.
  • 25 scoped merchant tools with exact native writes, live policy checks, approvals and tasks, and snapshot revert.
  • Operations control panel: health dashboard, client policies, buyer access rules, rate controls, signing-key rotation, retention and test console.
  • Optional natural-language buyer layer with Anthropic and OpenAI-compatible adapters, encrypted credentials and spend reservations.
  • Offline commercial license activation.

Support#

  • Security issues: report privately through the support channel included with your purchase. Include your version and a redacted reproduction. Never send production API keys, encryption keys or buyer data.
  • General support: use the support channel included with your purchase, or visit triplenerdscore.com.

© tripleNERDscore, LLC. Expresso Store AI is commercial software, licensed per hostname.