Go x402(v1)支付协议接入指南:基于 Gin 构建 HTTP 402 资源服务器
发布时间:2026/9/17 17:03:07 作者:尧图编辑部 阅读量:1,286
支付协议接入指南:基于 Gin 构建 HTTP 402 资源服务器)
Go x402v1支付协议接入指南基于 Gin 构建 HTTP 402 资源服务器【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402导读本文围绕当前仓库中 go/legacy/README.md 讲解的Go 语言 x402 v1 支付协议实现展开说明如何用 Go Gin 快速搭建一个“先付费后响应”的 HTTP 资源服务器客户端通过X-PAYMENT请求头携带签名支付载荷服务端中间件校验付款并结算未付款的浏览器访问则收到 402 付费墙。读完本文你将掌握go/legacy模块的安装方式、PaymentMiddleware的全部配置项、完整支付流程Verify → 响应 → Settle的源码级原理以及如何接入 Coinbase 托管 Facilitator 在 Base 主网接收真实 USDC 付款。需要说明的是该模块实现的是已弃用的 v1 协议仅接收安全补丁生产环境请按仓库内 docs/guides/migration-v1-to-v2.mdx 迁移到 v2。一、模块定位与弃用状态go/legacy是仓库中独立的 Go modulegithub.com/x402-foundation/x402/go见 go.modGo 1.23.3由 5 个子包组成子包职责pkg/ginGin 支付中间件PaymentMiddlewarepkg/facilitatorclient调用 Facilitator 的 Verify / Settle 客户端pkg/types支付需求、支付载荷、响应等核心数据结构pkg/coinbasefacilitatorCoinbase 托管 Facilitator 的认证配置examples本地示例与 Base 主网示例模块当前版本为0.2.0见 pkg/types/version.go。原 README 明确标注Deprecated (v1)本模块实现 x402v1协议已弃用仅接收安全补丁。请迁移至 v2参见迁移指南遗留示例存档在 git tagarchive/legacy-v1-examples。因此本文所有内容以“理解 v1 协议实现与迁移参考”为定位不推荐新项目直接基于它上线。二、安装模块与任何 Go 依赖一样在项目内执行go get github.com/x402-foundation/x402/go该模块同时依赖github.com/gin-gonic/gin v1.10.0、github.com/coinbase/cdp-sdk/go用于 CDP 认证 JWT 生成、github.com/joho/godotenv用于主网示例加载.env以及github.com/stretchr/testify测试均会随go get一并解析。三、快速开始用 Gin 接入 x402 支付原 README 给出了一个完整可运行的最小资源服务器一个“付费笑话”接口/joke每次访问需支付 0.0001 美元未付款请求会被中间件拦截。完整代码如下package main import ( math/big x402gin github.com/x402-foundation/x402/go/pkg/gin github.com/gin-gonic/gin github.com/x402-foundation/x402/go/pkg/types ) func main() { r : gin.Default() facilitatorConfig : types.FacilitatorConfig{ URL: http://localhost:3000, } r.GET( /joke, x402gin.PaymentMiddleware( big.NewFloat(0.0001), 0x209693Bc6afc0C5328bA36FaF03C514EF312287C, x402gin.WithFacilitatorConfig(facilitatorConfig), x402gin.WithResource(http://localhost:4021/joke), ), func(c *gin.Context) { c.JSON(200, gin.H{ joke: Why do programmers prefer dark mode? Because light attracts bugs!, }) }, ) r.Run(:4021) // Start the server on 0.0.0.0:4021 (for windows localhost:4021) }运行后服务监听:4021Windows 下需改为localhost:4021。该示例的完整版也保留在 examples/server/resource.go两者内容一致。这段代码揭示了PaymentMiddleware的两个必选参数amount以十进制小数表示的单次收费金额例如0.0001表示 0.0001 USDC。注意 middleware.go 中将其乘以1e6后转成整数maxAmountRequiredUSDC 为 6 位小数即0.0001 → 100address收款地址payTo示例中是0x209693Bc6afc0C5328bA36FaF03C514EF312287C。WithFacilitatorConfig指定本地 Facilitator 服务地址示例为http://localhost:3000WithResource声明受保护资源本身的完整 URL会写入支付需求供客户端与 Facilitator 核对。四、PaymentMiddleware 配置项全解中间件采用函数式选项Functional Options模式所有可选项定义在 middleware.go说明如下选项函数对应字段作用默认值WithFacilitatorConfig(config)FacilitatorConfig指定 Facilitator 服务地址与认证指向https://x402.org/facilitatorfacilitatorclient.go 中的DefaultFacilitatorURLWithResource(resource)Resource受保护资源的完整 URL写入PaymentRequirements.Resource空为空时退化为ResourceRootURL 请求路径WithResourceRootURL(rootURL)ResourceRootURL与请求路径拼接生成 Resource空WithDescription(desc)Description资源描述展示给客户端空WithMimeType(mimeType)MimeType资源 MIME 类型空WithMaxTimeoutSeconds(sec)MaxTimeoutSeconds支付有效的最长超时秒数写入支付需求60见 middleware.goWithOutputSchema(schema)OutputSchema资源输出的 JSON Schema*json.RawMessagenil序列化时省略WithTestnet(testnet)Testnet是否使用测试网 Base Sepolia 与测试 USDCtrueWithCustomPaywallHTML(html)CustomPaywallHTML自定义 402 付费墙 HTML内置占位页htmlbodyPayment Required/body/htmlmiddleware.go网络与资产的选择逻辑Testnet标志直接决定链与 USDC 合约地址middleware.go默认Testnettruenetwork base-sepoliaUSDC 合约0x036CbD53842c5426634e7929541eC2318f3dCF7eTestnetfalse主网network baseUSDC 合约0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Base 主网原生 USDC。同时中间件会调用paymentRequirements.SetUSDCInfo(testnet)types.go在Extra字段写入 USDC 代币元数据测试网为{name:USDC,version:2}主网为{name:USD Coin,version:2}。五、请求处理流程从 402 付费墙到结算回执PaymentMiddleware返回的gin.HandlerFunc内部完整实现了“校验 → 执行业务 → 结算”三步流水线middleware.go这也是理解 v1 协议的关键浏览器识别与付费墙读取Accept与User-Agent若两者分别包含text/html与Mozilla则判定为浏览器middleware.go。此时若缺少有效支付直接以402 StatusPaymentRequired返回 HTML 付费墙默认页或WithCustomPaywallHTML自定义页非浏览器 402 响应无X-PAYMENT头或载荷解码失败时返回402JSON携带accepts一份PaymentRequirements数组描述付费要求与x402Version: 1客户端据此构造签名支付解码支付载荷读取请求头X-PAYMENT经types.DecodePaymentPayloadFromBase64types.go做 Base64 解码 JSON 反序列化并强制回填X402Version 1Verify 校验调用facilitatorClient.Verify(payload, requirements)。校验失败返回402携带invalidReason与accepts通信异常返回500执行业务处理器校验通过后用自定义responseWriter拦截响应体与状态码middleware.go再执行c.Next()运行真实 handlerSettle 结算业务成功返回后调用facilitatorClient.Settle(...)正式上链扣款。结算失败会把已写入的响应整体替换为402错误成功后把SettleResponse经EncodeToBase64Stringtypes.goBase64 编码后写入响应头X-PAYMENT-RESPONSE并把被拦截的原始响应体与状态码原样写回客户端。流程时序图Client Resource Server (Gin) Facilitator │ GET /joke │ │ ├─────────────────────────────────► 无 X-PAYMENT 或无效 │ │◄──────────────────────────────── 402 accepts浏览器收付费墙 HTML │ │ GET /joke X-PAYMENT │ │ ├─────────────────────────────────► 解码载荷 │ │ ├──────── POST /verify ────────────────►│ │ │◄──── isValid / invalidReason ────────┤ │ ├──────── POST /settle ────────────────►│ │ │◄──── transaction / success ──────────┤ │◄──────────────────────────────── 200 X-PAYMENT-RESPONSE结算回执 │该流程与 middleware_test.go 中的测试场景一一对应——测试通过内置的TestServerConfig分别模拟“校验成功 结算成功”“校验失败”“结算失败”等分支验证 402 / 200 响应与X-PAYMENT-RESPONSE头的生成逻辑可作为阅读实现的辅助用例。六、核心数据结构所有协议数据结构集中在 pkg/types/types.go其中PaymentRequirements即客户端收到的“价格清单”也是发给 Facilitator 的校验基准JSON 字段Go 类型说明schemestring支付方案v1 中固定为exactnetworkstring链标识base/base-sepoliamaxAmountRequiredstring十进制字符串表示的最大扣款金额USDC 最小单位resourcestring受保护资源 URLdescriptionstring资源描述mimeTypestring资源 MIME 类型payTostring收款地址maxTimeoutSecondsint支付超时上限assetstring支付资产合约地址USDCoutputSchema*json.RawMessage输出 JSON Schema可省略extra*json.RawMessage扩展字段USDC 元数据可省略客户端返回的PaymentPayload则包含x402Version、scheme、network以及payload——在 EVM 上即ExactEvmPayload内含ERC-3009 类型化签名授权from、to、value、validAfter、validBefore、nonce六个字段与signature见 types.go。这正是 v1 exact 方案“预付授权、后由 Facilitator 执行转账”的核心扣款不是服务器发起的任意转账而是基于链上 ERC-3009 授权签名完成的受控转移。Facilitator 的响应体同样有对应结构VerifyResponseisValid、invalidReason、payer与SettleResponsesuccess、errorReason、transaction、network、payer。两个结构的“失败”语义不同——校验失败通常返回402付款无效可重试结算失败代表扣款未完成服务器必须视为请求失败并回滚响应。七、FacilitatorClient与 Facilitator 服务的通信协议facilitatorclient/facilitatorclient.go 封装了对 Facilitator 的两个 HTTP 端点调用POST {URL}/verify请求体为{x402Version, paymentPayload, paymentRequirements}返回VerifyResponsePOST {URL}/settle请求体同上返回SettleResponse。客户端结构体包含三个字段URL、HTTPClient可通过FacilitatorConfig.Timeout设置超时默认无超时与CreateAuthHeaders。其中CreateAuthHeaders返回map[string]map[string]string分别以verify、settle为键提供两个端点各自的额外请求头facilitatorclient.go用于需要鉴权的托管 Facilitator。对应的types.FacilitatorConfigtypes.go完整定义如下type FacilitatorConfig struct { URL string // Facilitator 服务根地址 Timeout func() time.Duration // 可选的 HTTP 超时 CreateAuthHeaders func() (map[string]map[string]string, error) // 可选的端点级鉴权头 }错误处理上非 200 响应会分别包装为VerifyError/SettleErrortypes.go携带Reason、Payer、Network、Transaction等上下文并实现Unwrap()以便用errors.Is/As链式排查。八、接入 Coinbase 托管 FacilitatorBase 主网收款示例默认 Facilitator 面向开发测试若要在 Base 主网接收真实 USDC仓库提供了 examples/mainnet/mainnet.go 完整示例它通过coinbasefacilitator.CreateFacilitatorConfig一键接入 Coinbase 托管 x402 FacilitatorfacilitatorConfig : coinbasefacilitator.CreateFacilitatorConfig(apiKeyID, apiKeySecret) r.GET( /premium-joke, x402gin.PaymentMiddleware( big.NewFloat(0.01), // $0.01 USD payTo, // Your wallet address x402gin.WithFacilitatorConfig(facilitatorConfig), x402gin.WithDescription(A premium programming joke), x402gin.WithResource(https://api.example.com/premium-joke), x402gin.WithTestnet(false), // Use mainnet! ), func(c *gin.Context) { c.JSON(200, gin.H{ joke: Why do Java developers wear glasses? Because they dont C#!, type: premium, }) }, )环境变量与启动步骤按 examples/mainnet/README.md主网示例需要两个前置条件Coinbase Developer PlatformCDPAPI 密钥与用于收款的以太坊地址。启动方式复制.env-local为.env填入收款地址与 CDP 密钥cp .env-local .env运行服务go run mainnet.go程序启动时用godotenv加载环境变量并校验三个必需项mainnet.goCDP_API_KEY_ID、CDP_API_KEY_SECRET与ADDRESS缺失时打印错误并退出。示例同时提供/premium-joke0.01 美元收费与免费的/free-joke两个端点作对照。底层认证原理CreateFacilitatorConfig返回的配置指向https://api.cdp.coinbase.com/platform/v2/x402facilitator.go并把CreateCdpAuthHeaders注入CreateAuthHeaders。该函数对verify、settle两个端点分别生成两样东西facilitator.goAuthorization 头调用coinbase/cdp-sdk的auth.GenerateJWT以POST方法、请求主机与路径为上下文生成短期 JWT前缀Bearercdp.goCorrelation-Context 头携带sdk_version、sdk_languagego、sourcex402、source_version对应types.Version等遥测信息cdp.go。这也解释了为什么本地示例中FacilitatorConfig只有URL即可工作接入托管 Facilitator 时认证头由CreateAuthHeaders在每个 Verify / Settle 请求发出前动态生成最终在 facilitatorclient.go 中按端点注入请求。九、验证与测试仓库为中间件与客户端提供了单元测试是理解行为约定与协议边界的第一手资料go/legacy/pkg/gin/middleware_test.go通过TestServerConfig配置模拟 Facilitator 的成功/失败行为用httptest驱动 Gin 路由覆盖“无支付 → 402”“校验通过 → 200 结算回执”“校验/结算失败 → 402”等路径共 359 行go/legacy/pkg/facilitatorclient/facilitatorclient_test.go验证 Verify / Settle 的请求构造、认证头注入与错误包装。运行方式cd go/legacy go test ./...十、迁移到 v2由于go/legacy为 v1 实现且已进入仅安全维护状态正式使用请迁移至 v2。仓库内 docs/guides/migration-v1-to-v2.mdx 提供了完整迁移指南v2 的 Go 实现位于 go 根目录模块含 go/http、go/mechanisms、go/types 等协议细节可对照 specs/x402-specification-v2.md 与 specs/transports-v2/http.md 阅读。迁移时重点关注三处差异中间件/客户端 API 的重构v1 的PaymentMiddleware与FacilitatorClient在 v2 中被拆分进go/http的 builder/middleware 体系、支付载荷与支付需求的字段演进以及 default facilitator 的地址与鉴权方式变化——结合本仓库 v2 源码与上述文档逐一核对即可平滑切换。【免费下载链接】x402A payments protocol for the internet. Built on HTTP.项目地址: https://gitcode.com/GitHub_Trending/x4/x402创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考