Skip to content

chatbasket/acp-server

Repository files navigation

Agentic Commerce Protocol (ACP) Server

A reference implementation of the Agentic Commerce Protocol specification (v2025-12-11) in Python using FastAPI.

Overview

This server implements the complete ACP specification:

  1. Agentic Checkout API - Manages checkout session lifecycle (create, update, retrieve, complete, cancel)
  2. Delegate Payment API - Handles secure payment credential tokenization with allowance constraints
  3. Product Feed API - Provides structured product catalog following OpenAI Product Feed specification

Features

✅ Full ACP specification compliance (v2025-12-11)
✅ FastAPI with automatic OpenAPI documentation
✅ Pydantic models for type safety and validation
✅ Bearer token authentication
✅ API version validation
✅ Idempotency support
✅ Standardized error responses
✅ Product catalog with 10+ sample products
✅ Product validation in checkout sessions
✅ CORS enabled for browser JavaScript clients
✅ In-memory storage (easily replaceable with database)

Quick Start

Prerequisites

  • Python 3.11 or higher
  • pip

Installation

  1. Clone or download this repository
cd acp-server
  1. Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install dependencies
pip install -r requirements.txt
  1. Configure environment (optional)
cp .env.example .env
# Edit .env to customize settings
  1. Run the server
python main.py

The server will start on http://localhost:8000

API Documentation

Once the server is running, visit:

API Endpoints

Agentic Checkout API

1. Create Checkout Session

POST /checkout_sessions

Creates a new checkout session from items and optional buyer/address.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-12-11 (required)
  • Idempotency-Key: <uuid> (recommended)
  • Content-Type: application/json (required)

Request Body:

{
  "items": [
    {
      "id": "item_456",
      "quantity": 1
    }
  ],
  "fulfillment_address": {
    "name": "John Doe",
    "line_one": "1234 Chat Road",
    "line_two": "",
    "city": "San Francisco",
    "state": "CA",
    "country": "US",
    "postal_code": "94131"
  }
}

Response: 201 Created - Full checkout session with line items, totals, and fulfillment options


2. Retrieve Checkout Session

GET /checkout_sessions/{checkout_session_id}

Returns the current state of a checkout session.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-12-11 (required)

Response: 200 OK - Full checkout session state


3. Update Checkout Session

POST /checkout_sessions/{checkout_session_id}

Updates items, address, or fulfillment option selection.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-12-11 (required)
  • Idempotency-Key: <uuid> (recommended)

Request Body:

{
  "fulfillment_option_id": "fulfillment_option_456"
}

Response: 200 OK - Updated checkout session


4. Complete Checkout Session

POST /checkout_sessions/{checkout_session_id}/complete

Finalizes the checkout with payment and creates an order.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-12-11 (required)
  • Idempotency-Key: <uuid> (recommended)

Request Body:

{
  "buyer": {
    "first_name": "John",
    "last_name": "Smith",
    "email": "johnsmith@mail.com",
    "phone_number": "15552003434"
  },
  "payment_data": {
    "token": "spt_123",
    "provider": "stripe",
    "billing_address": {
      "name": "John Smith",
      "line_one": "1234 Chat Road",
      "line_two": "",
      "city": "San Francisco",
      "state": "CA",
      "country": "US",
      "postal_code": "94131"
    }
  }
}

Response: 200 OK - Completed session with order details


5. Cancel Checkout Session

POST /checkout_sessions/{checkout_session_id}/cancel

Cancels an active checkout session.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-12-11 (required)

Response: 200 OK - Canceled session


Delegate Payment API

Create Payment Token

POST /agentic_commerce/delegate_payment

Creates a delegated vault token for payment credentials with allowance constraints.

Headers:

  • Authorization: Bearer <token> (required)
  • API-Version: 2025-09-29 (required - Note: Uses different version)
  • Idempotency-Key: <uuid> (recommended)
  • Content-Type: application/json (required)

Request Body:

{
  "payment_method": {
    "type": "card",
    "card_number_type": "fpan",
    "virtual": false,
    "number": "4242424242424242",
    "exp_month": "11",
    "exp_year": "2026",
    "name": "Jane Doe",
    "cvc": "223",
    "display_card_funding_type": "credit",
    "display_brand": "visa",
    "display_last4": "4242",
    "metadata": {}
  },
  "allowance": {
    "reason": "one_time",
    "max_amount": 2000,
    "currency": "usd",
    "checkout_session_id": "checkout_session_123",
    "merchant_id": "merchant_abc",
    "expires_at": "2025-10-09T07:20:50.52Z"
  },
  "risk_signals": [
    {
      "type": "card_testing",
      "score": 10,
      "action": "authorized"
    }
  ],
  "metadata": {}
}

Response: 201 Created

{
  "id": "vt_01J8Z3WXYZ9ABC",
  "created": "2025-09-29T11:00:00Z",
  "metadata": {
    "source": "agentic_checkout",
    "merchant_id": "merchant_abc"
  }
}

Product Feed API

Get Product Feed

GET /products/feed

Returns the product catalog in JSONL format following the OpenAI Product Feed specification.

Query Parameters:

  • format - Output format: jsonl (default) or json
  • query - Text search in title and description (optional)
  • category - Filter by category (optional)
  • brand - Filter by brand (optional)
  • in_stock_only - Only return in-stock products (optional, default: false)

Response (format=json): 200 OK

{
  "products": [
    {
      "id": "LAPTOP-PRO-15",
      "title": "Professional Laptop 15-inch",
      "description": "High-performance laptop...",
      "price": "129900 USD",
      "availability": "in_stock",
      "inventory_quantity": 50,
      "enable_search": true,
      "enable_checkout": true,
      ...
    }
  ],
  "count": 10
}

Response (format=jsonl): 200 OK with Content-Type: application/x-ndjson


Search Products

GET /products

Search and filter products in the catalog.

Query Parameters:

  • query - Text search (optional)
  • category - Filter by category (optional)
  • brand - Filter by brand (optional)
  • min_price - Minimum price in minor units (optional)
  • max_price - Maximum price in minor units (optional)
  • in_stock_only - Only in-stock products (optional)
  • limit - Max results, default 100 (optional)

Example:

curl "http://localhost:8000/products?query=laptop&in_stock_only=true&limit=5"

Response: 200 OK

{
  "products": [...],
  "count": 5,
  "query": {
    "query": "laptop",
    "in_stock_only": true,
    "limit": 5
  }
}

Get Product by ID

GET /products/{product_id}

Retrieve a specific product by its ID.

Example:

curl http://localhost:8000/products/LAPTOP-PRO-15

Response: 200 OK - Product object

Response (Not Found): 404 Not Found


Health Check

GET /health

Returns server health status and statistics.

Response: 200 OK

{
  "status": "healthy",
  "timestamp": "2025-12-22T10:30:00Z",
  "sessions_count": 5,
  "tokens_count": 3
}

Example Usage with cURL

1. Browse available products

# Get all products
curl http://localhost:8000/products

# Search for specific products
curl "http://localhost:8000/products?query=laptop&in_stock_only=true"

# Get product feed in JSONL format
curl http://localhost:8000/products/feed?format=jsonl

2. Create a checkout session with catalog products

curl -X POST http://localhost:8000/checkout_sessions \
  -H "Authorization: Bearer demo-token-12345" \
  -H "API-Version: 2025-12-11" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {"product_id": "LAPTOP-PRO-15", "quantity": 1},
      {"product_id": "WIRELESS-MOUSE", "quantity": 1}
    ],
    "fulfillment_address": {
      "name": "John Doe",
      "line_one": "1234 Main St",
      "line_two": "",
      "city": "San Francisco",
      "state": "CA",
      "country": "US",
      "postal_code": "94131"
    }
  }'

Note: The items now use product_id which must exist in the products.json catalog. The checkout will validate:

  • Product exists in catalog
  • Product is available for checkout (enable_checkout: true)
  • Product is in stock
  • Sufficient inventory for requested quantity

Product prices are automatically pulled from the catalog.

3. Retrieve the session

curl -X GET http://localhost:8000/checkout_sessions/{session_id} \
  -H "Authorization: Bearer demo-token-12345" \
  -H "API-Version: 2025-12-11"

4. Update fulfillment option

curl -X POST http://localhost:8000/checkout_sessions/{session_id} \
  -H "Authorization: Bearer demo-token-12345" \
  -H "API-Version: 2025-12-11" \
  -H "Content-Type: application/json" \
  -d '{
    "fulfillment_option_id": "fulfillment_option_exp_abc123"
  }'

5. Complete checkout

curl -X POST http://localhost:8000/checkout_sessions/{session_id}/complete \
  -H "Authorization: Bearer demo-token-12345" \
  -H "API-Version: 2025-12-11" \
  -H "Content-Type: application/json" \
  -d '{
    "buyer": {
      "first_name": "John",
      "last_name": "Smith",
      "email": "john@example.com"
    },
    "payment_data": {
      "token": "spt_demo_token",
      "provider": "stripe"
    }
  }'

Configuration

The server can be configured via environment variables:

Variable Default Description
API_VERSION 2025-12-11 ACP API version
BEARER_TOKEN demo-token-12345 Authentication token
HOST 0.0.0.0 Server host
PORT 8000 Server port

Project Structure

acp-server/
├── main.py              # FastAPI application with endpoints
├── models.py            # Pydantic data models
├── utils.py             # Utility functions and middleware
├── requirements.txt     # Python dependencies
├── .env.example         # Environment variable template
├── .gitignore          # Git ignore rules
└── README.md           # This file

Architecture Notes

In-Memory Storage

This reference implementation uses in-memory dictionaries for:

  • checkout_sessions - Active checkout sessions
  • payment_tokens - Delegated payment tokens
  • idempotency_cache - Idempotency key tracking

For production use, replace these with:

  • PostgreSQL/MySQL for relational data
  • Redis for caching and idempotency
  • Secure vault service for payment credentials

Mock Data

The implementation includes mock pricing and fulfillment logic:

  • All items are priced at $30.00 each
  • 10% tax is applied
  • Two shipping options are generated (standard/express)

For production, integrate with:

  • Product catalog service
  • Tax calculation service
  • Shipping rate APIs

Security Notes

⚠️ This is a reference implementation for development and testing purposes.

For production deployment:

  1. Use secure token generation and storage
  2. Implement proper PCI DSS compliance
  3. Add rate limiting
  4. Enable TLS/HTTPS
  5. Implement request signing verification
  6. Add comprehensive logging (without PCI data)
  7. Use environment-based secrets management
  8. Implement webhook signature verification

Error Handling

The server returns flat error objects per ACP specification:

{
  "type": "invalid_request",
  "code": "invalid",
  "message": "Description of the error",
  "param": "field.name"
}

Error types:

  • invalid_request - Malformed request
  • request_not_idempotent - Idempotency conflict
  • processing_error - Server processing error
  • service_unavailable - Service temporarily unavailable

Testing

Test the API using the built-in Swagger UI at http://localhost:8000/docs

Or use the included example requests in this README with cURL.

Contributing

This is a reference implementation. For contributions to the ACP specification itself, visit: https://github.com/agentic-commerce-protocol/agentic-commerce-protocol

License

Apache 2.0 - See the ACP repository for details.

Resources

Support

For issues with this reference implementation, please check the code and documentation.

For questions about the ACP specification, visit the official repository.

About

Reference implementation of ACP server in Python using FastAPI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published