tcgunel/ucp-laravel
Composer 安装命令:
composer require tcgunel/ucp-laravel
包简介
Universal Commerce Protocol (UCP) for Laravel — expose your storefront to AI shopping agents.
README 文档
README
Expose any Laravel storefront to AI shopping agents through Google's Universal Commerce Protocol (UCP).
The Universal Commerce Protocol is the open standard — announced by Google in January 2026 and developed with Shopify, Etsy, Wayfair, Target and Walmart — that lets AI agents (Google AI Mode, Gemini, and others) discover and buy from a store programmatically.
ucp-laravel makes your application UCP-native. You implement small per-capability
contracts that map your products and orders onto the UCP schema; the package serves the
discovery manifest, the capability endpoints, validation, and the response envelopes.
Capabilities
The package implements the full UCP 2026-04-08 shopping capability surface over
the REST binding:
| Capability | UCP identifier | Status |
|---|---|---|
| Discovery manifest | /.well-known/ucp |
✅ |
| Catalog — search / lookup / detail | dev.ucp.shopping.catalog |
✅ |
| Cart | dev.ucp.shopping.cart |
✅ |
| Checkout | dev.ucp.shopping.checkout |
✅ |
| Discount | dev.ucp.shopping.discount |
✅ |
| Fulfillment | dev.ucp.shopping.fulfillment |
✅ |
| Order — lookup + webhooks | dev.ucp.shopping.order |
✅ |
| Identity Linking — OAuth 2.0 | dev.ucp.common.identity_linking |
✅ |
| AP2 Mandates — agent payments | dev.ucp.shopping.ap2_mandate |
✅ |
Security-critical pieces stay in your application, behind contracts: the package
never captures payment, never implements an OAuth server, and never owns
your signing keys. Checkout completion, the OAuth /oauth2/* endpoints and the ES256
crypto are delegated to provider contracts you implement.
Spec note. UCP is young and its schemas are still moving. This package mirrors the
2026-04-08revision; treat the JSON shapes as a faithful implementation, not a frozen guarantee. Verify against ucp.dev before going to production.
Requirements
- PHP 8.2+
- Laravel 11, 12 or 13
Installation
Once published to Packagist:
composer require tcgunel/ucp-laravel
While the package is consumed privately across projects, add it as a path or VCS repository — see docs/installation.md.
Publish the config file (optional — the package works with sensible defaults):
php artisan vendor:publish --tag=ucp-config
The service provider is auto-discovered. The UCP routes are live immediately; each capability stays dormant — and unadvertised in the manifest — until you configure its provider.
Quick start
Each capability is one contract. Start with Catalog — it is read-only and the fastest to ship:
namespace App\Ucp; use App\Models\Product as Listing; use Tcgunel\Ucp\Contracts\CatalogProvider; use Tcgunel\Ucp\DTO\Availability; use Tcgunel\Ucp\DTO\Money; use Tcgunel\Ucp\DTO\PriceRange; use Tcgunel\Ucp\DTO\Product; use Tcgunel\Ucp\DTO\RequestContext; use Tcgunel\Ucp\DTO\SearchQuery; use Tcgunel\Ucp\DTO\SearchResult; use Tcgunel\Ucp\DTO\Variant; final class EloquentCatalogProvider implements CatalogProvider { public function search(SearchQuery $query): SearchResult { $listings = Listing::query() ->when($query->hasQuery(), fn ($q) => $q->where('name', 'like', "%{$query->query}%")) ->limit($query->pagination->limit) ->get(); return new SearchResult(products: $listings->map($this->toUcpProduct(...))->all()); } public function lookup(array $ids, RequestContext $context): array { return Listing::query()->findMany($ids)->map($this->toUcpProduct(...))->all(); } public function product(string $id, array $selected, array $preferences, RequestContext $context): ?Product { $listing = Listing::query()->find($id); return $listing instanceof Listing ? $this->toUcpProduct($listing) : null; } private function toUcpProduct(Listing $listing): Product { $price = new Money((int) $listing->price_in_kurus, 'TRY'); return new Product( id: (string) $listing->id, title: $listing->name, description: $listing->description ?? '', priceRange: PriceRange::uniform($price), variants: [ new Variant( id: (string) $listing->id, title: $listing->name, price: $price, availability: $listing->stock > 0 ? Availability::inStock($listing->stock) : Availability::outOfStock(), ), ], ); } }
Register it:
// config/ucp.php 'catalog_provider' => \App\Ucp\EloquentCatalogProvider::class,
Every other capability follows the same shape — implement a contract, register it under its config key. See the guides below.
Endpoints
| Method & path | Capability |
|---|---|
GET /.well-known/ucp |
discovery manifest |
GET /.well-known/oauth-authorization-server · /.well-known/oauth-protected-resource |
Identity Linking |
POST /catalog/search · /catalog/lookup · /catalog/product |
Catalog |
POST /carts · GET·PUT /carts/{id} · POST /carts/{id}/cancel |
Cart |
POST /checkout-sessions · GET·PUT /checkout-sessions/{id} · POST …/complete · …/cancel |
Checkout |
GET /orders/{id} |
Order |
Catalog requests reject malformed input with 422. For cart, checkout and order,
business outcomes return 200 with a messages[] array — the UCP convention —
while only protocol-level problems use HTTP error statuses. Order-lifecycle updates are
pushed to agents as signed webhooks.
How it works
AI shopping agent
│
├── GET /.well-known/ucp ──────────► ManifestController ──► ManifestBuilder
│ (advertises only configured capabilities)
│
├── GET /.well-known/oauth-* ───────► IdentityController ──► IdentityLinkProvider
│
└── POST /catalog · /carts · ───────► capability controller
/checkout-sessions · GET /orders (validate → DTO)
│
▼
Catalog · Cart · Checkout · Order providers ← YOUR CODE
The package owns the protocol — routing, the manifest, request validation, the ucp
response envelope, the JSON schema. Your application owns the data, the OAuth server and
the crypto, through small contracts. Controllers stay thin; DTOs are immutable; every
capability is an interface.
Documentation
| Guide | Contents |
|---|---|
| Installation | Composer setup, publishing, what gets registered |
| Configuration | Every config/ucp.php key |
| Catalog provider | The catalog contract, the DTOs, money precision |
| Cart & checkout providers | The session contracts, lifecycle, discounts, fulfilment, payment |
| Order, Identity & AP2 | Order webhooks, OAuth discovery, AP2 mandates |
| Multi-tenancy | Per-tenant manifests and capabilities |
| Manifest reference | The /.well-known/ucp JSON structure |
| Roadmap | What's next |
Multi-tenancy
The package is built for multi-tenant SaaS. Endpoint URLs in the manifest follow the request host, so per-tenant domains work with zero extra wiring. See docs/multi-tenancy.md.
Testing
composer test
The suite runs against Orchestra Testbench; no host application is required.
Code quality
| Tool | Command | Standard |
|---|---|---|
| Pint | composer lint / composer format |
Laravel preset + strict types |
| PHPStan (Larastan) | composer analyse |
Level 8 |
| PHPUnit | composer test |
— |
composer check runs all three.
Contributing
Bug reports and pull requests are welcome. Please run composer check before opening a
PR. See CHANGELOG.md for release history.
License
The MIT License. See LICENSE.
Credits
- Built by Tolga Can Günel.
- Implements the Universal Commerce Protocol — a project of Google and the broader commerce community.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-21