Skip to main content

Getting Started with FastAPI

Start accepting x402 payments in your FastAPI server in 2 minutes.

Example Code

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
Network Options

BlockEden.xyz supports multiple networks:

  • sui (recommended for fastest settlement)
  • ethereum
  • base
  • polygon
  • avalanche

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 FastAPI server is now accepting x402 payments!

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.

Coming Soon

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:

  1. Switch to production network (e.g., sui instead of sui-testnet)
  2. Use environment variables for all sensitive data
  3. Enable HTTPS (use a reverse proxy like nginx)
  4. Set up proper logging and monitoring
  5. Configure CORS for your production domains
  6. 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_KEY is 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 x402 package
  • 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?

Join Discord