A spec-compliant implementation of the x402 payment protocol extension for python-a2a, enabling digital payments in agent-to-agent commerce.
This project implements the x402 payment protocol specification using python-a2a. It demonstrates how AI agents can autonomously negotiate and execute digital payments using EIP-3009 transfer authorization.
- MerchantServer: Extends
python_a2a.A2AServerwith x402 payment capabilities - x402PaymentMiddleware: Spec-compliant middleware handling the complete payment lifecycle
- PaymentAwareClient: Wraps
python_a2a.A2AClientfor autonomous payment handling - MockFacilitator: Test facilitator simulating blockchain payment verification and settlement
- HTTP header extension activation (Spec Section 7)
- Client sends
X-A2A-Extensionsheader with extension URI - Server echoes header in response to confirm activation
- Uses x402-a2a package helpers for header checking
- Client sends
- Metadata structure using
x402.payment.*dotted keys - Payment status values in kebab-case per spec
- x402Version field in responses
- Receipt array with full payment history tracking
- TaskId correlation for multi-turn payment flows
- Standardized error codes (
x402ErrorCodeenum) - Payment expiry validation framework
- outputSchema support in PaymentRequirements
graph TB
Server[MerchantServer<br/>extends python_a2a.A2AServer]
HandleTask[handle_task task]
Middleware[x402PaymentMiddleware]
BusinessLogic[business_logic_fn]
Server --> HandleTask
HandleTask --> Middleware
Middleware --> BusinessLogic
MiddlewareFeatures["- Catches x402PaymentRequiredException<br/>- Converts to INPUT_REQUIRED response<br/>- Verifies payment with facilitator<br/>- Settles payment on-chain<br/>- Returns COMPLETED with content"]
Middleware -.-> MiddlewareFeatures
style Server fill:#ffe1e1
style Middleware fill:#fff4e1
style MiddlewareFeatures fill:#f0f0f0
graph TB
Client[PaymentAwareClient<br/>wraps python_a2a.A2AClient]
Step1[1. Send initial request]
Step2[2. Detect PAYMENT_REQUIRED response]
Step3[3. Display payment info to user]
Step4[4. Sign payment with wallet EIP-3009]
Step5[5. Resubmit with signed payment]
Step6[6. Receive PAYMENT_COMPLETED + content]
Client --> Step1
Step1 --> Step2
Step2 --> Step3
Step3 --> Step4
Step4 --> Step5
Step5 --> Step6
style Client fill:#e1f5ff
style Step6 fill:#e1ffe1
The implementation follows the x402 spec's complete payment lifecycle:
- Client sends purchase request (e.g., "Buy a laptop")
- Server's business logic raises
x402PaymentRequiredException - Middleware sets
task.status.state = INPUT_REQUIRED - Metadata contains:
{ "x402.payment.status": "payment-required", "x402.payment.required": { "x402Version": 1, "accepts": [{ scheme, network, asset, payTo, maxAmountRequired, ... }] } }
- Client detects
payment-requiredstatus in metadata - Signs payment using EIP-3009 transfer authorization
- Resubmits task with same task ID (correlation)
- Metadata contains:
{ "x402.payment.status": "payment-submitted", "x402.payment.payload": { scheme, network, signature, ... } }
- Middleware validates payment hasn't expired (
maxTimeoutSeconds) - Facilitator verifies signature and payment authorization
- Middleware updates status to
payment-verified
- Business logic executes and generates response
- Facilitator settles payment on-chain
- Middleware appends to receipt array and sets final status:
{ "x402.payment.status": "payment-completed", "x402.payment.receipts": [{ success, network, txHash, ... }] } - Task state changes to
COMPLETEDwith artifacts
On failure, middleware sets:
{
"x402.payment.status": "payment-failed",
"x402.payment.error": "INVALID_SIGNATURE",
"x402.payment.receipts": [{ success: false, errorReason, ... }]
}See ARCHITECTURE.md for detailed sequence diagrams and function traces.
# Clone repository
git clone https://github.com/ryanRfox/python-a2a-x402.git
cd python-a2a-x402
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install all dependencies (including x402-a2a from GitHub)
pip install -r requirements.txtNote: The x402-a2a package is installed directly from GitHub as it's not available on PyPI. This is handled automatically by requirements.txt using PEP 440 direct references.
See CONTRIBUTING.md for detailed development setup.
# Run all tests (41/41 passing: 38 unit + 3 integration)
python -m pytest tests/ -v
# Run only unit tests (38/38 passing)
python -m pytest tests/unit/ -v
# Run only integration tests (3/3 passing)
python -m pytest tests/integration/ -v
# Run specific test file
python -m pytest tests/unit/test_wallet.py -v
# Run with detailed logging
python -m pytest tests/ -v -sTest Coverage:
- ✅ Unit Tests (38/38 passing):
- Wallet: EIP-3009 signing (4 tests)
- Facilitator: Verify & settle (6 tests)
- MerchantServer: Business logic & payments (5 tests)
- x402PaymentMiddleware: Payment lifecycle (5 tests)
- PaymentAwareClient: Client-side flow (10 tests)
- HTTP Headers: Extension activation (8 tests)
- ✅ Integration Tests (3/3 passing):
- Complete payment flow end-to-end
- Free service (no payment)
- HTTP header activation over real HTTP
See tests/README.md for comprehensive testing documentation.
The system uses distinct ports for different environments to avoid conflicts:
| Environment | Port | Purpose | Configuration |
|---|---|---|---|
| Production/Demo | 5001 |
Default merchant server | merchant_server.py default |
| Integration Tests | 5555 |
Test server (isolated) | tests/fixtures/server_fixtures.py |
| Unit Tests | N/A | No server runs | Tests use mocks only |
Why separate ports?
- Integration tests can run while demo server is running
- No port conflicts between test runs
- Clean separation of concerns
Terminal 1 - Start Merchant Server:
# Default port (5001)
python src/merchant_server.py
# Or specify custom port
python src/merchant_server.py --port 5001Terminal 2 - Run Client:
# Connect to default port
python src/payment_client.py --server http://localhost:5001
# Or specify custom server
python src/payment_client.py --server http://localhost:5001Terminal 3 - Run Tests (while demo runs):
python -m pytest tests/integration/ -vThen try commands like:
- "What's your status?" (free)
- "Buy a laptop" (requires payment)
python-a2a-x402/
├── src/ # Source code
│ ├── merchant_server.py # MerchantServer extending A2AServer
│ ├── x402_middleware.py # Payment middleware for python-a2a
│ ├── payment_client.py # PaymentAwareClient wrapper
│ ├── wallet.py # MockLocalWallet with EIP-3009 signing
│ └── facilitator.py # MockFacilitator for testing
├── tests/ # Test suite
│ ├── README.md # Testing documentation
│ ├── conftest.py # Global fixtures and TypeTracer
│ ├── fixtures/ # Reusable test fixtures
│ │ ├── client_fixtures.py # Wallet and client fixtures
│ │ └── server_fixtures.py # Server and facilitator fixtures
│ ├── unit/ # Unit tests (38/38 passing)
│ │ ├── test_wallet.py # Wallet signing tests
│ │ ├── test_facilitator.py # Facilitator tests
│ │ ├── test_merchant_server.py # Merchant server tests
│ │ ├── test_x402_middleware.py # Middleware tests
│ │ ├── test_payment_client.py # Client tests
│ │ └── test_http_headers.py # HTTP header activation tests
│ └── integration/ # Integration tests (3/3 passing)
│ └── test_payment_flow.py # End-to-end payment flow over HTTP
├── ARCHITECTURE.md # Technical architecture documentation
├── CONTRIBUTING.md # Development setup and workflow
├── README.md # This file
├── pytest.ini # Pytest configuration
└── requirements.txt # Python dependencies
The x402PaymentMiddleware is a separate class following the adapter pattern:
- Wraps business logic functions without modifying them
- Handles payment lifecycle orthogonally to business concerns
- Maintains spec-compliant state management
- Enables clean separation of payment and business logic
All payment state is stored in task.status.message.metadata using dotted keys:
x402.payment.status- Current payment state (kebab-case)x402.payment.required- Payment requirements withx402Versionx402.payment.payload- Signed payment authorizationx402.payment.receipts- Array of settlement results (full history)x402.payment.error- Standardized error code on failure
Helper function _get_metadata_dict() handles python-a2a's Metadata objects.
Payment submissions reuse the original task ID:
payment_task = Task(
id=task.id, # Same ID for correlation
status=TaskStatus(...)
)This enables the server to retrieve stored payment requirements.
All payment attempts (success and failure) are appended to x402.payment.receipts:
metadata["x402.payment.receipts"].append(
settle_response.model_dump(by_alias=True)
)This provides complete payment history per spec requirement.
Business logic raises x402PaymentRequiredException when payment is needed:
raise x402PaymentRequiredException(
"Payment required for laptop",
payment_requirements=[requirements]
)Middleware catches and converts to spec-compliant INPUT_REQUIRED response.
- MockLocalWallet: EIP-3009 signing with hardcoded key
⚠️ TESTING ONLY - MockFacilitator: Simulates verification/settlement
⚠️ NOT PRODUCTION-READY
- python-a2a (>=0.5.10): Python implementation of Google's A2A protocol
- x402-a2a (>=1.0.0): Upstream x402 types and constants
- eth-account (>=0.13.7): Ethereum wallet and signing
- httpx (>=0.28.1): HTTP client
- pydantic (>=2.0.0): Data validation
- pytest (>=8.0.0): Testing framework
- pytest-asyncio (>=0.23.0): Async test support
The test suite provides comprehensive coverage of core components:
✅ All Tests Passing: 41/41 (38 unit + 3 integration)
Unit Tests (38/38 passing):
-
Wallet (4 tests):
- Initialization and address validation
- EIP-3009 payment signing
- Amount validation
- Network consistency
-
Facilitator (6 tests):
- Initialization with valid/invalid flags
- Payment verification (success/failure)
- Payment settlement (success/failure)
-
MerchantServer (5 tests):
- Initialization and agent card
- Free vs paid service handling
- Payment requirement generation
- Deterministic pricing logic
-
x402PaymentMiddleware (5 tests):
- Initialization and state management
- Free service pass-through
- Payment exception catching
- Verify and settle flow
- x402 metadata structure compliance
-
PaymentAwareClient (10 tests):
- Initialization with/without wallet
- Custom fields extraction
- Payment requirement detection
- Task creation and response extraction
- Complete payment flow integration
-
HTTP Headers (8 tests):
- Extension URI constant validation
- Extension activation detection
- Client sends activation header
- Server echoes header
- Spec Section 7 compliance
Integration Tests (3/3 passing):
- Complete Payment Flow: Full end-to-end payment over HTTP with auto-approve
- Free Service Flow: Services without payment requirements
- HTTP Header Activation: Real HTTP requests with X-A2A-Extensions header
- TypeTracer: Detailed function call tracing with type information
- Fixtures: Reusable components (wallet, server, facilitator)
- Professional logging: Comprehensive execution traces
# Run all unit tests
python -m pytest tests/unit/ -v
# Run specific test file
python -m pytest tests/unit/test_wallet.py -v
# Run with detailed output
python -m pytest tests/ -v -s
# Expected output: 41 passed in 4.65sSee tests/README.md for comprehensive testing documentation.
Critical:
- Replace
MockLocalWalletwith secure key management (HSM, KMS, or secure enclave) - Integrate real payment facilitator (not
MockFacilitator) - Implement timestamp tracking for payment expiry validation
- Add rate limiting and DDoS protection
- Enable comprehensive audit logging
Recommended:
- Implement proper authentication and authorization
- Add monitoring and alerting for payment failures
- Set up disaster recovery procedures
- Conduct security audit before production deployment
- Production-grade expiry validation with timestamp tracking
- Real facilitator integration (Coinbase Commerce, Stripe Crypto)
- Enhanced testing (unit tests, negative cases, load testing)
- Performance optimizations (async operations, caching, Redis)
- Security enhancements (rate limiting, audit logging)
MIT
- README.md - This file: project overview and quick start
- ARCHITECTURE.md - Complete technical documentation:
- System component diagrams
- Payment flow sequence diagrams
- Metadata structure visualization
- State machine diagrams
- Function call traces with example data
- Error handling flowcharts
- CONTRIBUTING.md - Development setup and workflow
- tests/README.md - Testing guide and best practices
- x402 A2A Extension - Official x402 repository
- x402 Protocol Specification v0.1 - Official spec
- x402 Protocol Documentation - Protocol overview
- EIP-3009: Transfer With Authorization - Ethereum payment standard
- python-a2a - Python implementation of Google's A2A protocol (by themanojdesai)
- x402-a2a - Official x402-a2a Python package (Google/Coinbase)