Getting Started with FastAPI
Start accepting x402 payments in your FastAPI server in 2 minutes.
You can find the full code for this example on GitHub.
Step 1: Install Dependencies
Install the required packages for your FastAPI server:
pip install x402 fastapi uvicorn python-dotenv
Step 2: Set Your Environment Variables
Create a .env file in your project root:
echo "ADDRESS=0x...\nNETWORK=sui" > .env
Your .env file should look like this:
ADDRESS=0x... # wallet public address you want to receive payments to
NETWORK=sui # recommended for fastest settlement
# Optional: Configure facilitator URL if using custom facilitator
# FACILITATOR_URL=https://x402.blockeden.xyz
BlockEden.xyz supports multiple networks:
sui(recommended for fastest settlement)ethereumbasepolygonavalanche
Step 3: Create a New FastAPI App
Create a main.py file with the following code:
import os
from typing import Any, Dict
from dotenv import load_dotenv
from fastapi import FastAPI
from x402.fastapi.middleware import require_payment
from x402.types import TokenAmount, TokenAsset, EIP712Domain
# Load environment variables
load_dotenv()
# Get configuration from environment
ADDRESS = os.getenv("ADDRESS")
NETWORK = os.getenv("NETWORK", "sui")
if not ADDRESS:
raise ValueError("Missing required environment variables")
app = FastAPI(
title="x402 Payment Server",
description="FastAPI server with x402 payment integration",
)
# Apply payment middleware to weather route
app.middleware("http")(
require_payment(
path="/weather",
price="$0.001",
pay_to_address=ADDRESS,
network=NETWORK,
)
)
# Apply payment middleware to premium routes
app.middleware("http")(
require_payment(
path="/premium/*",
price=TokenAmount(
amount="10000",
asset=TokenAsset(
address="0x...", # USDC contract address for your network
decimals=6,
eip712=EIP712Domain(name="USDC", version="2"),
),
),
pay_to_address=ADDRESS,
network=NETWORK,
)
)
@app.get("/")
async def root() -> Dict[str, str]:
return {
"message": "x402 Payment Server",
"status": "running",
}
@app.get("/weather")
async def get_weather() -> Dict[str, Any]:
"""Get weather data - requires payment"""
return {
"report": {
"weather": "sunny",
"temperature": 70,
"location": "San Francisco",
}
}
@app.get("/premium/content")
async def get_premium_content() -> Dict[str, Any]:
"""Get premium content - requires payment"""
return {
"content": "This is premium content",
"type": "article",
"timestamp": "2025-01-01T00:00:00Z",
}
@app.get("/premium/analytics")
async def get_premium_analytics() -> Dict[str, Any]:
"""Get premium analytics - requires payment"""
return {
"analytics": {
"users": 1000,
"revenue": 50000,
"growth": 25.5,
}
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
app,
host="0.0.0.0",
port=4021,
log_level="info",
)
Step 4: Run the Server
Start your FastAPI server:
uvicorn main:app --reload
Or run directly with Python:
python main.py
Your server will be available at http://localhost:4021. You can view the interactive API docs at http://localhost:4021/docs.
Step 5: Test the Server
You can test payments against your server locally using HTTP clients like curl, Postman, or by building a Python client application.
Client implementation guides for httpx and requests libraries will be available soon.
Manual Testing with curl
# This will return a 402 Payment Required response
curl http://localhost:4021/weather
# The response will include payment details in headers
Payment Configuration Options
The require_payment middleware accepts flexible payment configurations:
Simple Dollar Amount
app.middleware("http")(
require_payment(
path="/weather",
price="$0.001",
pay_to_address=ADDRESS,
network="sui",
)
)
Token Amount with Specific Asset
from x402.types import TokenAmount, TokenAsset, EIP712Domain
app.middleware("http")(
require_payment(
path="/premium/data",
price=TokenAmount(
amount="10000",
asset=TokenAsset(
address="0x...", # Token contract address
decimals=6,
eip712=EIP712Domain(name="USDC", version="2"),
),
),
pay_to_address=ADDRESS,
network="sui",
)
)
Wildcard Routes
Protect all routes under a path:
app.middleware("http")(
require_payment(
path="/premium/*", # Matches /premium/anything
price="$0.05",
pay_to_address=ADDRESS,
network="sui",
)
)
Advanced Features
Custom Payment Verification Callback
Add custom logic when payments are verified:
# Note: Custom payment verification callbacks may vary based on
# the x402 library version. Check the official documentation for
# the exact callback mechanism supported by your version.
app.middleware("http")(
require_payment(
path="/weather",
price="$0.001",
pay_to_address=ADDRESS,
network="sui",
)
)
# You can add custom logic in your route handler after payment verification
@app.get("/weather")
async def get_weather():
# Payment has been verified if this handler is reached
# Add your custom logic here
return {"report": {"weather": "sunny", "temperature": 70}}
Error Handling
Add custom error handling:
from fastapi import Request, status
from fastapi.responses import JSONResponse
from x402.exceptions import X402PaymentError
@app.exception_handler(X402PaymentError)
async def payment_error_handler(request: Request, exc: X402PaymentError):
return JSONResponse(
status_code=status.HTTP_402_PAYMENT_REQUIRED,
content={
"error": "Payment required",
"details": str(exc),
"path": str(request.url),
},
)
CORS Configuration
Enable CORS for cross-origin requests:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000", "https://yourdomain.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Request Context Access
Access payment information in your route handlers:
from fastapi import Request
@app.get("/weather")
async def get_weather(request: Request) -> Dict[str, Any]:
# Access payment details from request state
payment_info = getattr(request.state, "x402_payment", None)
return {
"report": {"weather": "sunny", "temperature": 70},
"payment": {
"tx_hash": payment_info.tx_hash if payment_info else None,
}
}
Production Deployment
Before deploying to production:
- Switch to production network (e.g.,
suiinstead ofsui-testnet) - Use environment variables for all sensitive data
- Enable HTTPS (use a reverse proxy like nginx)
- Set up proper logging and monitoring
- Configure CORS for your production domains
- Use a production ASGI server (Gunicorn + Uvicorn)
Production Example
import os
import logging
from typing import Any, Dict
from dotenv import load_dotenv
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from x402.fastapi.middleware import require_payment
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
load_dotenv()
app = FastAPI(title="Production x402 Server")
# CORS configuration
app.add_middleware(
CORSMiddleware,
allow_origins=os.getenv("ALLOWED_ORIGINS", "").split(","),
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Payment middleware
app.middleware("http")(
require_payment(
path="/api/data",
price="$0.01",
pay_to_address=os.getenv("ADDRESS"),
network="sui", # Production Sui network
)
)
@app.get("/api/data")
async def get_data() -> Dict[str, Any]:
logger.info("Delivering protected data")
return {"data": "Protected content"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
app,
host="0.0.0.0",
port=int(os.getenv("PORT", "4021")),
workers=4, # Multiple workers for production
log_level="info",
)
Deploy with Gunicorn
For production, use Gunicorn with Uvicorn workers:
pip install gunicorn
gunicorn main:app \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:4021 \
--timeout 120
Troubleshooting
Common Issues
Payment verification fails
- Verify your
BLOCKEDEN_API_KEYis correct - Check that the wallet address format matches the network
- Ensure the facilitator URL is accessible
CORS errors
- Add CORS middleware before payment middleware
- Configure allowed origins properly
Network mismatch
- Ensure client and server use the same network
- Check that the token address is valid for the network
Module import errors
- Ensure you installed
x402package - Verify your Python version is 3.8 or higher
Port already in use
- Change the port in
uvicorn.run()configuration - Kill any existing processes:
lsof -ti:4021 | xargs kill
Why Choose FastAPI?
FastAPI is an excellent choice for x402 payment servers:
High performance: One of the fastest Python frameworks available Type safety: Built-in type hints and validation Auto documentation: Interactive API docs (Swagger/ReDoc) out of the box Modern Python: Uses async/await for concurrent requests - Easy to learn: Intuitive API similar to Flask
Next Steps
Need Help?
Join Our Community
Have questions or want to connect with other developers?