Protocols and patterns are emerging that let AI agents interact with commerce systems - product search, checkout flows, inventory, order management. For that to work reliably we need middleware that orchestrates complex interactions between AI systems and traditional commerce APIs.
I built commerce-orchestrator for that role: an open-source Rust project that sits between AI agents (or any client) and commerce backends as a deterministic orchestration layer.
The Problem
Modern commerce stacks are complex. Simple user actions often require coordination across catalog, inventory, pricing, payment, and order systems. When an AI agent tries to perform the same flow - discover products, check availability, compare pricing, initiate checkout, confirm order - we hit a mismatch: AI systems are stateless and probabilistic; commerce systems need deterministic, transactional flows. Without an orchestration layer you get inconsistent state, duplicated requests, partial transactions, unreliable retries, and security risks. An orchestrator in the middle is what makes agent-driven commerce safe.
What This Project Does Today
The Commerce Orchestrator is middleware: clients call its REST (and A2A) API; the service runs deterministic cart and checkout flows and delegates to your catalog, pricing, tax, geo, payment, and receipt backends via configurable HTTP adapters.
Implemented today:
- Cart and checkout - Create cart, add/update/remove items, apply adjustments, start checkout, execute checkout with idempotency and in-flight deduplication.
- Payment lifecycle - Capture, void, and refund over the facade and HTTP API; tenant-scoped and auth-protected.
- Reliability - Outbox, inbox, and dead-letter primitives; operational endpoints to process outbox, list/replay dead-letter, and run reconciliation.
- Auth and multi-tenancy - Bearer token auth, tenant and scope checks; idempotency and state scoped by tenant.
- Observability - Request IDs, tracing, a metrics endpoint; health probes for liveness and readiness.
-
Discovery -
GET /.well-known/ucpreturns a capability manifest (UCP-style) with version andrest_endpoint; advertised capabilities map to implemented routes. -
A2A -
POST /api/v1/a2a/checkoutandPOST /api/v1/a2a/cartaccept envelope payloads; requests are normalized to the same domain types and policy as REST.
Why Rust
Rust was chosen for performance (high request volume with minimal runtime overhead), reliability (ownership model to avoid memory leaks and concurrency bugs in transactional workflows), and a strong async ecosystem for high-throughput APIs.
Architecture
The codebase is a Cargo workspace of crates. Request flow looks like this:
- orchestrator-http - Axum server, routes, auth, request ID, tracing.
- orchestrator-api - Stable facade: cart commands, checkout execute, payment lifecycle, incoming events, outbox/dead-letter/reconciliation.
- orchestrator-runtime - Durable execution runner, idempotency, retries, timeout handling, persistence traits.
- provider-contracts - Trait interfaces for catalog, pricing, tax, geo, payment, receipt.
- integration-adapters - HTTP clients that implement those traits (configurable base URLs).
- orchestrator-core - Domain model, state machine, validation, policy.
- orchestrator-observability - Tracing, metrics helpers, audit event schemas.
Persistence is file-backed (event store, idempotency, outbox, inbox, dead-letter); restart-recovery tests validate that the same idempotency key returns the same outcome after process restart.
API Surface (What’s Actually There)
All under /api/v1 unless noted. Auth: in production, Bearer token required.
| Area | Endpoints |
|---|---|
| Cart & checkout |
POST /api/v1/cart/commands, POST /api/v1/checkout/execute
|
| A2A |
POST /api/v1/a2a/checkout, POST /api/v1/a2a/cart
|
| Payments |
POST /api/v1/payments/capture, POST /api/v1/payments/void, POST /api/v1/payments/refund
|
| Events |
POST /api/v1/events/incoming (idempotent accept-once) |
| Operations |
POST /api/v1/ops/outbox/process, GET /api/v1/ops/dead-letter, POST /api/v1/ops/dead-letter/replay, POST /api/v1/ops/reconciliation
|
| Discovery |
GET /.well-known/ucp (no auth) |
| Health |
GET /health/live, GET /health/ready, GET /metrics
|
Checkout requests include tenant_id, merchant_id, cart_id, cart_version, idempotency_key, and optional payment-intent fields (e.g. payment_handler_id, ap2_consent_proof). With AP2_STRICT=1, checkout validates a structured consent proof (issuer, signature, expiry, payment handler binding) before execution.
Reliability in Practice
- Idempotency - Checkout and payment lifecycle use idempotency keys; duplicate keys get in-flight deduplication or cached result; state is persisted so restart doesn’t break idempotent semantics.
-
Outbox - Effects can be enqueued and processed via
process_outbox_once(max_attempts); configurable retries with backoff in the adapter client; after max attempts, messages move to dead-letter. - Dead-letter - List and replay via HTTP; replay re-enqueues for another attempt.
-
Incoming events -
accept_incoming_event_once(message_id)deduplicates webhook-style events. -
Reconciliation -
run_reconciliation(transaction_ids)compares orchestrator payment state with provider state (when the provider implementsget_payment_state) and reports mismatches.
Outbox processing is triggered by you (e.g. timer or worker calling the ops endpoint); there is no built-in scheduler in the repo.
Implemented vs Deferred (No Spin)
| Implemented | Deferred / optional |
|---|---|
Discovery /.well-known/ucp, capability manifest, rest_endpoint |
MCP tool mapping (optional; tests “when added”) |
| A2A envelope normalization for checkout and cart | AP2 replay protection for mandates (deferred) |
| Cart commands, checkout execute, payment capture/void/refund | - |
| Idempotency + in-flight dedupe; file-backed persistence | - |
| Outbox, inbox, dead-letter, list/replay, reconciliation | - |
| Bearer auth, tenant isolation, production config (PUBLIC_BASE_URL, etc.) | - |
| AP2 payment intent fields; AP2 strict consent proof validation | - |
| Request IDs, tracing, metrics, health probes | - |
Known limitations (from the repo): File-backed persistence is directory-based JSON and is not suitable for high concurrency without external locking or shared-write storage. Default Kubernetes manifests assume a single replica for this reason. AP2 replay protection (mandate/nonce deduplication) is explicitly deferred.
Current Status and Next Steps
The project is in active development. The core is there: Rust API, orchestration layer, pluggable adapters, async workflows, and the reliability and observability pieces above. Possible next steps: more agent-oriented API shapes, a declarative workflow DSL, stronger observability (e.g. structured audit events), and additional pluggable adapters. MCP mapping and full AP2 replay protection are on the backlog as optional/deferred.
Open Source
The project is available at:
https://github.com/AncientiCe/commerce-orchestrator
If you’re exploring AI-driven commerce, agent automation, or orchestration middleware in Rust, I’d welcome feedback - especially on adapter design, workflow ergonomics, or observability. This repo is one concrete take on AI-safe commerce infrastructure you can run and extend today.
Summary: This post describes only what the repository implements today. Implemented vs deferred and known limitations are taken from the codebase, the conformance matrix, and the changelog.

Top comments (0)