Skip to content

second-state/payment-link

Repository files navigation

Payment Link Service

A Python web service for creating x402-protected payment links. This service allows you to generate unique payment URLs that require cryptocurrency payments before granting access.

Quick Start with Docker

  1. Configure environment:
cp .env.example .env
# Edit .env with your wallet address and settings
  1. Build the image:
docker build -t payment-link .
  1. Run the container:
touch payments.db
docker run -d \
  -p 8000:8000 \
  -v $(pwd)/payments.db:/app/payments.db \
  --env-file .env \
  --name payment-link \
  payment-link

The touch command creates an empty database file, and the -v flag mounts it into the container for persistence.

  1. Verify it's running:
curl http://localhost:8000/

Configuration

Configure the service using environment variables:

Variable Default Description
NETWORK base-sepolia Blockchain network (base-sepolia for testnet, base for mainnet)
APP_BASE_URL http://localhost:8000 Public base URL for generated payment links
APP_NAME Payment Link Service Service name displayed in payment UI
APP_LOGO /static/logo.png Logo URL for payment UI
FACILITATOR_URL https://x402f1.secondstate.io x402 facilitator service endpoint
MAX_TIMEOUT_SECONDS 60 Payment timeout in seconds
DATABASE_PATH payments.db SQLite database file path

API Endpoints

GET /

Serves the web UI for creating and paying payment links.

Open in a browser to access the interactive payment interface.


GET /create-payment-link

Creates a new payment link with a unique ID.

Query Parameters:

Parameter Type Required Description
amount float Yes Payment amount in USD (must be > 0)
receiver string Yes Blockchain address to receive the payment

Example Request:

curl "http://localhost:8000/create-payment-link?amount=0.01&receiver=0x1234567890abcdef1234567890abcdef12345678"

Response:

{
  "payment_id": "550e8400-e29b-41d4-a716-446655440000",
  "payment_url": "http://localhost:8000/pay/550e8400-e29b-41d4-a716-446655440000",
  "amount": "0.01",
  "receiver": "0x1234567890abcdef1234567890abcdef12345678"
}

GET /pay/{payment_id}

x402-protected payment endpoint. This endpoint handles the payment flow.

Path Parameters:

Parameter Type Description
payment_id string Unique payment identifier from /create-payment-link

Behavior:

  1. If payment is pending (no X-Payment header): Returns HTTP 402 with payment requirements
  2. If payment is pending (with valid X-Payment header): Processes payment and returns success
  3. If payment is already completed: Returns the transaction details

Response (Payment Required - 402):

For API clients (non-browser):

{
  "x402Version": 1,
  "accepts": [...],
  "error": "No X-PAYMENT header provided"
}

For browsers: Returns an HTML payment page.

Response (Payment Successful - 200):

{
  "status": "paid",
  "tx": "0x1234567890abcdef..."
}

Response (Not Found - 404):

{
  "error": "Payment not found"
}

GET /status/{payment_id}

Check the current status of a payment.

Path Parameters:

Parameter Type Description
payment_id string Unique payment identifier

Example Request:

curl "http://localhost:8000/status/550e8400-e29b-41d4-a716-446655440000"

Response (Pending):

{
  "payment_id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 0.01,
  "paid": false,
  "tx": null
}

Response (Paid):

{
  "payment_id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 0.01,
  "paid": true,
  "tx": "0x1234567890abcdef..."
}

Response (Not Found - 404):

{
  "error": "Payment not found"
}

Usage Example

  1. Create a payment link:
curl "http://localhost:8000/create-payment-link?amount=0.01"
  1. Share the payment_url with the payer. When they open it in a browser, they'll see a payment interface.

  2. After payment, the payer can reload the page to see the confirmation with the transaction hash.

  3. Check payment status programmatically:

curl "http://localhost:8000/status/{payment_id}"

Development Setup

For local development without Docker:

  1. Install dependencies:
uv sync
  1. Configure environment:
cp .env.example .env
# Edit .env with your settings
  1. Run the server:
uv run python main.py
  1. Run tests:
uv run pytest tests/ -v

How x402 Works

The x402 protocol enables HTTP-native payments:

  1. Client requests a protected resource
  2. Server responds with HTTP 402 and payment requirements
  3. Client makes a blockchain payment and includes proof in the X-Payment header
  4. Server verifies the payment and grants access

This service uses USDC on Base (or Base Sepolia for testing) for payments.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors 2

  •  
  •