【Agentic Payment 系列 #4】從理論到實作:用 Golang 親手跑一遍 x402 支付流程
透過一個極簡的 Golang Demo 專案,從 Server(賣方)到 Client(買方)完整走過 x402 協議的 402 挑戰、離線簽署與鏈上結算流程 —— 把前三篇的協議設計變成可執行的程式碼。
本文為 Agentic Payment 系列第四篇。建議至少先閱讀第一篇,了解 x402 協議的設計哲學與交易流程: → 【Agentic Payment 系列 #1】HTTP 402 沉睡三十年後醒來:x402 如何讓支付成為網際網路的一等公民 → 【Agentic Payment 系列 #2】信任的代價:AP2 授權機制、A2A 支付整合與三大協議戰場劃分 → 【Agentic Payment 系列 #3】兆美元賽道:Agent 經濟的市場、合規與 Web 4.0 支付堆疊
前三篇文章,我們從協議設計、信任機制到市場預測,把 Agentic Payment Stack 的理論面貌剖析得相當透徹。
這篇文章的任務很簡單 —— 用一個極簡的 Golang Demo 專案,讓你親手走過 x402 協議從「402 挑戰」到「200 OK + 鏈上交易確認」的完整生命週期。不需要前端,不需要複雜的部署,兩個 Terminal 就能跑完。
專案原始碼:charles-hsiao/x402-demo
為什麼選 Golang?
x402 Foundation 的官方 SDK 提供了 TypeScript 與 Golang 兩種實作。選擇 Golang 有幾個工程上的理由:
- 單一二進位檔部署:編譯後丟到任何 Linux 機器上直接跑,不需要 Node.js Runtime 或 Docker,這對邊緣節點與嵌入式 Agent 場景尤其重要
- 強型別與編譯時檢查:支付相關的程式碼容不得型別混淆,Golang 的編譯器在你犯錯之前就會攔截
- 原生併發模型:Goroutine 的輕量級設計使 Server 得以低成本地處理數千個並發支付請求
因為筆者不會寫 TypeScript
當然,如果你的技術棧是 TypeScript,也可以試試看 x402 的 npm SDK。
專案結構:極簡的 Buyer-Seller 架構
x402-demo/
├── server/
│ └── main.go # Gin HTTP Server(Seller / 賣方)
├── client/
│ ├── main.go # Go HTTP Client(Buyer / 買方)
│ ├── builder_pattern.go
│ ├── mechanism_helper_registration.go
│ └── utils.go
├── .env.example # 環境變數範本
├── Makefile # 常用指令
└── README.md
整個 Demo 只有兩個角色:
| 角色 | 對應目錄 | 說明 |
|---|---|---|
| Server(Seller) | server/ | 提供付費 API,收取 USDC |
| Client(Buyer) | client/ | 呼叫付費 API,自動完成簽署與支付 |
第三個角色 Facilitator(促成者) 由 x402 官方提供的公共服務擔任(https://x402.org/facilitator),負責鏈上驗證與結算,不需要自行部署。
前置準備
在開始之前,你需要準備:
- Go 1.26+(建議透過 asdf 管理版本)
- 兩個 EVM 錢包:一個收款(Server 端),一個付款(Client 端),下面會帶你用 Foundry 在一分鐘內建好
- Base Sepolia 測試網的 USDC:替付款錢包從 Circle Faucet 免費領取
建立錢包:用 Foundry 的 cast wallet new
Foundry(getfoundry.sh)是目前最主流的 EVM 開發工具套件,其中的 cast 指令讓你在 CLI 直接操作錢包,不需要安裝 MetaMask 或連接任何 GUI。
Step 1:安裝 Foundry
~$ curl -L https://foundry.paradigm.xyz | bash && foundryup
安裝完成後,確認工具已就緒:
~$ cast --version
Step 2:建立收款錢包(Server / 賣方)
~$ cast wallet new
輸出格式如下,Address 就是你的收款地址,這個錢包用在 Server 端,不需要私鑰也不需要有任何餘額:
Successfully created new keypair.
Address: 0xAAAA...(你的收款地址)
Private key: 0xBBBB...(妥善保存,此 demo 中 Server 端不需要用到)
把 Address 記下來,後面填入 EVM_PAYEE_ADDRESS。
Step 3:建立付款錢包(Client / 買方)
再執行一次,產生第二組金鑰;這把私鑰會讓 Agent 自動簽署支付:
~$ cast wallet new
Successfully created new keypair.
Address: 0xCCCC...(你的付款地址)
Private key: 0xDDDD...(填入 EVM_PRIVATE_KEY)
安全提醒:
cast wallet new產生的私鑰只顯示一次,請立刻複製到.env。這是 Testnet 錢包,切勿將此私鑰用於主網或存入任何真實資產。
Step 4:領取測試網 USDC
付款錢包需要有 USDC 才能完成 x402 支付。前往 Circle Faucet(faucet.circle.com):
- 選擇網路:Base Sepolia
- 貼上你的付款錢包地址(
0xCCCC...) - 點擊 Send,約 30 秒後即可收到 20 USDC

確認 USDC 已到帳,直接在 Base Sepolia Scan 輸入你的付款錢包地址查詢,看到 Token Transfers 頁籤有 USDC 入帳記錄即代表領取成功:下圖範例錢包

設定環境變數
有了兩個錢包地址與私鑰之後,設定 .env:
~$ cp .env.example .env
# Server(賣方)
EVM_PAYEE_ADDRESS=0xAAAA...你的收款地址 # 收款用的錢包地址
FACILITATOR_URL=https://x402.org/facilitator # 免費測試網 Facilitator
# Client(買方)
EVM_PRIVATE_KEY=0xDDDD...你的付款私鑰 # 測試網私鑰(切勿使用主網私鑰!)
再強調一次:此為 demo 專案,
EVM_PRIVATE_KEY只能使用測試網的私鑰。
Server 端:用 Middleware 把 API 變成付費資源
Server 端的核心概念只有一個:把 x402 Payment Middleware 套在你想收費的 Route 上。
這就像你在 Gin 框架裡加 Authentication Middleware 一樣,只是從「驗證身份」變成了「驗證付款」。
關鍵程式碼解析
// 建立 Facilitator Client —— 指向公共的驗證/結算服務
facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
URL: facilitatorURL,
})
// 定義哪些 Route 需要付款、價格多少、接受哪些鏈與幣種
routes := x402http.RoutesConfig{
"GET /weather": {
Accepts: x402http.PaymentOptions{
{
Scheme: "exact",
Price: "$0.001",
Network: "eip155:84532", // Base Sepolia
PayTo: evmAddress,
},
{
Scheme: "exact",
Price: "$0.001",
Network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
PayTo: svmAddress,
},
},
Description: "Get weather data for a city",
MimeType: "application/json",
},
}
// 套用 Middleware:攔截請求、檢查付款、驗證結算
r.Use(ginmw.X402Payment(ginmw.Config{
Routes: routes,
Facilitator: facilitatorClient,
Schemes: []ginmw.SchemeConfig{
{Network: "eip155:84532", Server: evm.NewExactEvmScheme()},
{Network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", Server: svm.NewExactSvmScheme()},
},
Timeout: 30 * time.Second,
}))
幾個設計上值得注意的點:
支持多鏈。 Accepts 是一個陣列,同時接受 EVM(Base Sepolia)與 SVM(Solana Devnet)的付款。Client 可以根據自己持有的資產選擇最合適的支付路徑。這正是第一篇文章提到的「降低供需雙方耦合度」的具體實現。
定價直覺化。 Price: "$0.001":SDK 在內部自動處理 USDC 的小數轉換,開發者不需要手動計算。實際上 USDC 在鏈上以 6 位小數(decimals = 6)儲存,因此 1 USDC = 1,000,000 個最小單位;$0.001 = 千分之一美元,對應的最小單位數量便是 1,000,000 × 0.001 = 1000。
Middleware Pattern。 付費 Route 與免費 Route 的 Handler 程式碼完全相同,x402 的支付邏輯全部封裝在 Middleware 層。/weather 收費、/health 免費,差別只是 Middleware 裡的 Route Config,不是 Handler 的邏輯。
免費端點(不受 Middleware 保護)
r.GET("/health", func(c *ginfw.Context) {
c.JSON(http.StatusOK, ginfw.H{
"status": "ok",
"version": "2.0.0",
})
})
Client 端:全自動的 402 → 簽署 → 重試
Client 端展示了 x402 SDK 的核心便利性 —— 開發者不需要手動處理 402 回應邏輯。SDK 的 HTTP Client Wrapper 自動完成:
- 發送請求 → 收到 402
- 解析
PAYMENT-REQUIREDHeader - 用 Private Key 簽署支付授權(EIP-3009,Gasless)
- 帶著簽名重送請求
Builder Pattern:細粒度控制
func createBuilderPatternClient(evmPrivateKey, svmPrivateKey, evmRpcURL string) (*x402.X402Client, error) {
// 從私鑰建立簽名器
evmSigner, err := evmsigners.NewClientSignerFromPrivateKey(evmPrivateKey)
if err != nil {
return nil, err
}
// 建立 x402 Client 並註冊支付機制
client := x402.Newx402Client()
// 用 Wildcard 匹配所有 EVM 網路
client.Register("eip155:*", exactevm.NewExactEvmScheme(evmSigner, rpcConfig))
client.Register("eip155:*", uptoevm.NewUptoEvmScheme(evmSigner, rpcConfig))
// 如果有 Solana 私鑰,也註冊 SVM 支付機制
if svmPrivateKey != "" {
svmSigner, err := svmsigners.NewClientSignerFromPrivateKey(svmPrivateKey)
if err != nil {
return nil, err
}
client.Register("solana:*", exactsvm.NewExactSvmScheme(svmSigner))
}
return client, nil
}
Wildcard 網路註冊 是一個巧妙的抽象。"eip155:*" 表示「任何 EVM 相容鏈都用這把 Signer」,讓 Client 不需要提前知道 Server 會要求哪條鏈的付款。當 Server 未來新增 Polygon 或 Arbitrum 的支付選項時,Client 端不需要任何程式碼變更。
HTTP Client Wrapper:無縫整合
func wrapHTTPClient(x402Client *x402.X402Client) *http.Client {
httpClient := x402http.Newx402HTTPClient(x402Client)
return x402http.WrapHTTPClientWithPayment(http.DefaultClient, httpClient)
}
這三行程式碼完成的事情是:把標準的 http.Client 包裝成一個「會自動付錢」的 Client。之後你用 httpClient.Do(req) 發任何請求,如果目標 Server 回傳 402,SDK 會自動攔截、簽署、重試,對呼叫端的程式碼來說整個支付流程是透明的。
這就是 x402 宣稱的「支付像加一個 Header」的開發體驗。對比傳統支付整合動輒需要數百行的 Token 交換、Webhook 處理與錯誤恢復邏輯,這裡的程式碼量確實只有三行。
完整流程 Demo:從 402 到 200
Step 1:啟動 Server
~$ make server
Starting x402 Server...
cd server && go run main.go
🚀 Starting Gin x402 server...
EVM Payee address: 0xb2F27822D005Cf511b373285Bbd469bD61FcE4f7
SVM Payee address:
EVM Network: eip155:84532
SVM Network: solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
Facilitator: https://x402.org/facilitator
Step 2:觀察 402 回應(不帶付款)
~$ curl -si http://localhost:4021/weather | grep -i "HTTP\|payment"
HTTP/1.1 402 Payment Required
Payment-Required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIiwicmVzb3VyY2UiOnsidXJsIjoiaHR0cDovL2xvY2FsaG9zdDo0MDIxL3dlYXRoZXIiLCJkZXNjcmlwdGlvbiI6IkdldCB3ZWF0aGVyIGRhdGEgZm9yIGEgY2l0eSIsIm1pbWVUeXBlIjoiYXBwbGljYXRpb24vanNvbiJ9LCJhY2NlcHRzIjpbeyJzY2hlbWUiOiJleGFjdCIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MzIiLCJhc3NldCI6IjB4MDM2Q2JENTM4NDJjNTQyNjYzNGU3OTI5NTQxZUMyMzE4ZjNkQ0Y3ZSIsImFtb3VudCI6IjEwMDAiLCJwYXlUbyI6IjB4YjJGMjc4MjJEMDA1Q2Y1MTFiMzczMjg1QmJkNDY5YkQ2MUZjRTRmNyIsIm1heFRpbWVvdXRTZWNvbmRzIjo2MCwiZXh0cmEiOnsibmFtZSI6IlVTREMiLCJ2ZXJzaW9uIjoiMiJ9fSx7InNjaGVtZSI6ImV4YWN0IiwibmV0d29yayI6InNvbGFuYTpFdFdUUkFCWmFZcTZpTWZlWUtvdVJ1MTY2VlUyeHFhMSIsImFzc2V0IjoiNHpNTUM5c3J0NVJpNVgxNEdBZ1hoYUhpaTNHblBBRUVSWVBKZ1pKRG5jRFUiLCJhbW91bnQiOiIxMDAwIiwicGF5VG8iOiIiLCJtYXhUaW1lb3V0U2Vjb25kcyI6NjAsImV4dHJhIjp7ImZlZVBheWVyIjoiQ0tQS0pXTmRKRXFhODF4N0NrWjE0QlZQaVk2eTE2U3hzN293em5xdFdZcDUifX1dfQ==
Payment-Required 的值是 Base64 編碼的 JSON,解碼後可以看到完整的支付條件:
{
"x402Version": 2,
"error": "Payment required",
"resource": {
"url": "http://localhost:4021/weather",
"description": "Get weather data for a city",
"mimeType": "application/json"
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:84532",
"asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"amount": "1000",
"payTo": "0xb2F27822D005Cf511b373285Bbd469bD61FcE4f7",
"maxTimeoutSeconds": 60,
"extra": { "name": "USDC", "version": "2" }
},
{
"scheme": "exact",
"network": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
"asset": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
"amount": "1000",
"payTo": "",
"maxTimeoutSeconds": 60,
"extra": { "feePayer": "CKPKJWNdJEqa81x7CkZ14BVPiY6y16Sxs7owznqtWYp5" }
}
]
}
幾個欄位值得對照前面的程式碼確認:
amount: "1000":正是$0.001 × 1,000,000 = 1000個 USDC 最小單位asset:EVM 端為0x036CbD...,即 Base Sepolia 上的 USDC 合約地址payTo:EVM 端填入 Server 的收款地址(EVM_PAYEE_ADDRESS);Solana 端為空,代表此 Demo 的 Server 沒有設定 SVM 收款地址maxTimeoutSeconds: 60:Client 必須在 60 秒內完成簽署並重送請求,逾時則 Server 拒絕accepts是陣列:Client 可以選擇 EVM 或 Solana 任一路徑支付,SDK 會根據 Client 已註冊的 Scheme 自動挑選
Server 對未付款的請求回傳 402 Payment Required,Header 中包含完整的支付條件 —— 價格、受款地址、鏈 ID、代幣合約、Nonce。這就是第一篇文章提到的 Payment Discovery 機制在 HTTP 層的具體呈現。
Step 3:執行 Client(自動完成支付)
~$ make client
Running x402 Client...
cd client && go run .
Running example: builder-pattern
Making request to: http://localhost:4021/weather
✅ Response body:
{
"city": "San Francisco",
"temperature": 60,
"timestamp": "2026-05-07T18:44:47+08:00",
"weather": "foggy"
}
💰 Payment Details:
Success: true
Transaction: 0x3c4268ea2ba29a327aaba55efb08598b6a6803f2a0600e9bdadbc2f1955a16c8
Network: eip155:84532
Payer: 0x288fC773264840fD691b2c0049F35B925222AFbE
從使用者(開發者)的角度看,這就是一次普通的 HTTP GET 請求。SDK 在底層自動完成了:
- 第一次請求 → 收到 402
- 解析
PAYMENT-REQUIREDHeader 中的支付條件 - 選擇匹配的 Scheme(EVM Exact)
- 用 EIP-3009 模式簽署支付授權(Gasless —— Client 不需要持有 ETH 來付 Gas)
- 帶著
PAYMENT-SIGNATUREHeader 重送請求 - Server 轉發給 Facilitator 驗證 → Facilitator 發起鏈上 USDC 轉帳
- 驗證通過後回傳
200 OK+ 資源內容 +PAYMENT-RESPONSEHeader(含 Transaction Hash)
整個流程在約 1-2 秒內完成(Testnet 區塊確認時間)。回應中的 Transaction Hash 可以直接貼到 Base Sepolia Scan 查詢鏈上的結算紀錄;以本文的範例收款錢包為例,可以在 Token Transfers 頁面看到每一筆 USDC 入帳。

付款錢包(0x288fC773...,即 EVM_PRIVATE_KEY 對應的地址)同樣可以在 Base Sepolia Scan 查到對應的 USDC 轉出紀錄:

支付方案與 Scheme 機制
Demo 專案中使用了 exact Scheme(精確金額轉帳)。x402 SDK 同時支援 upto Scheme(預授權上限),適用於按量計費場景:
| Scheme | 說明 | 適用場景 |
|---|---|---|
exact | Client 支付精確金額 | 固定價格的 API 調用 |
upto | Client 預授權一個上限金額,Server 按實際用量結算 | Streaming、按量計費 |
在程式碼中,Client 透過同時註冊 exactevm 和 uptoevm 兩種 Scheme,讓 SDK 根據 Server 的 PAYMENT-REQUIRED 回應自動選擇對應的支付邏輯:
client.Register("eip155:*", exactevm.NewExactEvmScheme(evmSigner, rpcConfig))
client.Register("eip155:*", uptoevm.NewUptoEvmScheme(evmSigner, rpcConfig))
Facilitator 的角色:你不需要運行區塊鏈節點
Demo 中最容易被忽略但最關鍵的設計,是 Facilitator 完全由外部服務提供。Server 端只需要設定一個 URL:
FACILITATOR_URL=https://x402.org/facilitator
Facilitator 替 Server 完成了所有鏈上操作:驗證簽名有效性、確認 Nonce 未被重放、檢查 Client 餘額充足、發起 USDC 轉帳。Server 本身不需要連接 RPC 節點、不需要管理 Gas Fee、不需要理解 EIP-3009 的細節。
這就是第一篇文章中提到的「餐廳不需要理解 Visa 結算協議」的 Demo 驗證:Server 只管提供內容,Facilitator 處理一切金流。
| Facilitator | URL | 適用環境 | 備註 |
|---|---|---|---|
| x402.org(官方免費) | https://x402.org/facilitator | Testnet | 無需申請帳號 |
| CDP(Coinbase Developer Platform) | https://api.cdp.coinbase.com/platform/v2/x402 | Testnet + Mainnet | 需要 CDP API Keys |
從 Testnet 到 Mainnet:一行設定的距離
切換到主網只需要修改兩個值:
// Testnet
Network: "eip155:84532" // Base Sepolia
// Mainnet
Network: "eip155:8453" // Base Mainnet
加上將 Facilitator 切換到 CDP 的主網端點(需要 API Keys)。但請記住:主網上的是真金白銀。在你對 Testnet 流程完全熟悉之前,不要碰 Mainnet。
對 Agent 開發者意味著什麼
如果你正在建構 AI Agent,x402 的 Golang SDK 讓你的 Agent 具備了「原生支付能力」,而且成本極低。
在 Base Sepolia(以及未來的 Mainnet)上,每筆 x402 交易的 Gas 成本低於 $0.0001。這意味著你的 Agent 可以:
- 以 $0.001 調用一次氣象 API
- 以 $0.005 抓取一篇新聞摘要
- 以 $0.01 取得一份分析報告
而每一筆交易都有不可偽造的鏈上收據(Transaction Hash),可審計、可驗證、不可否認。
// 你的 Agent 程式碼 —— 就是這麼簡單
client := x402.Newx402Client()
client.Register("eip155:*", exactevm.NewExactEvmScheme(signer, nil))
httpClient := x402http.WrapHTTPClientWithPayment(http.DefaultClient,
x402http.Newx402HTTPClient(client))
resp, _ := httpClient.Do(req) // 自動處理付款
六行程式碼,你的 Agent 就從「只會免費呼叫 API 的程式」升級為「能在開放市場自主消費的經濟行為者」。
當付款的工程成本降到六行程式碼、經濟成本降到萬分之一美元,「為每次 API 調用收費」不再是架構上的奢侈,而是商業模式的預設選項。這對整個 API 經濟的定價模型,是一次根本性的重新校準。
動手試試
~$ git clone https://github.com/charles-hsiao/x402-demo.git
~$ cd x402-demo
~$ cp .env.example .env
# 編輯 .env,填入你的錢包地址與測試網私鑰
~$ make setup
~$ make server # Terminal 1
~$ make client # Terminal 2
五分鐘內,你就會看到你的第一筆 x402 鏈上支付完成。
如果暫時不想在本機跑環境,Cloudflare 提供了一個線上的 x402 Playground,可以直接在瀏覽器中觀察 402 挑戰、支付簽署與結算的互動過程。
小結
x402 的 Developer Experience 已經到了「跟加一個 Auth Middleware 差不多」的程度。當支付基礎設施的整合成本降到這個水平,擋在 Micropayments 前面的最後一道牆,就不再是技術門檻,而是想像力。
或許未來的電商支付、SaaS 產品 不再需要 Stripe、不再需要訂閱制、不再需要廣告 —— 只需要一個 402 回應、一個願意為價值付費的 Agent,以及一個你要用來收款的區塊鏈錢包。
區塊鏈技術在過去十年間,因為投機泡沫與監管爭議而背負了太多負面標籤。但 Agentic Payment 這個場景讓我重新看見了那個最初令人興奮的想像:一個價值可以像資訊一樣自由流動的世界。
網際網路的偉大之處,不在於它讓人們談論它,而在於它作為基礎設施靜靜地撐起了整個數位世界 —— 沒有人在傳送一封 Email 時會想到 TCP/IP。區塊鏈長期以來缺少的,正是這種「消失在背景中、讓上層應用發光」的角色定位。x402 讓我第一次清楚地感受到:這個時刻,或許正在到來。
不是 ICO,不是 NFT,而是 AI Agent 每秒發起的數百萬筆 $0.001 結算請求 —— 無聲地流過區塊鏈,就像封包流過路由器一樣自然。當區塊鏈真正成為網際網路的支付層,它就不再需要被討論,只需要被使用。
下一篇:【Agentic Payment 系列 #5】沒有人看到全貌:AP2 v0.2 用兩張 Mandate 重寫 Agent 的授權邊界
回顧系列全文: → 【Agentic Payment 系列 #1】HTTP 402 沉睡三十年後醒來:x402 如何讓支付成為網際網路的一等公民 → 【Agentic Payment 系列 #2】信任的代價:AP2 授權機制、A2A 支付整合與三大協議戰場劃分 → 【Agentic Payment 系列 #3】兆美元賽道:Agent 經濟的市場、合規與 Web 4.0 支付堆疊
如果這篇文章對你有幫助,歡迎分享給對 Agent 經濟與 Web3 支付感興趣的朋友。