Overview
Icon for Agentic Commerce

Agentic Commerce

Enable agentic commerce endpoints

@financedistrict/medusa-plugin-agentic-commerce

Make your Medusa v2 store shoppable by AI agents.

This plugin adds UCP and ACP protocol endpoints to your Medusa backend, so AI shopping agents can discover your products, create checkouts, and complete purchases — through standard HTTP APIs that require no frontend at all.

Why this matters

AI agents are becoming the next commerce channel. Just like merchants once added mobile apps alongside their websites, they'll soon need to serve autonomous agents that shop on behalf of consumers. But agents don't browse — they need structured APIs with standardized discovery, checkout flows, and payment settlement.

UCP (Universal Commerce Protocol) and ACP (Agentic Commerce Protocol) are the emerging open standards for this. This plugin implements both as native Medusa v2 modules, so your store speaks the language agents understand — in minutes, with no custom code and no frontend changes.

What you get

Feature Description Dual protocol support Both UCP and ACP endpoints from a single plugin Product discovery Full-text search and direct lookup for agents to browse your catalog Checkout sessions Create, update, complete, and cancel — with idempotency built in Pluggable payments Bring your own payment handler via the adapter interface Order tracking Agents can retrieve order status and details Webhook notifications Automatic agent callbacks on order placement Protocol discovery Copy to clipboard/.well-known/ucp and Copy to clipboard/.well-known/acp.json for automatic capability detection Product feed sync Scheduled job to push your catalog to agent platforms

Quick Start

1. Install

npm install @financedistrict/medusa-plugin-agentic-commerce

2. Configure Copy to clipboardmedusa-config.ts

import { defineConfig } from "@medusajs/framework/utils"
export default defineConfig({
// Register the plugin for route/workflow/subscriber auto-discovery
plugins: [
{
resolve: "@financedistrict/medusa-plugin-agentic-commerce",
options: {},
},
],
modules: [
// Register the agent session module (owns quotes, ownership and cancellation state)
{
key: "agenticCommerceSession",
resolve: "@financedistrict/medusa-plugin-agentic-commerce/modules/agent-session",
},
// Register the core service module with your configuration
{
key: "agenticCommerce",
resolve: "@financedistrict/medusa-plugin-agentic-commerce/modules/agentic-commerce",

Run Copy to clipboardnpx medusa db:migrate after installing or upgrading: the agent session module creates the Copy to clipboardagent_session table and the same module creates the Copy to clipboardpayment_authorization table of the payment ledger. Checkout sessions and carts opened before this version have no row or no session secret and must be recreated by the agent.

A signed payment authorization (token, payer and nonce) can be used on one cart only. The payment ledger records it before the cart is completed, so the same authorization is refused on a second cart (ACP answers Copy to clipboard409 payment_authorization_used) while the cart that holds it can still retry. Checkout completion fails when the agent session module is not registered.

3. Set Environment Variables

# Required
AGENTIC_COMMERCE_API_KEY=your-secret-api-key
AGENTIC_PAYMENT_PROVIDER=pp_prism_prism
# Optional
AGENTIC_COMMERCE_SIGNATURE_KEY=your-hmac-secret
STOREFRONT_URL=https://your-store.com
AGENTIC_STORE_NAME="Your Store"
AGENTIC_STORE_DESCRIPTION="Premium widgets for humans and agents"

4. Start Your Store

npx medusa develop

Your agent APIs are now live:

# Discovery
curl http://localhost:9000/.well-known/ucp
curl http://localhost:9000/.well-known/acp.json
# Search products (UCP)
curl -X POST http://localhost:9000/ucp/catalog/search \
-H "UCP-Agent: my-agent/1.0" \
-H "Request-Id: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"query": "t-shirt", "limit": 10}'

Protocols

UCP (Unified Commerce Protocol)

UCP is designed for agent-to-merchant interactions. It uses a shopping-cart model where agents manage carts directly.

Endpoint Method Description Copy to clipboard/.well-known/ucp GET Protocol discovery and capabilities, with Copy to clipboardsupported_versions Copy to clipboard/.well-known/ucp/:version GET Discovery profile for one enabled UCP version (404 when not enabled) Copy to clipboard/ucp/catalog/search POST Full-text product search Copy to clipboard/ucp/catalog/lookup POST Direct product lookup by ID or handle Copy to clipboard/ucp/carts POST Create a new cart Copy to clipboard/ucp/carts/:id GET Retrieve cart Copy to clipboard/ucp/carts/:id PUT Update cart (add/remove items, set address) Copy to clipboard/ucp/checkout-sessions POST Create checkout session from cart Copy to clipboard/ucp/checkout-sessions/:id GET Retrieve checkout session Copy to clipboard/ucp/checkout-sessions/:id PUT Update checkout session Copy to clipboard/ucp/checkout-sessions/:id/complete POST Complete checkout and place order Copy to clipboard/ucp/checkout-sessions/:id/cancel POST Cancel checkout session Copy to clipboard/ucp/orders/:id GET Retrieve order details

Required headers: Copy to clipboardUCP-Agent, Copy to clipboardRequest-Id, and Copy to clipboardUCP-Session-Secret on every call that follows the create call (see below)

Session secret: creating a cart or checkout session returns a random Copy to clipboardUCP-Session-Secret response header, once. Send it as the Copy to clipboardUCP-Session-Secret request header on every later call for that cart or session, and on Copy to clipboardGET /ucp/orders/:id for the order it placed. The store keeps only a hash of it. The Copy to clipboardUCP-Agent header and a Bearer token do not identify the buyer. A request without the secret gets Copy to clipboard401 session_secret_required, checked before anything is read. A wrong secret, or an unknown id, gets Copy to clipboard404 with Copy to clipboardcart_not_found, Copy to clipboardcheckout_not_found or Copy to clipboardorder_not_found. The secret is checked before the version pin. URLs in responses carry ids only. If a create response is lost, create a new session: a replayed create (same Copy to clipboardIdempotency-Key) does not return the secret again.

Versions: the store serves Copy to clipboarducp_version (default: the latest version, currently Copy to clipboard2026-08-25) plus every version in Copy to clipboarducp_supported_versions (default: every other known version, currently Copy to clipboard2026-04-08, Copy to clipboard2026-01-23). The version for a request comes from the Copy to clipboarducp.version of the agent profile named in Copy to clipboardUCP-Agent: ...; profile="https://...". The profile is fetched over HTTPS only, from public addresses only, with a 3 s timeout, a 128 KiB cap and no redirects, and cached for 10 minutes. At most 16 profiles are fetched at once, 4 per host and 8 per client IP (Copy to clipboardreq.ip); concurrent lookups of one URL share a single fetch, and a busy answer falls back to the last known profile of that URL. Rate-limit Copy to clipboard/ucp at your edge as well.

Agent profile Copy to clipboardlenient (default) Copy to clipboardstrict no Copy to clipboardUCP-Agent header Copy to clipboard400 missing_ucp_agent Copy to clipboard400 missing_ucp_agent no Copy to clipboardprofile in Copy to clipboardUCP-Agent current version current version unreachable or not HTTPS current version + warning log Copy to clipboard424 profile_unreachable profile fetcher busy current version + warning log, or the session version Copy to clipboard503 profile_fetch_busy with Copy to clipboardRetry-After: 3, or the session version no or malformed Copy to clipboarducp.version current version + warning log Copy to clipboard422 profile_malformed unknown version Copy to clipboard422 version_unsupported Copy to clipboard422 version_unsupported known version the store disabled Copy to clipboard422 version_unsupported Copy to clipboard422 version_unsupported enabled version that version that version

Other FD store plugins serve the current version when Copy to clipboardUCP-Agent is missing; this plugin keeps its original Copy to clipboard400.

A checkout session or cart created for a declared version stays on it. A later request that declares a different version gets Copy to clipboard422 version_unsupported; a request whose profile cannot be resolved keeps the session's version. Copy to clipboardlenient deviates from the UCP spec on purpose: agents built before version negotiation keep working. Warnings are logged as JSON with the key Copy to clipboarducp_profile_resolution. In Copy to clipboard2026-01-23, cart and catalog routes answer Copy to clipboard404 capabilities_incompatible.

Complete checkout: each Copy to clipboardpayment.instruments[] entry carries a Copy to clipboardcredential. With the Prism provider, Copy to clipboardhandler_id is Copy to clipboardxyz.fd.prism_payment, Copy to clipboardx402 or omitted; Copy to clipboardtype is Copy to clipboardx402, Copy to clipboardtokenized, Copy to clipboarddefault or omitted; Copy to clipboardcredential.type is Copy to clipboardx402 or omitted. Any other value returns Copy to clipboard422 invalid_instrument, and the signed amount must still match the cart's Prism quote. A failed payment returns Copy to clipboard422 payment_failed; responses under 500 are cached per Copy to clipboardIdempotency-Key for 24 hours, so retry with a new key.

ACP (Agent Commerce Protocol)

ACP is designed for platform-to-merchant interactions. It uses a session-based model where the platform manages the checkout flow.

Endpoint Method Description Copy to clipboard/.well-known/acp.json GET Protocol discovery and capabilities Copy to clipboard/acp/checkout_sessions POST Create checkout session Copy to clipboard/acp/checkout_sessions/:id GET Retrieve checkout session Copy to clipboard/acp/checkout_sessions/:id POST Update checkout session Copy to clipboard/acp/checkout_sessions/:id/complete POST Complete checkout Copy to clipboard/acp/checkout_sessions/:id/cancel POST Cancel checkout session Copy to clipboard/acp/orders/:id GET Retrieve order Copy to clipboard/acp/product-feed GET Retrieve product feed

Required headers: Copy to clipboardAuthorization: Bearer <api_key>, Copy to clipboardAPI-Version

A checkout session belongs to the API key that created it. Copy to clipboardGET /acp/orders/:id answers Copy to clipboard404 not_found unless the order was placed by a session that API key opened.

Payment Handlers

Payment is handled through a pluggable adapter system. Each adapter implements the Copy to clipboardPaymentHandlerAdapter interface and registers as a Medusa module.

Using the Prism Payment Handler

For x402 stablecoin payments (USDC, FDUSD, etc.), use the companion package:

npm install @financedistrict/medusa-plugin-prism-payment

See @financedistrict/medusa-plugin-prism-payment for setup instructions.

Building a Custom Payment Handler

Implement the Copy to clipboardPaymentHandlerAdapter interface:

import type {
PaymentHandlerAdapter,
CheckoutPrepareInput,
} from "@financedistrict/medusa-plugin-agentic-commerce"
export default class MyPaymentAdapter implements PaymentHandlerAdapter {
readonly id = "my_payment_handler"
readonly name = "My Payment"
// Discovery — what to advertise in .well-known endpoints
async getUcpDiscoveryHandlers(): Promise<Record<string, unknown[]>> {
return {
"com.example.my_payment": [{
id: "my-handler",
version: "1.0.0",
}],
}
}
async getAcpDiscoveryHandlers(): Promise<unknown[]> {

Register it as a Medusa module and reference it in Copy to clipboardpayment_handler_adapters:

// medusa-config.ts
modules: [
{
key: "myPaymentHandler",
resolve: "./src/modules/my-payment-handler",
options: { /* ... */ },
},
{
key: "agenticCommerce",
resolve: "@financedistrict/medusa-plugin-agentic-commerce/modules/agentic-commerce",
options: {
payment_handler_adapters: ["myPaymentHandler"],
payment_provider_id: "pp_my_provider",
// ...
},
},
]

Architecture

medusa-config.ts
|
+-- plugins: [@financedistrict/medusa-plugin-agentic-commerce]
| Routes, workflows, subscribers, jobs auto-discovered
|
+-- modules:
+-- agenticCommerceSession (agent_session table)
| Fingerprint, UCP version pin, cancellation, payment quotes
|
+-- agenticCommerce (core service)
| Config, auth, formatting, payment registry
|
+-- prismPaymentHandler (optional adapter)
Discovery, checkout-prepare, response formatting

How Adapter Resolution Works

Medusa v2 modules have isolated DI containers. The plugin resolves payment handler adapters from the request-scoped container (Copy to clipboardreq.scope) via middleware — not from the module's constructor. This ensures all modules are registered and accessible at request time.

Request → resolvePaymentAdapters middleware → route handler
|
+-- req.scope.resolve("prismPaymentHandler")
+-- agenticCommerceService.resolveAdapters(req.scope)

Workflows

The plugin provides four reusable workflows that orchestrate the checkout process:

Workflow Description Copy to clipboardcreateCheckoutSessionWorkflow Validates cart, resolves region, prepares payment Copy to clipboardupdateCheckoutSessionWorkflow Handles item/address changes, re-prepares payment Copy to clipboardcompleteCheckoutSessionWorkflow Completes payment, creates order Copy to clipboardcancelCheckoutSessionWorkflow Cancels session and releases resources

Import them in your custom code:

import {
createCheckoutSessionWorkflow,
completeCheckoutSessionWorkflow,
} from "@financedistrict/medusa-plugin-agentic-commerce/workflows"

Configuration

Plugin Options

Option Type Default Description Copy to clipboardapi_key Copy to clipboardstring Copy to clipboard"" API key for ACP Bearer token authentication Copy to clipboardsignatureKey Copy to clipboardstring Copy to clipboard"" HMAC-SHA256 key for request signing. Set it in production: with no key, outbound webhook signatures can be computed by anyone and inbound Copy to clipboardSignature headers are rejected Copy to clipboardstorefront_url Copy to clipboardstring Copy to clipboard"http://localhost:8000" Public URL of your storefront Copy to clipboardstore_name Copy to clipboardstring Copy to clipboard"My Store" Store name in protocol responses Copy to clipboardstore_description Copy to clipboardstring Copy to clipboard"" Store description for discovery Copy to clipboardpayment_provider_id Copy to clipboardstring required Medusa payment provider that settles agent payments, for example Copy to clipboard"pp_prism_prism" Copy to clipboardallow_system_payment_provider Copy to clipboardboolean Copy to clipboardfalse Allows Copy to clipboardpp_system_default for local testing. It approves every payment, so it also needs Copy to clipboardNODE_ENV Copy to clipboarddevelopment or Copy to clipboardtest and no Copy to clipboardpayment_handler_adapters Copy to clipboardpayment_handler_adapters Copy to clipboardstring[] Copy to clipboard[] Module keys of payment handler adapters Copy to clipboarducp_version Copy to clipboardstring latest (Copy to clipboard"2026-08-25") Current UCP version, served when the agent declares none. Set Copy to clipboard"2026-04-08" to keep the root profile of 0.x releases Copy to clipboarducp_supported_versions Copy to clipboardstring[] every known version except Copy to clipboarducp_version Further UCP versions served on request; the current version is removed from this list Copy to clipboarducp_version_negotiation Copy to clipboard"lenient" | "strict" Copy to clipboard"lenient" How an unusable agent profile is handled (see UCP above) Copy to clipboardacp_version Copy to clipboardstring Copy to clipboard"2026-01-30" ACP protocol version to advertise

An unknown version or negotiation value stops the store at boot. So does a missing Copy to clipboardpayment_provider_id, or the system provider outside the local-testing case above.

Medusa's own Copy to clipboard/store/carts/:id/complete and any other caller of Copy to clipboardcompleteCartWorkflow cannot complete an agent cart: a validate hook lets it complete only inside the plugin's checkout completion. Medusa allows one handler per workflow hook, so a store that registers its own Copy to clipboardcompleteCartWorkflow.hooks.validate fails at boot with this plugin; move that check to another hook or step. The hook also runs for a cart that already has an order, so a repeated native complete of an agent cart answers Copy to clipboardagent_checkout_required.

The plugin records on the agent session that the payment provider is about to be called, through the Copy to clipboardbeforePaymentAuthorization hook of Copy to clipboardcompleteCartWorkflow. A failure after that point holds the payment for review instead of freeing the cart for another credential. Medusa allows one handler per workflow hook, so a store or another plugin that registers its own Copy to clipboardbeforePaymentAuthorization handler fails at boot with this plugin.

Environment Variables

Variable Maps to Copy to clipboardAGENTIC_COMMERCE_API_KEY Copy to clipboardapi_key Copy to clipboardAGENTIC_COMMERCE_SIGNATURE_KEY Copy to clipboardsignatureKey Copy to clipboardSTOREFRONT_URL Copy to clipboardstorefront_url Copy to clipboardAGENTIC_STORE_NAME Copy to clipboardstore_name Copy to clipboardAGENTIC_STORE_DESCRIPTION Copy to clipboardstore_description Copy to clipboardAGENTIC_PAYMENT_PROVIDER Copy to clipboardpayment_provider_id

Exported Utilities

import {
// Service & module
AgenticCommerceService,
AgenticCommerceModule,
AGENTIC_COMMERCE_MODULE,
// Payment adapter interface
PaymentHandlerAdapter, // type
CheckoutPrepareInput, // type
PaymentHandlerRegistry,
// Error formatting
formatAcpError,
formatUcpError,
// Address translation
medusaToAcpAddress,
acpAddressToMedusa,
medusaToUcpAddress,
ucpAddressToMedusa,

Protocol Compliance

Types and formatters are audited against the official protocol specifications:

Versioning

This package follows semver. While pre-1.0:

  • Protocol spec changes → minor bump (e.g., 0.1.x → 0.2.0)
  • Medusa compatibility changes → patch bump (e.g., 0.1.0 → 0.1.1)
  • Bug fixes → patch bump

The companion Copy to clipboard@financedistrict/medusa-plugin-prism-payment declares this package as a peer dependency with a Copy to clipboard^ range (e.g., Copy to clipboard^0.1.0), so incompatible combinations are caught at install time.

Requirements

  • Medusa v2 (2.x)
  • Node.js >= 20
  • PostgreSQL (standard Medusa requirement)

License

MIT

You may also like

Browse all integrations

Build your own

Develop your own custom integration

Build your own integration with our API to speed up your processes. Make your integration available via npm for it to be shared in our Library with the broader Medusa community.

gift card interface

Ready to build your custom commerce setup?