ap2-agentic-payments/skills/ap2-cart-mandate/SKILL.md
Implement the AP2 Cart Mandate — the human-present VDC that binds user authorization to a specific transaction with merchant-signed product offers and user-signed confirmation. Use when building cart creation, signing, and verification for human-present checkout flows.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins ap2-cart-mandateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch live docs:
https://ap2-protocol.org/specification/ for the Cart Mandate schemasite:github.com google-agentic-commerce AP2 src/ap2/types mandate for the Python type definitionssite:github.com google-agentic-commerce AP2 samples cart mandate for sample implementationshttps://ap2-protocol.org/topics/core-concepts/ for Cart Mandate conceptual detailsThe Cart Mandate is the primary VDC for human-present transactions. It captures explicit user authorization for a specific set of items at specific prices, cryptographically binding the user's identity and consent to the exact transaction details.
The Merchant Endpoint creates and signs the Cart Mandate after receiving an Intent Mandate from the Shopping Agent. The merchant's signature guarantees fulfillment of the specified items at the specified prices.
Two signatures are required:
A CartMandate has two parts: contents (CartContents) and merchant_authorization (a JWT).
CartContents fields: id, user_cart_confirmation_required, payment_request (W3C PaymentRequest), cart_expiry, merchant_name.
Based on the specification, key fields include:
{
"contents": {
"id": "cart_identifier",
"user_cart_confirmation_required": true,
"payment_request": {
"method_data": [
{
"supportedMethods": "https://processor.example.com/pay",
"data": { ... }
}
],
"details": {
"id": "order_id",
"displayItems": [
{ "label": "Product Name", "amount": { "currency": "USD", "value": "29.99" } }
],
"total": {
"label": "Total",
"amount": { "currency": "USD", "value": "29.99" }
},
"shipping_options": null
},
"options": {
"requestPayerName": true,
"requestShipping": true,
"requestPayerEmail": false,
"requestPayerPhone": false
}
},
"cart_expiry": "2025-09-01T13:00:00Z",
"merchant_name": "Example Merchant"
},
"merchant_authorization": "<base64url-header>..<base64url-signature>"
}
Cart Mandates embed the W3C Payment Request API structure:
The merchant_authorization is a Base64url-encoded JWT using detached JWS format: <base64url-header>..<base64url-signature> (double dots — the payload is omitted because it is the canonicalized CartContents).
Supported signing algorithms: ES256, ES384, ES512 (ECDSA with P-256, P-384, P-521 curves).
JCS (RFC 8785) canonicalization is applied to the CartContents JSON before signing, ensuring deterministic serialization.
The JWT header MUST include alg and kid claims. The JWT payload includes: iss, aud, iat, exp, jti, cart_hash.
The merchant authorization guarantees:
The user signature proves:
Fetch the specification for exact Cart Mandate fields, signature format, and the payment_request schema before implementing.
development
Build with Spree's headless Next.js storefront — the official `spree/storefront` repo (Next.js 16 App Router with Server Actions and Turbopack, React 19 Server Components, Tailwind CSS 4, TypeScript 5, `@spree/sdk`, Sentry), server-only auth (httpOnly JWT cookies + publishable key), MeiliSearch faceted catalog, one-page checkout with Apple/Google Pay/Klarna/Affirm/SEPA, multi-region market routing, GA4 + JSON-LD SEO, and Vercel/Docker deployment. Use when forking or customizing the storefront, or evaluating headless adoption.
tools
Build Spree extensions as Rails engines — gem scaffolding, `bin/rails g spree:extension`, mounting routes/migrations/assets, the modern `prepend` decorator pattern (`*_decorator.rb` with `self.prepended(base)`), generators (`spree:model_decorator`, `spree:controller_decorator`), the four customization surfaces in preference order (Events > Webhooks > Dependencies > Decorators), Spree::Dependencies for swapping service objects, gem release/versioning, and the deprecated Deface engine. Use when building a reusable Spree extension or adding non-trivial customization to an app.
development
Build with Spree's event bus and Webhooks 2.0 — `Spree::Events` publication, `Spree::Subscriber` DSL with `subscribes_to` and `on`, wildcard matching, lifecycle events (`{model}.created/.updated/.deleted` via `publishes_lifecycle_events`), the canonical event catalog (order.*, payment.*, shipment.*, product.*), Webhooks 2.0 endpoints, HMAC-SHA256 signing (`X-Spree-Webhook-Signature`), exponential-backoff retries, and Sidekiq job orchestration. Use when wiring event-driven business logic, building webhook consumers, or replacing ActiveSupport callback chains.
tools
Cross-cutting Spree development patterns — the customization preference hierarchy (Events > Webhooks > Dependencies > Decorators), `Spree::Dependencies` service-object swapping, the `_decorator.rb` + `prepend` + `self.prepended` idiom, idempotent subscribers and webhook receivers, multi-store scoping discipline, prefixed IDs, calculator polymorphism (shipping/promotion/tax share the base), service-object composition with `dry-monads` or simple results, why to avoid `class_eval` reopening and Deface, and Spree-on-Rails idioms (Hotwire/Turbo Stimulus, ActiveStorage, Action Cable, Sidekiq). Use when designing the architecture of a Spree extension or solving cross-cutting concerns.