UCP (Universal Commerce Protocol) store-side SDK: make any PHP shop visible and shoppable for AI agents — manifest, agent-readable catalog, checkout sessions with signed cart hand-off.

v0.1.0 2026-08-02 09:33 UTC

This package is auto-updated.

Last update: 2026-08-02 09:49:40 UTC


README

Store-side SDK for UCP (Universal Commerce Protocol): AI agents discover your store through /.well-known/ucp, read the catalog, build a cart via checkout sessions and hand a signed cart link to the human — payment always stays with your store. This package brings the same protocol surface that the Botmetria WooCommerce plugin ships, to any PHP platform: custom engines, Laravel, Slim, legacy front controllers.

  • Zero required dependencies (PHP ≥ 8.1, ext-json).
  • Two capability levels from one integration:
    • implement ProductProviderInterface → agents see your catalog (manifest honestly reports checkout: false — "storefront mode");
    • also implement CartProviderInterface → full agent checkout with HMAC-signed cart hand-off into your native checkout.
  • Wire format is pinned by cross-implementation golden fixtures (tests/ verify byte-level parity with the WooCommerce plugin and the Botmetria cloud) — see SPEC.md / ucp-store spec.

Install

composer require botmetria/ucp

Quick start (plain PHP front controller)

use Botmetria\Ucp\Ucp;
use Botmetria\Ucp\ArrayProductProvider;

$ucp = new Ucp([
    'store_name' => 'My Shop',
    'store_url'  => 'https://my-shop.com/',
    'currency'   => 'EUR',
    'country'    => 'MD',
    'products'   => new ArrayProductProvider($myItems), // or your own provider
    // 'cart'    => new MyCartProvider(),               // optional: enables agent checkout
]);
$ucp->run(); // serves /.well-known/ucp and /ucp/v1/*; otherwise returns control

Put those lines at the very top of your front controller (index.php), before your application's routing.

Your adapters

use Botmetria\Ucp\ProductProviderInterface;
use Botmetria\Ucp\CartProviderInterface;

final class MyProducts implements ProductProviderInterface
{
    public function list(int $offset, int $limit, string $query = '', string $category = ''): array
    {
        // return canonical item arrays: id, name, url, price, currency (+optional
        // description, sku, gtin, brand, category[], availability, images[]...)
    }

    public function get(string $id): ?array { /* one item or null */ }
}

final class MyCart implements CartProviderInterface
{
    public function fill(array $items): string
    {
        foreach ($items as $item) {
            $this->cart->add($item['id'], $item['quantity']); // your platform's cart
        }
        return '/checkout'; // where to send the shopper
    }
}

That is the whole integration: ~30 lines for catalog-only, ~50 with checkout.

Framework bridges

  • Laravel: bind Ucp::class as a singleton, prepend Botmetria\Ucp\Bridge\LaravelMiddleware to the global middleware stack.
  • PSR-15 (Slim, Mezzio): new Bridge\Psr15Middleware($ucp, $responseFactory) first in the pipeline (requires psr/http-server-middleware).

Sessions & rate limiting

Checkout sessions live 24h in a pluggable key-value store: Storage\FileStore (default, single server), Storage\ApcuStore (shared across workers), or your own Storage\KeyValueStoreInterface over Redis for multi-server setups. A sliding-window rate limiter (120 req / 60 s per IP) guards /ucp/v1/* out of the box.

Order attribution

When an order born from an agent cart is placed, call $ucp->markOrdered($sessionId, $orderId) in your order hook — the session id arrives with the hand-off. Sessions also carry source (chatgpt / perplexity / claude / …) detected from the agent's User-Agent.

Verify your integration

Run the free agent purchase demo on your domain: a real agent reads your manifest, opens the catalog, picks a product and (with checkout enabled) builds a cart with a live hand-off link.

License

MIT © Botmetria — botmetria.com