Skip to main content

Universal Commerce Protocol (UCP) tools for Strands Agents. Enable agentic commerce with discovery, checkout, orders, and payment handling.

Project description

Strands UCP

Universal Commerce Protocol (UCP) tools for Strands Agents

Enable agentic commerce experiences with full UCP protocol support: discovery, checkout, orders, payments, and extensions.

PyPI version Python 3.10+ License

🚀 Features

  • 🔍 Discovery - Query merchant capabilities, services, and payment handlers
  • 🛒 Checkout - Full lifecycle management (create → update → complete)
  • 📦 Orders - Get, list, cancel, and update orders
  • 💰 Payments - Multi-handler support with automatic header management
  • 🔐 Security - Request signature support (parameter + env var)
  • 🎟️ Extensions - Discounts, fulfillment, refunds, returns, disputes
  • 🔧 Custom - Passthrough for any UCP endpoint

📦 Installation

pip install strands-ucp

🎯 Quick Start

from strands_ucp import ucp_discover, ucp_checkout_session, ucp_apply_discount, ucp_complete_checkout

# 1. Discover merchant capabilities
discovery = ucp_discover("https://shop.example.com")
handlers = discovery["body"]["payment"]["handlers"]

# 2. Create checkout session (with optional signature)
checkout = ucp_checkout_session(
    merchant_url="https://shop.example.com",
    line_items=[
        {"item": {"id": "product_123", "title": "Widget"}, "quantity": 2}
    ],
    currency="USD",
    payment_handlers=handlers,
    buyer={"full_name": "John Doe", "email": "john@example.com"},
    request_signature="eyJhbGc..."  # Optional: JWT/signed token
)

# 3. Apply discount code
checkout = ucp_apply_discount(
    merchant_url="https://shop.example.com",
    checkout_id=checkout["checkout_id"],
    discount_codes=["SAVE10"],
    current_checkout=checkout["body"]
)

# 4. Complete checkout
order = ucp_complete_checkout(
    merchant_url="https://shop.example.com",
    checkout_id=checkout["checkout_id"],
    payment_instrument={
        "type": "card",
        "handler_id": "mock_payment_handler",
        "credential": {"token": "success_token"}
    }
)

print(f"Order created: {order['order_id']}")

🔐 Security & Signatures

Request Signatures

Production UCP merchants require request signatures for security. Provide them via:

1. Function Parameter (Recommended)

ucp_checkout_session(
    merchant_url="https://shop.example.com",
    request_signature="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    # ... other params
)

2. Environment Variable

export UCP_REQUEST_SIGNATURE="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# Signature automatically loaded from env var
ucp_checkout_session(
    merchant_url="https://shop.example.com",
    # ... other params
)

Parameter takes precedence over env var. If neither is provided, the request-signature header is omitted (discovery endpoints typically don't require signatures).

Generating Signatures

Request signatures are typically JWT tokens signed with your merchant credentials:

import jwt
import time

def generate_request_signature(merchant_secret: str, request_data: dict) -> str:
    payload = {
        "iat": int(time.time()),
        "exp": int(time.time()) + 300,  # 5 min expiry
        "data": request_data
    }
    return jwt.encode(payload, merchant_secret, algorithm="HS256")

# Use in request
signature = generate_request_signature("your-secret-key", {"merchant_id": "123"})
ucp_checkout_session(..., request_signature=signature)

📚 Available Functions

Core Function

ucp(action, merchant_url, **kwargs)

Generic UCP client supporting all operations.

Actions:

  • discovery - Get merchant capabilities
  • checkout_create - Create checkout session
  • checkout_get - Get checkout session
  • checkout_update - Update checkout
  • checkout_complete - Complete checkout with payment
  • order_get - Get order details
  • order_list - List orders
  • order_cancel - Cancel order
  • order_update - Update order
  • refund_create - Create refund
  • return_create - Create return
  • dispute_create - Create dispute
  • custom - Custom endpoint access

Parameters:

  • action (str) - UCP action to perform
  • merchant_url (str) - Merchant base URL
  • method (str) - HTTP method (auto-set for standard actions)
  • endpoint (str) - Custom endpoint path
  • headers (dict) - Additional headers
  • body (dict) - Request body
  • checkout_id (str) - Checkout session ID
  • order_id (str) - Order ID
  • request_signature (str) - Request signature (JWT/token)
  • auto_headers (bool) - Auto-add UCP headers (default: True)
  • timeout (int) - Request timeout in seconds
  • follow_redirects (bool) - Follow redirects (default: True)

Helper Functions

ucp_discover(merchant_url)

Discover merchant capabilities and services.

ucp_checkout_session(merchant_url, line_items, currency, payment_handlers, buyer=None, request_signature=None)

Create a new checkout session with optional buyer info and signature.

ucp_apply_discount(merchant_url, checkout_id, discount_codes, current_checkout, request_signature=None)

Apply discount codes to checkout with optional signature.

ucp_complete_checkout(merchant_url, checkout_id, payment_instrument, risk_signals=None, request_signature=None)

Complete checkout with payment and optional signature.

🔧 Advanced Usage

Custom Requests

from strands_ucp import ucp

# Custom endpoint with signature
result = ucp(
    action="custom",
    merchant_url="https://shop.example.com",
    method="POST",
    endpoint="/api/custom-action",
    body={"custom_field": "value"},
    request_signature="eyJhbGc..."
)

Manual Header Control

from strands_ucp import ucp

result = ucp(
    action="checkout_create",
    merchant_url="https://shop.example.com",
    body={...},
    auto_headers=False,  # Disable automatic headers
    headers={
        "UCP-Agent": 'profile="https://my-agent/profile"',
        "request-id": "custom-request-id",
        "request-signature": "signed-jwt-token",
        "idempotency-key": "custom-idempotency-key"
    }
)

Order Management

from strands_ucp import ucp

# Get order
order = ucp(
    action="order_get",
    merchant_url="https://shop.example.com",
    order_id="order_abc123"
)

# Cancel order
ucp(
    action="order_cancel",
    merchant_url="https://shop.example.com",
    order_id="order_abc123",
    body={"reason": "Customer request"},
    request_signature="eyJhbGc..."
)

# Create refund
ucp(
    action="refund_create",
    merchant_url="https://shop.example.com",
    order_id="order_abc123",
    body={"amount": 2500, "reason": "Defective product"},
    request_signature="eyJhbGc..."
)

Environment-Based Configuration

# Set signature once for all requests
export UCP_REQUEST_SIGNATURE="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Optional: Set custom agent profile
export UCP_AGENT_PROFILE="https://my-company.com/agent-profile"
# Signature automatically loaded from env
from strands_ucp import ucp_checkout_session

checkout = ucp_checkout_session(
    merchant_url="https://shop.example.com",
    line_items=[...],
    currency="USD",
    payment_handlers=[...]
    # request_signature loaded from UCP_REQUEST_SIGNATURE env var
)

📖 Response Format

All functions return a dictionary with:

{
    "status": "success" | "error",
    "status_code": 200,
    "headers": {...},
    "body": {...},  # Parsed JSON response
    "ucp_metadata": {...},  # UCP metadata (when available)
    "capabilities": [...],   # Capabilities (when available)
    "checkout_id": "...",    # Checkout ID (when available)
    "order_id": "...",       # Order ID (when available)
    "request": {
        "method": "POST",
        "url": "...",
        "headers": {...},  # Note: request-signature excluded from logs
        "body": {...}
    }
}

Security Note: The request-signature header is excluded from response logs for security.

🧪 Testing

Test with the official UCP sample server:

# Clone samples
git clone https://github.com/Universal-Commerce-Protocol/samples.git
cd samples/rest/python/server

# Install and run
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py --port 8182

Then test:

from strands_ucp import ucp_discover

result = ucp_discover("http://localhost:8182")
print(result)

Testing with Signatures

The sample server may accept test signatures:

from strands_ucp import ucp_checkout_session

checkout = ucp_checkout_session(
    merchant_url="http://localhost:8182",
    line_items=[{"item": {"id": "test_item"}, "quantity": 1}],
    currency="USD",
    payment_handlers=[...],
    request_signature="test"  # Test servers may accept this
)

Production: Always use properly signed JWT tokens in production.

🔗 Protocol Details

Required Headers

Automatically added by the tool (when auto_headers=True):

  • UCP-Agent - Agent profile identifier
  • request-id - Unique request ID (UUID)
  • idempotency-key - For safe retries (POST/PUT/PATCH)
  • request-signature - Request signature (if provided via parameter or env var)

Discovery Endpoint

GET /.well-known/ucp returns:

  • UCP version
  • Supported services
  • Capabilities (checkout, order, discounts, etc.)
  • Payment handlers
  • Transport bindings (REST, MCP, A2A)

Standard Endpoints

  • Checkout: /checkout-sessions, /checkout-sessions/{id}, /checkout-sessions/{id}/complete
  • Orders: /orders, /orders/{id}, /orders/{id}/cancel
  • Extensions: /orders/{id}/refunds, /orders/{id}/returns, /orders/{id}/disputes

🌐 Resources

🤝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

Apache License 2.0 - See LICENSE file for details.

🙏 Acknowledgments

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

strands_ucp-0.1.0.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

strands_ucp-0.1.0-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file strands_ucp-0.1.0.tar.gz.

File metadata

  • Download URL: strands_ucp-0.1.0.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for strands_ucp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7755fb52c15164408625597418aecdc72c270de7f341826165a1e8a7e885decd
MD5 59346ffd1f2a530ee8a8e71fb199ed8b
BLAKE2b-256 6f5267605e3908ff2e7cb69f05d0bbd37e607d26441c5e3a296e2504ab52bb0a

See more details on using hashes here.

File details

Details for the file strands_ucp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: strands_ucp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for strands_ucp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d5712fc676b38b6fbd207534f6bd819305f45502239bf4b14658a85c152c723
MD5 bad594c5a60bdb9e5851dba84112398c
BLAKE2b-256 fd608dc6ca255fd2078e74d5deec60e773eab8135034d65c2193466f7a8b8794

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page