$npx -y skills add basezh/agent-skills-on-base --skill monetize-serviceBuild and deploy a paid API that other agents can pay to use via x402. Use when you or the user want to monetize an API, make money, earn money, offer a service, sell a service to other agents, charge for endpoints, create a paid endpoint, or set up a paid service. Covers "make m
| 1 | # Build an x402 Payment Server |
| 2 | |
| 3 | Create an Express server that charges USDC for API access using the x402 payment protocol. Callers pay per-request in USDC on Base — no accounts, API keys, or subscriptions needed. Your service is automatically discoverable by other agents via the x402 Bazaar. |
| 4 | |
| 5 | ## How It Works |
| 6 | |
| 7 | x402 is an HTTP-native payment protocol. When a client hits a protected endpoint without paying, the server returns HTTP 402 with payment requirements. The client signs a USDC payment and retries with a payment header. The facilitator verifies and settles the payment, and the server returns the response. Services register with the x402 Bazaar so other agents can discover and pay for them automatically. |
| 8 | |
| 9 | ## Confirm wallet is initialized and authed |
| 10 | |
| 11 | ```bash |
| 12 | npx awal@2.0.3 status |
| 13 | ``` |
| 14 | |
| 15 | If the wallet is not authenticated, refer to the `authenticate-wallet` skill. |
| 16 | |
| 17 | ## Step 1: Get the Payment Address |
| 18 | |
| 19 | Run this to get the wallet address that will receive payments: |
| 20 | |
| 21 | ```bash |
| 22 | npx awal@2.0.3 address |
| 23 | ``` |
| 24 | |
| 25 | Use this address as the `payTo` value. |
| 26 | |
| 27 | ## Step 2: Set Up the Project |
| 28 | |
| 29 | ```bash |
| 30 | mkdir x402-server && cd x402-server |
| 31 | npm init -y |
| 32 | npm install express @x402/express @x402/core @x402/evm @x402/extensions |
| 33 | ``` |
| 34 | |
| 35 | Create `index.js`: |
| 36 | |
| 37 | ```js |
| 38 | const express = require("express"); |
| 39 | const { paymentMiddleware } = require("@x402/express"); |
| 40 | const { x402ResourceServer, HTTPFacilitatorClient } = require("@x402/core/server"); |
| 41 | const { ExactEvmScheme } = require("@x402/evm/exact/server"); |
| 42 | |
| 43 | const app = express(); |
| 44 | app.use(express.json()); |
| 45 | |
| 46 | const PAY_TO = "<address from step 1>"; |
| 47 | |
| 48 | // Create facilitator client and x402 resource server |
| 49 | const facilitator = new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" }); |
| 50 | const server = new x402ResourceServer(facilitator); |
| 51 | server.register("eip155:8453", new ExactEvmScheme()); |
| 52 | |
| 53 | // x402 payment middleware — protects routes below |
| 54 | app.use( |
| 55 | paymentMiddleware( |
| 56 | { |
| 57 | "GET /api/example": { |
| 58 | accepts: { |
| 59 | scheme: "exact", |
| 60 | price: "$0.01", |
| 61 | network: "eip155:8453", |
| 62 | payTo: PAY_TO, |
| 63 | }, |
| 64 | description: "Description of what this endpoint returns", |
| 65 | mimeType: "application/json", |
| 66 | }, |
| 67 | }, |
| 68 | server, |
| 69 | ), |
| 70 | ); |
| 71 | |
| 72 | // Protected endpoint |
| 73 | app.get("/api/example", (req, res) => { |
| 74 | res.json({ data: "This costs $0.01 per request" }); |
| 75 | }); |
| 76 | |
| 77 | app.listen(3000, () => console.log("Server running on port 3000")); |
| 78 | ``` |
| 79 | |
| 80 | ## Step 3: Run It |
| 81 | |
| 82 | ```bash |
| 83 | node index.js |
| 84 | ``` |
| 85 | |
| 86 | Test with curl — you should get a 402 response with payment requirements: |
| 87 | |
| 88 | ```bash |
| 89 | curl -i http://localhost:3000/api/example |
| 90 | ``` |
| 91 | |
| 92 | ## API Reference |
| 93 | |
| 94 | ### paymentMiddleware(routes, server) |
| 95 | |
| 96 | Creates Express middleware that enforces x402 payments. |
| 97 | |
| 98 | | Parameter | Type | Description | |
| 99 | | --------- | -------------------- | ---------------------------------------------------- | |
| 100 | | `routes` | object | Route config mapping route patterns to payment config | |
| 101 | | `server` | x402ResourceServer | Pre-configured x402 resource server instance | |
| 102 | |
| 103 | ### x402ResourceServer |
| 104 | |
| 105 | Created with a facilitator client. Register payment schemes and extensions before passing to middleware. |
| 106 | |
| 107 | ```js |
| 108 | const { x402ResourceServer, HTTPFacilitatorClient } = require("@x402/core/server"); |
| 109 | const { ExactEvmScheme } = require("@x402/evm/exact/server"); |
| 110 | |
| 111 | const facilitator = new HTTPFacilitatorClient({ url: "https://x402.org" }); |
| 112 | const server = new x402ResourceServer(facilitator); |
| 113 | server.register("eip155:8453", new ExactEvmScheme()); |
| 114 | ``` |
| 115 | |
| 116 | | Method | Description | |
| 117 | | --------------------------- | --------------------------------------------------------- | |
| 118 | | `register(network, scheme)` | Register a payment scheme for a CAIP-2 network identifier | |
| 119 | |
| 120 | ### Route Config |
| 121 | |
| 122 | Each key in the routes object is `"METHOD /path"`. The value is a config object: |
| 123 | |
| 124 | ```js |
| 125 | { |
| 126 | "GET /api/data": { |
| 127 | accepts: { |
| 128 | scheme: "exact", |
| 129 | price: "$0.05", |
| 130 | network: "eip155:8453", |
| 131 | payTo: "0x...", |
| 132 | }, |
| 133 | description: "Human-readable description of the endpoint", |
| 134 | mimeType: "application/json", |
| 135 | extensions: { |
| 136 | ...declareDiscoveryExtension({ |
| 137 | output: { |
| 138 | example: { result: "example response" }, |
| 139 | schema: { |