> ## Documentation Index
> Fetch the complete documentation index at: https://docs.x402.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart for Sellers

> This guide walks you through integrating with **x402** to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access.

**Note:** This quickstart begins with testnet configuration for safe testing. When you're ready for production, see [Running on Mainnet](#running-on-mainnet) for the simple changes needed to accept real payments on Base (EVM) and Solana networks.

### Prerequisites

Before you begin, ensure you have:

* A crypto wallet to receive funds (any EVM or SVM compatible wallet)
* [Node.js](https://nodejs.org/en) and npm, [Go](https://go.dev/), or Python and pip installed
* An existing API or server

**Note**\
There are pre-configured examples available in the x402 repo for both [Node.js](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers) and [Go](https://github.com/x402-foundation/x402/tree/main/examples/go/servers). There is also an [advanced example](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/advanced) that shows how to use the x402 SDKs to build a more complex payment flow.

### 1. Install Dependencies

<Tabs>
  <Tab title="Express">
    Install the [x402 Express middleware package](https://www.npmjs.com/package/@x402/express).

    ```bash theme={null}
    npm install @x402/express @x402/core @x402/evm @x402/svm @x402/avm
    ```
  </Tab>

  <Tab title="Next.js">
    Install the [x402 Next.js middleware package](https://www.npmjs.com/package/@x402/next).

    ```bash theme={null}
    npm install @x402/next @x402/core @x402/evm @x402/svm @x402/avm
    ```
  </Tab>

  <Tab title="Hono">
    Install the [x402 Hono middleware package](https://www.npmjs.com/package/@x402/hono).

    ```bash theme={null}
    npm install @x402/hono @x402/core @x402/evm @x402/svm @x402/avm
    ```
  </Tab>

  <Tab title="Fastify">
    Install the [x402 Fastify middleware package](https://www.npmjs.com/package/@x402/fastify).

    ```bash theme={null}
    npm install @x402/fastify @x402/core @x402/evm @x402/svm @x402/avm
    ```
  </Tab>

  <Tab title="Go (Gin)">
    Add the x402 Go module to your project:

    ```bash theme={null}
    go get github.com/x402-foundation/x402/go
    ```
  </Tab>

  <Tab title="Go (Echo)">
    Add the x402 Go module to your project:

    ```bash theme={null}
    go get github.com/x402-foundation/x402/go
    ```
  </Tab>

  <Tab title="FastAPI">
    [Install the x402 Python package](https://pypi.org/project/x402/) with FastAPI support:

    ```bash theme={null}
    pip install "x402[fastapi]"

    # For Solana support, also add:
    pip install "x402[svm]"
    ```
  </Tab>

  <Tab title="Flask">
    [Install the x402 Python package](https://pypi.org/project/x402/) with Flask support:

    ```bash theme={null}
    pip install "x402[flask]"

    # For Solana support, also add:
    pip install "x402[svm]"
    ```
  </Tab>
</Tabs>

### 2. Add Payment Middleware

Integrate the payment middleware into your application. You will need to provide:

* The Facilitator URL or facilitator client. For testing, use `https://x402.org/facilitator` which works on Base Sepolia and Solana devnet.
  * For mainnet setup, see [Running on Mainnet](#running-on-mainnet)
* The routes you want to protect.
* Your receiving wallet address.

<Tabs>
  <Tab title="Express">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/express).

    ```typescript theme={null}
    import express from "express";
    import { paymentMiddleware, x402ResourceServer } from "@x402/express";
    import { ExactEvmScheme } from "@x402/evm/exact/server";
    import { ExactSvmScheme } from "@x402/svm/exact/server";
    import { ExactAvmScheme } from "@x402/avm/exact/server";
    import { HTTPFacilitatorClient } from "@x402/core/server";

    const app = express();

    // Your receiving wallet addresses
    const evmAddress = "0xYourEvmAddress";
    const svmAddress = "YourSolanaAddress";
    const avmAddress = "YourAlgorandAddress";

    // Create facilitator client (testnet)
    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://x402.org/facilitator"
    });

    app.use(
      paymentMiddleware(
        {
          "GET /weather": {
            accepts: [
              {
                scheme: "exact",
                price: "$0.001",
                network: "eip155:84532", // Base Sepolia
                payTo: evmAddress,
              },
              {
                scheme: "exact",
                price: "$0.001",
                network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", // Solana Devnet
                payTo: svmAddress,
              },
              {
                scheme: "exact",
                price: "$0.001",
                network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=", // Algorand Testnet
                payTo: avmAddress,
              },
            ],
            description: "Weather data",
            mimeType: "application/json",
          },
        },
        new x402ResourceServer(facilitatorClient)
          .register("eip155:84532", new ExactEvmScheme())
          .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme())
          .register("algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=", new ExactAvmScheme()),
      ),
    );

    app.get("/weather", (req, res) => {
      res.send({
        report: {
          weather: "sunny",
          temperature: 70,
        },
      });
    });

    app.listen(4021, () => {
      console.log(`Server listening at http://localhost:4021`);
    });
    ```
  </Tab>

  <Tab title="Next.js">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/fullstack/next).

    Next.js offers two approaches: `paymentProxy` for protecting page routes (or multiple routes at once), and `withX402` for wrapping individual API route handlers. The key difference is that `withX402` only settles payment after a successful response (status \< 400), making it the recommended approach for API routes.

    **Option A: `paymentProxy`** — best for page routes or protecting multiple routes with a single config:

    ```typescript theme={null}
    // proxy.ts
    import { paymentProxy } from "@x402/next";
    import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
    import { ExactEvmScheme } from "@x402/evm/exact/server";
    import { ExactSvmScheme } from "@x402/svm/exact/server";

    export const evmAddress = "0xYourEvmAddress";
    export const svmAddress = "YourSolanaAddress";

    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://x402.org/facilitator"
    });

    export const server = new x402ResourceServer(facilitatorClient);
    server.register("eip155:*", new ExactEvmScheme());
    server.register("solana:*", new ExactSvmScheme());

    export const proxy = paymentProxy(
      {
        "/protected": {
          accepts: [
            {
              scheme: "exact",
              price: "$0.001",
              network: "eip155:84532", // Base Sepolia
              payTo: evmAddress,
            },
            {
              scheme: "exact",
              price: "$0.001",
              network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", // Solana Devnet
              payTo: svmAddress,
            },
          ],
          description: "Premium content",
          mimeType: "text/html",
        },
      },
      server,
    );

    export const config = {
      matcher: ["/protected/:path*"],
    };
    ```

    **Option B: `withX402`** — recommended for API routes, settles payment only after a successful response:

    ```typescript theme={null}
    // app/api/weather/route.ts
    import { NextRequest, NextResponse } from "next/server";
    import { withX402 } from "@x402/next";
    import { server, evmAddress, svmAddress } from "../../../proxy";

    const handler = async (_: NextRequest) => {
      return NextResponse.json(
        {
          report: {
            weather: "sunny",
            temperature: 72,
          },
        },
        { status: 200 },
      );
    };

    export const GET = withX402(
      handler,
      {
        accepts: [
          {
            scheme: "exact",
            price: "$0.001",
            network: "eip155:84532", // Base Sepolia
            payTo: evmAddress,
          },
          {
            scheme: "exact",
            price: "$0.001",
            network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", // Solana Devnet
            payTo: svmAddress,
          },
        ],
        description: "Access to weather API",
        mimeType: "application/json",
      },
      server,
    );
    ```
  </Tab>

  <Tab title="Hono">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/hono).

    ```typescript theme={null}
    import { Hono } from "hono";
    import { serve } from "@hono/node-server";
    import { paymentMiddleware, x402ResourceServer } from "@x402/hono";
    import { ExactEvmScheme } from "@x402/evm/exact/server";
    import { ExactSvmScheme } from "@x402/svm/exact/server";
    import { HTTPFacilitatorClient } from "@x402/core/server";

    const app = new Hono();
    const evmAddress = "0xYourEvmAddress";
    const svmAddress = "YourSolanaAddress";

    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://x402.org/facilitator"
    });

    app.use(
      paymentMiddleware(
        {
          "GET /weather": {
            accepts: [
              {
                scheme: "exact",
                price: "$0.001",
                network: "eip155:84532", // Base Sepolia
                payTo: evmAddress,
              },
              {
                scheme: "exact",
                price: "$0.001",
                network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", // Solana Devnet
                payTo: svmAddress,
              },
            ],
            description: "Weather data",
            mimeType: "application/json",
          },
        },
        new x402ResourceServer(facilitatorClient)
          .register("eip155:84532", new ExactEvmScheme())
          .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()),
      ),
    );

    app.get("/weather", (c) => {
      return c.json({
        report: {
          weather: "sunny",
          temperature: 70,
        },
      });
    });

    serve({ fetch: app.fetch, port: 4021 });
    ```
  </Tab>

  <Tab title="Fastify">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/fastify).

    ```typescript theme={null}
    import Fastify from "fastify";
    import { paymentMiddleware, x402ResourceServer } from "@x402/fastify";
    import { ExactEvmScheme } from "@x402/evm/exact/server";
    import { ExactSvmScheme } from "@x402/svm/exact/server";
    import { HTTPFacilitatorClient } from "@x402/core/server";

    const app = Fastify();
    const evmAddress = "0xYourEvmAddress";
    const svmAddress = "YourSolanaAddress";

    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://x402.org/facilitator"
    });

    paymentMiddleware(
      app,
      {
        "GET /weather": {
          accepts: [
            {
              scheme: "exact",
              price: "$0.001",
              network: "eip155:84532", // Base Sepolia
              payTo: evmAddress,
            },
            {
              scheme: "exact",
              price: "$0.001",
              network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", // Solana Devnet
              payTo: svmAddress,
            },
          ],
          description: "Weather data",
          mimeType: "application/json",
        },
      },
      new x402ResourceServer(facilitatorClient)
        .register("eip155:84532", new ExactEvmScheme())
        .register("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", new ExactSvmScheme()),
    );

    app.get("/weather", async () => {
      return {
        report: {
          weather: "sunny",
          temperature: 70,
        },
      };
    });

    app.listen({ port: 4021 });
    ```
  </Tab>

  <Tab title="Go (Gin)">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/go/servers/gin).

    ```go theme={null}
    package main

    import (
        "net/http"
        "time"

        x402 "github.com/x402-foundation/x402/go"
        x402http "github.com/x402-foundation/x402/go/http"
        ginmw "github.com/x402-foundation/x402/go/http/gin"
        evm "github.com/x402-foundation/x402/go/mechanisms/evm/exact/server"
        svm "github.com/x402-foundation/x402/go/mechanisms/svm/exact/server"
        "github.com/gin-gonic/gin"
    )

    func main() {
        evmAddress := "0xYourEvmAddress"
        svmAddress := "YourSolanaAddress"
        evmNetwork := x402.Network("eip155:84532")                              // Base Sepolia
        svmNetwork := x402.Network("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1")  // Solana Devnet

        r := gin.Default()

        // Create facilitator client
        facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
            URL: "https://x402.org/facilitator",
        })

        // Apply x402 payment middleware
        r.Use(ginmw.X402Payment(ginmw.Config{
            Routes: x402http.RoutesConfig{
                "GET /weather": {
                    Accepts: x402http.PaymentOptions{
                        {
                            Scheme:  "exact",
                            Price:   "$0.001",
                            Network: "eip155:84532",
                            PayTo:   evmAddress,
                        },
                        {
                            Scheme:  "exact",
                            Price:   "$0.001",
                            Network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
                            PayTo:   svmAddress,
                        },
                    },
                    Description: "Get weather data for a city",
                    MimeType:    "application/json",
                },
            },
            Facilitator: facilitatorClient,
            Schemes: []ginmw.SchemeConfig{
                {Network: evmNetwork, Server: evm.NewExactEvmScheme()},
                {Network: svmNetwork, Server: svm.NewExactSvmScheme()},
            },
            Timeout: 30 * time.Second,
        }))

        // Protected endpoint
        r.GET("/weather", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{
                "weather":     "sunny",
                "temperature": 70,
            })
        })

        r.Run(":4021")
    }
    ```
  </Tab>

  <Tab title="Go (net/http)">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/go/servers/nethttp).

    ```go theme={null}
    package main

    import (
        "encoding/json"
        "net/http"
        "time"

        x402 "github.com/x402-foundation/x402/go"
        x402http "github.com/x402-foundation/x402/go/http"
        nethttpmw "github.com/x402-foundation/x402/go/http/nethttp"
        evm "github.com/x402-foundation/x402/go/mechanisms/evm/exact/server"
        svm "github.com/x402-foundation/x402/go/mechanisms/svm/exact/server"
    )

    func main() {
        evmAddress := "0xYourEvmAddress"
        svmAddress := "YourSolanaAddress"
        evmNetwork := x402.Network("eip155:84532")                              // Base Sepolia
        svmNetwork := x402.Network("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1")  // Solana Devnet

        // Create facilitator client
        facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
            URL: "https://x402.org/facilitator",
        })

        // Configure routes
        routes := x402http.RoutesConfig{
            "GET /weather": {
                Accepts: x402http.PaymentOptions{
                    {
                        Scheme:  "exact",
                        Price:   "$0.001",
                        Network: "eip155:84532",
                        PayTo:   evmAddress,
                    },
                    {
                        Scheme:  "exact",
                        Price:   "$0.001",
                        Network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
                        PayTo:   svmAddress,
                    },
                },
                Description: "Get weather data for a city",
                MimeType:    "application/json",
            },
        }

        // Create ServeMux and register handlers
        mux := http.NewServeMux()

        // Protected endpoint
        mux.HandleFunc("GET /weather", func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Content-Type", "application/json")
            w.WriteHeader(http.StatusOK)
            json.NewEncoder(w).Encode(map[string]interface{}{
                "weather":     "sunny",
                "temperature": 70,
            })
        })

        // Apply x402 payment middleware
        handler := nethttpmw.X402Payment(nethttpmw.Config{
            Routes:      routes,
            Facilitator: facilitatorClient,
            Schemes: []nethttpmw.SchemeConfig{
                {Network: evmNetwork, Server: evm.NewExactEvmScheme()},
                {Network: svmNetwork, Server: svm.NewExactSvmScheme()},
            },
            Timeout: 30 * time.Second,
        })(mux)

        http.ListenAndServe(":4021", handler)
    }
    ```
  </Tab>

  <Tab title="Go (Echo)">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/go/servers/echo).

    ```go theme={null}
    package main

    import (
        "net/http"
        "time"

        x402 "github.com/x402-foundation/x402/go"
        x402http "github.com/x402-foundation/x402/go/http"
        echomw "github.com/x402-foundation/x402/go/http/echo"
        evm "github.com/x402-foundation/x402/go/mechanisms/evm/exact/server"
        svm "github.com/x402-foundation/x402/go/mechanisms/svm/exact/server"
        "github.com/labstack/echo/v4"
    )

    func main() {
        evmAddress := "0xYourEvmAddress"
        svmAddress := "YourSolanaAddress"
        evmNetwork := x402.Network("eip155:84532")                              // Base Sepolia
        svmNetwork := x402.Network("solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1")  // Solana Devnet

        e := echo.New()

        // Create facilitator client
        facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
            URL: "https://x402.org/facilitator",
        })

        // Apply x402 payment middleware
        e.Use(echomw.X402Payment(echomw.Config{
            Routes: x402http.RoutesConfig{
                "GET /weather": {
                    Accepts: x402http.PaymentOptions{
                        {
                            Scheme:  "exact",
                            Price:   "$0.001",
                            Network: "eip155:84532",
                            PayTo:   evmAddress,
                        },
                        {
                            Scheme:  "exact",
                            Price:   "$0.001",
                            Network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
                            PayTo:   svmAddress,
                        },
                    },
                    Description: "Get weather data for a city",
                    MimeType:    "application/json",
                },
            },
            Facilitator: facilitatorClient,
            Schemes: []echomw.SchemeConfig{
                {Network: evmNetwork, Server: evm.NewExactEvmScheme()},
                {Network: svmNetwork, Server: svm.NewExactSvmScheme()},
            },
            Timeout: 30 * time.Second,
        }))

        // Protected endpoint
        e.GET("/weather", func(c echo.Context) error {
            return c.JSON(http.StatusOK, map[string]interface{}{
                "weather":     "sunny",
                "temperature": 70,
            })
        })

        e.Start(":4021")
    }
    ```
  </Tab>

  <Tab title="FastAPI">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/python/servers/fastapi).

    ```python theme={null}
    from typing import Any

    from fastapi import FastAPI

    from x402.http import FacilitatorConfig, HTTPFacilitatorClient, PaymentOption
    from x402.http.middleware.fastapi import PaymentMiddlewareASGI
    from x402.http.types import RouteConfig
    from x402.mechanisms.evm.exact import ExactEvmServerScheme
    from x402.mechanisms.svm.exact import ExactSvmServerScheme
    from x402.schemas import Network
    from x402.server import x402ResourceServer

    app = FastAPI()

    # Your receiving wallet addresses
    evm_address = "0xYourEvmAddress"
    svm_address = "YourSolanaAddress"
    EVM_NETWORK: Network = "eip155:84532"  # Base Sepolia
    SVM_NETWORK: Network = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"  # Solana Devnet

    # Create facilitator client (testnet)
    facilitator = HTTPFacilitatorClient(
        FacilitatorConfig(url="https://x402.org/facilitator")
    )

    # Create resource server and register schemes
    server = x402ResourceServer(facilitator)
    server.register(EVM_NETWORK, ExactEvmServerScheme())
    server.register(SVM_NETWORK, ExactSvmServerScheme())

    # Define protected routes
    routes: dict[str, RouteConfig] = {
        "GET /weather": RouteConfig(
            accepts=[
                PaymentOption(
                    scheme="exact",
                    pay_to=evm_address,
                    price="$0.001",
                    network=EVM_NETWORK,
                ),
                PaymentOption(
                    scheme="exact",
                    pay_to=svm_address,
                    price="$0.001",
                    network=SVM_NETWORK,
                ),
            ],
            mime_type="application/json",
            description="Weather report",
        ),
    }

    # Add payment middleware
    app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)


    @app.get("/weather")
    async def get_weather() -> dict[str, Any]:
        return {
            "report": {
                "weather": "sunny",
                "temperature": 70,
            }
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=4021)
    ```
  </Tab>

  <Tab title="Flask">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/python/servers/flask).

    ```python theme={null}
    from flask import Flask, jsonify

    from x402.http import FacilitatorConfig, HTTPFacilitatorClientSync, PaymentOption
    from x402.http.middleware.flask import payment_middleware
    from x402.http.types import RouteConfig
    from x402.mechanisms.evm.exact import ExactEvmServerScheme
    from x402.mechanisms.svm.exact import ExactSvmServerScheme
    from x402.schemas import Network
    from x402.server import x402ResourceServerSync

    app = Flask(__name__)

    # Your receiving wallet addresses
    evm_address = "0xYourEvmAddress"
    svm_address = "YourSolanaAddress"
    EVM_NETWORK: Network = "eip155:84532"  # Base Sepolia
    SVM_NETWORK: Network = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"  # Solana Devnet

    facilitator = HTTPFacilitatorClientSync(
        FacilitatorConfig(url="https://x402.org/facilitator")
    )

    server = x402ResourceServerSync(facilitator)
    server.register(EVM_NETWORK, ExactEvmServerScheme())
    server.register(SVM_NETWORK, ExactSvmServerScheme())

    routes: dict[str, RouteConfig] = {
        "GET /weather": RouteConfig(
            accepts=[
                PaymentOption(
                    scheme="exact",
                    pay_to=evm_address,
                    price="$0.001",
                    network=EVM_NETWORK,
                ),
                PaymentOption(
                    scheme="exact",
                    pay_to=svm_address,
                    price="$0.001",
                    network=SVM_NETWORK,
                ),
            ],
            mime_type="application/json",
            description="Weather report",
        ),
    }

    payment_middleware(app, routes=routes, server=server)


    @app.route("/weather")
    def get_weather():
        return jsonify({
            "report": {
                "weather": "sunny",
                "temperature": 70,
            }
        })


    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=4021)
    ```
  </Tab>
</Tabs>

**Route Configuration Interface:**

```typescript theme={null}
interface RouteConfig {
  accepts: Array<{
    scheme: string;           // Payment scheme: "exact" or "upto"
    price: string;            // For "exact": the fixed price. For "upto": the maximum authorized amount.
    network: string;          // Network in CAIP-2 format (e.g., "eip155:84532" or "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1")
    payTo: string;            // Your wallet address
  }>;
  description?: string;       // Description of the resource
  mimeType?: string;          // MIME type of the response
  extensions?: object;        // Optional extensions (e.g., Bazaar)
}
```

When a request is made to these routes without payment, your server will respond with the HTTP 402 Payment Required code and payment instructions.

### Payment Schemes: Exact vs Upto

x402 supports two payment schemes that control how charges are calculated:

**`exact`** (default) — The client pays the exact advertised price. This is the simplest scheme and works across all networks (EVM, SVM, Stellar, Aptos) and all SDKs (TypeScript, Go, Python). Best for fixed-price endpoints where the cost is known upfront.

**`upto`** — The client authorizes a **maximum** amount, but the server settles **only what was actually used**. This enables usage-based billing where the final charge depends on work performed (LLM token count, compute time, bytes served, etc.). Currently available on EVM networks only (Permit2), in TypeScript, Go, and Python SDKs.

The examples in step 2 above all use the `exact` scheme. To use `upto` instead, there are two key differences:

1. Set `scheme: "upto"` in your route config, where `price` becomes the **maximum** the client authorizes
2. Call `setSettlementOverrides` in your handler to specify the **actual** amount to charge

<Tabs>
  <Tab title="Express">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/upto).

    ```typescript theme={null}
    import express from "express";
    import { paymentMiddleware, setSettlementOverrides, x402ResourceServer } from "@x402/express";
    import { UptoEvmScheme } from "@x402/evm/upto/server";
    import { HTTPFacilitatorClient } from "@x402/core/server";

    const app = express();
    const evmAddress = "0xYourEvmAddress";

    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://x402.org/facilitator"
    });

    const maxPrice = "$0.10"; // Maximum the client authorizes (10 cents)

    app.use(
      paymentMiddleware(
        {
          "GET /api/generate": {
            accepts: {
              scheme: "upto",
              price: maxPrice,
              network: "eip155:84532", // Base Sepolia
              payTo: evmAddress,
            },
            description: "AI text generation — billed by token usage",
            mimeType: "application/json",
          },
        },
        new x402ResourceServer(facilitatorClient)
          .register("eip155:84532", new UptoEvmScheme()),
      ),
    );

    app.get("/api/generate", (req, res) => {
      // Simulate variable-cost work (LLM tokens, compute time, etc.)
      const maxAmountAtomic = 100000; // 10 cents in 6-decimal USDC atomic units
      const actualUsage = Math.floor(Math.random() * (maxAmountAtomic + 1));

      // Settle only the actual usage — the client is never charged more than this
      setSettlementOverrides(res, { amount: String(actualUsage) });

      res.json({
        result: "Here is your generated text...",
        usage: {
          authorizedMaxAtomic: String(maxAmountAtomic),
          actualChargedAtomic: String(actualUsage),
        },
      });
    });

    app.listen(4021, () => {
      console.log("Server listening at http://localhost:4021");
    });
    ```
  </Tab>

  <Tab title="Go (Gin)">
    Full example in the repo [here](https://github.com/x402-foundation/x402/tree/main/examples/go/servers/upto).

    ```go theme={null}
    package main

    import (
        "fmt"
        "math/rand"
        "net/http"
        "time"

        x402 "github.com/x402-foundation/x402/go"
        x402http "github.com/x402-foundation/x402/go/http"
        ginmw "github.com/x402-foundation/x402/go/http/gin"
        uptoevm "github.com/x402-foundation/x402/go/mechanisms/evm/upto/server"
        "github.com/gin-gonic/gin"
    )

    func main() {
        evmAddress := "0xYourEvmAddress"
        evmNetwork := x402.Network("eip155:84532") // Base Sepolia

        r := gin.Default()

        facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
            URL: "https://x402.org/facilitator",
        })

        maxPrice := "$0.10" // Maximum the client authorizes

        r.Use(ginmw.X402Payment(ginmw.Config{
            Routes: x402http.RoutesConfig{
                "GET /api/generate": {
                    Accepts: x402http.PaymentOptions{
                        {
                            Scheme:  "upto",
                            Price:   maxPrice,
                            Network: evmNetwork,
                            PayTo:   evmAddress,
                        },
                    },
                    Description: "AI text generation - billed by token usage",
                    MimeType:    "application/json",
                },
            },
            Facilitator: facilitatorClient,
            Schemes: []ginmw.SchemeConfig{
                {Network: evmNetwork, Server: uptoevm.NewUptoEvmScheme()},
            },
            Timeout: 30 * time.Second,
        }))

        r.GET("/api/generate", func(c *gin.Context) {
            // Simulate variable-cost work (LLM tokens, compute time, etc.)
            maxAmountAtomic := 100000 // 10 cents in 6-decimal USDC atomic units
            actualUsage := rand.Intn(maxAmountAtomic + 1)

            // Settle only the actual usage
            ginmw.SetSettlementOverrides(c, &x402.SettlementOverrides{
                Amount: fmt.Sprintf("%d", actualUsage),
            })

            c.JSON(http.StatusOK, gin.H{
                "result": "Here is your generated text...",
                "usage": gin.H{
                    "authorizedMaxAtomic": fmt.Sprintf("%d", maxAmountAtomic),
                    "actualChargedAtomic": fmt.Sprintf("%d", actualUsage),
                },
            })
        })

        r.Run(":4021")
    }
    ```
  </Tab>

  <Tab title="FastAPI">
    ```python theme={null}
    import random
    from typing import Any

    from fastapi import FastAPI
    from starlette.responses import Response

    from x402.http import FacilitatorConfig, HTTPFacilitatorClient, PaymentOption
    from x402.http.middleware.fastapi import PaymentMiddlewareASGI, set_settlement_overrides
    from x402.http.types import RouteConfig
    from x402.mechanisms.evm.upto import UptoEvmServerScheme
    from x402.schemas import Network
    from x402.server import x402ResourceServer

    app = FastAPI()

    evm_address = "0xYourEvmAddress"
    EVM_NETWORK: Network = "eip155:84532"  # Base Sepolia

    facilitator = HTTPFacilitatorClient(
        FacilitatorConfig(url="https://x402.org/facilitator")
    )

    server = x402ResourceServer(facilitator)
    server.register(EVM_NETWORK, UptoEvmServerScheme())

    max_price = "$0.10"  # Maximum the client authorizes (10 cents)

    routes: dict[str, RouteConfig] = {
        "GET /api/generate": RouteConfig(
            accepts=[
                PaymentOption(
                    scheme="upto",
                    pay_to=evm_address,
                    price=max_price,
                    network=EVM_NETWORK,
                ),
            ],
            mime_type="application/json",
            description="AI text generation — billed by token usage",
        ),
    }

    app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)


    @app.get("/api/generate")
    async def generate(response: Response) -> dict[str, Any]:
        # Simulate variable-cost work (LLM tokens, compute time, etc.)
        max_amount_atomic = 100000  # 10 cents in 6-decimal USDC atomic units
        actual_usage = random.randint(0, max_amount_atomic)

        # Settle only the actual usage — the client is never charged more than this
        set_settlement_overrides(response, {"amount": str(actual_usage)})

        return {
            "result": "Here is your generated text...",
            "usage": {
                "authorizedMaxAtomic": str(max_amount_atomic),
                "actualChargedAtomic": str(actual_usage),
            },
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=4021)
    ```
  </Tab>
</Tabs>

The `setSettlementOverrides` amount supports three formats:

* **Raw atomic units** — e.g., `"1000"` settles exactly 1,000 atomic units of the token (for USDC with 6 decimals, `"1000"` = \$0.001)
* **Percentage of authorized maximum** — e.g., `"50%"` settles 50% of `PaymentRequirements.amount`. Supports up to two decimal places (e.g., `"33.33%"`). The result is floored to the nearest atomic unit.
* **Dollar price** — e.g., `"$0.05"` converts a USD-denominated price to atomic units. This format works when you configured your route with `$`-prefixed pricing (e.g., `price: "$0.10"`). Token decimals are determined from the registered scheme. The result is rounded to the nearest atomic unit.

The resolved amount must always be \<= the authorized maximum. If the amount is `"0"`, no on-chain transaction occurs and the client is not charged.

### 3. Test Your Integration

To verify:

1. Make a request to your endpoint (e.g., `curl http://localhost:4021/weather`).
2. The server responds with a 402 Payment Required, including payment instructions in the `PAYMENT-REQUIRED` header.
3. Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the [Quickstart for Buyers](/getting-started/quickstart-for-buyers).
4. Retry the request, this time including the `PAYMENT-SIGNATURE` header containing the cryptographic proof of payment.
5. The server verifies the payment via the facilitator and, if valid, returns your actual API response (e.g., `{ "data": "Your paid API response." }`).

### 4. Enhance Discovery with Metadata (Recommended)

When using a facilitator that supports the Bazaar extension, your endpoints can be listed in the [x402 Bazaar](/extensions/bazaar), the discovery layer that helps buyers and AI agents find services.

**For HTTP endpoints**, add the discovery extension to your route config:

```typescript theme={null}
import { declareDiscoveryExtension } from "@x402/extensions/bazaar";

{
  "GET /weather": {
    accepts: [{ scheme: "exact", price: "$0.001", network: "eip155:8453", payTo: "0xYourAddress" }],
    description: "Get real-time weather data including temperature, conditions, and humidity",
    mimeType: "application/json",
    extensions: {
      ...declareDiscoveryExtension({
        input: { city: "San Francisco" },
        inputSchema: {
          properties: { city: { type: "string", description: "City name" } },
          required: ["city"],
        },
      }),
    },
  },
}
```

**For MCP tools**, pass the discovery extension in your payment wrapper config:

```typescript theme={null}
import { createPaymentWrapper } from "@x402/mcp";
import { declareDiscoveryExtension } from "@x402/extensions/bazaar";

const paid = createPaymentWrapper(resourceServer, {
  accepts,
  resource: { url: "mcp://tool/get_weather", description: "Get current weather for a city" },
  extensions: declareDiscoveryExtension({
    toolName: "get_weather",
    description: "Get current weather for a city",
    transport: "sse",
    inputSchema: {
      properties: { city: { type: "string", description: "City name" } },
      required: ["city"],
    },
  }),
});
```

Learn more about the discovery layer in the [Bazaar documentation](/extensions/bazaar).

### 5. Error Handling

* If you run into trouble, check out the examples in the [repo](https://github.com/x402-foundation/x402/tree/main/examples) for more context and full code.
* Run `npm install` or `go mod tidy` to install dependencies

***

## Running on Mainnet

Once you've tested your integration on testnet, you're ready to accept real payments on mainnet.

### 1. Update the Facilitator URL

For mainnet, use a production facilitator. See the [x402 Ecosystem](https://www.x402.org/ecosystem?filter=facilitators) for available options. Example using one facilitator:

<Tabs>
  <Tab title="Node.js">
    ```typescript theme={null}
    const facilitatorClient = new HTTPFacilitatorClient({
      url: "https://api.cdp.coinbase.com/platform/v2/x402"
      // url: "https://facilitator.payai.network"  // PayAI Facilitator
    });
    ```
  </Tab>

  <Tab title="Go (Gin)">
    ```go theme={null}
    facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
        URL: "https://api.cdp.coinbase.com/platform/v2/x402",
        // URL: "https://facilitator.payai.network",  // PayAI Facilitator
    })
    ```
  </Tab>

  <Tab title="Go (Echo)">
    ```go theme={null}
    facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
        URL: "https://api.cdp.coinbase.com/platform/v2/x402",
        // URL: "https://facilitator.payai.network",  // PayAI Facilitator
    })
    ```
  </Tab>

  <Tab title="Python (FastAPI)">
    ```python theme={null}
    from x402.http import FacilitatorConfig, HTTPFacilitatorClient

    facilitator = HTTPFacilitatorClient(
        FacilitatorConfig(url="https://api.cdp.coinbase.com/platform/v2/x402")
        #FacilitatorConfig(url="https://facilitator.payai.network")  # PayAI Facilitator
    )
    ```
  </Tab>

  <Tab title="Python (Flask)">
    ```python theme={null}
    from x402.http import FacilitatorConfig, HTTPFacilitatorClientSync

    facilitator = HTTPFacilitatorClientSync(
        FacilitatorConfig(url="https://api.cdp.coinbase.com/platform/v2/x402")
        #FacilitatorConfig(url="https://facilitator.payai.network")  # PayAI Facilitator
    )
    ```
  </Tab>
</Tabs>

### 2. Update Your Network Identifier

Change from testnet to mainnet network identifiers:

<Tabs>
  <Tab title="Base Mainnet">
    ```typescript theme={null}
    // Testnet → Mainnet
    network: "eip155:8453", // Base mainnet (was eip155:84532)
    ```
  </Tab>

  <Tab title="Solana Mainnet">
    ```typescript theme={null}
    // Testnet → Mainnet
    network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet

    // For Solana, use a Solana wallet address (base58 format)
    payTo: "YourSolanaWalletAddress",
    ```
  </Tab>

  <Tab title="Multi-Network">
    ```typescript theme={null}
    // Support multiple networks on the same endpoint
    {
      "GET /weather": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.001",
            network: "eip155:8453",  // Base mainnet
            payTo: "0xYourEvmAddress",
          },
          {
            scheme: "exact",
            price: "$0.001",
            network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",  // Solana mainnet
            payTo: "YourSolanaAddress",
          },
        ],
        description: "Weather data",
      },
    }
    ```
  </Tab>
</Tabs>

### 3. Register Multiple Schemes (Multi-Network)

For multi-network support, register both EVM and SVM schemes:

<Tabs>
  <Tab title="Express / Hono / Fastify">
    ```typescript theme={null}
    import { ExactEvmScheme } from "@x402/evm/exact/server";
    import { ExactSvmScheme } from "@x402/svm/exact/server";

    const server = new x402ResourceServer(facilitatorClient);
    server.register("eip155:*", new ExactEvmScheme());
    server.register("solana:*", new ExactSvmScheme());
    ```
  </Tab>

  <Tab title="Go (Gin)">
    ```go theme={null}
    import (
        evm "github.com/x402-foundation/x402/go/mechanisms/evm/exact/server"
        svm "github.com/x402-foundation/x402/go/mechanisms/svm/exact/server"
    )

    r.Use(ginmw.X402Payment(ginmw.Config{
        // ...
        Schemes: []ginmw.SchemeConfig{
            {Network: x402.Network("eip155:8453"), Server: evm.NewExactEvmScheme()},
            {Network: x402.Network("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"), Server: svm.NewExactSvmScheme()},
        },
    }))
    ```
  </Tab>

  <Tab title="Go (Echo)">
    ```go theme={null}
    import (
        evm "github.com/x402-foundation/x402/go/mechanisms/evm/exact/server"
        svm "github.com/x402-foundation/x402/go/mechanisms/svm/exact/server"
    )

    e.Use(echomw.X402Payment(echomw.Config{
        // ...
        Schemes: []echomw.SchemeConfig{
            {Network: x402.Network("eip155:8453"), Server: evm.NewExactEvmScheme()},
            {Network: x402.Network("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"), Server: svm.NewExactSvmScheme()},
        },
    }))
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from x402.mechanisms.evm.exact import ExactEvmServerScheme
    from x402.mechanisms.svm.exact import ExactSvmServerScheme
    from x402.server import x402ResourceServer

    server = x402ResourceServer(facilitator)
    server.register("eip155:8453", ExactEvmServerScheme())  # Base mainnet
    server.register("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", ExactSvmServerScheme())  # Solana mainnet
    ```
  </Tab>
</Tabs>

### 4. Update Your Wallet

Make sure your receiving wallet address is a real mainnet address where you want to receive USDC payments.

### 5. Test with Real Payments

Before going live:

1. Test with small amounts first
2. Verify payments are arriving in your wallet
3. Monitor the facilitator for any issues

**Warning:** Mainnet transactions involve real money. Always test thoroughly on testnet first and start with small amounts on mainnet.

***

## Network Identifiers (CAIP-2)

x402 v2 uses [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) format for network identifiers:

| Network        | CAIP-2 Identifier                         |
| -------------- | ----------------------------------------- |
| Base Mainnet   | `eip155:8453`                             |
| Base Sepolia   | `eip155:84532`                            |
| Solana Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` |
| Solana Devnet  | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` |

See [Network Support](/core-concepts/network-and-token-support) for the full list.

***

### Next Steps

* Check out the [Advanced Example](https://github.com/x402-foundation/x402/tree/main/examples/typescript/servers/advanced) for a more complex payment flow
* Explore [Advanced Concepts](/advanced-concepts/lifecycle-hooks) like lifecycle hooks for custom logic before/after verification/settlement
* Explore [Extensions](/extensions/bazaar) like Bazaar for service discovery
* Get started as a [buyer](/getting-started/quickstart-for-buyers)

For questions or support, join our [Discord](https://discord.gg/cdp).

### Summary

This quickstart covered:

* Installing the x402 SDK and relevant middleware
* Adding payment middleware to your API and configuring it
* Choosing between `exact` (fixed-price) and `upto` (usage-based) payment schemes
* Testing your integration
* Deploying to mainnet with CAIP-2 network identifiers

Your API is now ready to accept crypto payments through x402.
