我克隆了Solana基金会的PayKit仓库,在本地把Playground API跑起来,随便用HTTP客户端给GET /api/v1/fortune发了个请求。结果没有拿到预想中的JSON,而是直接撞上了一个402 Payment Required状态码。
这可不是什么需要屏蔽的错误,而是整个支付流程的第一个有效回应。响应里明明白白写着:调用一次接口需要支付10000 USDC基本单位,也就是0.01美元。更有意思的是,同一个accepts数组里塞了两套支付方案:一套叫x402 exact(精确支付),另一套叫MPP charge intent(多部分支付路径)。
![]()
简单说,一个402响应就告诉了调用方“你得付钱”,同时也把“怎么付”的菜单推了过来。AI代理或者任何HTTP客户端读到这个402,就可以选一个方案,签一笔支付,然后带着凭证重放原来的请求。
接下来我丢了一个临时的Solana密钥对给PayKit客户端,选中MPP方案,把同一个GET /api/v1/fortune请求重新投出去。客户端自动解析了402里的支付挑战、签署了转账、回传证明,最后拿到的不是一个402,而是一个正常的200响应,顺带一句俏皮话:“Your code will compile on the first try today.”(今天的代码第一次就能编译通过。)
拿到JSON不算完,我还专门查了响应头里的payment‑receipt和x‑payment‑settlement‑signature,跑到沙盒环境的RPC节点上去核对那笔链上交易。交易确实存在,而且它的err字段是null。这一行就把“HTTP演练返回200”和“支付通道真正完成结算”之间的分界线画清楚了。
这里必须说一句老实话:我并没有扔给一个LLM一句提示语、然后宣称它是自己选的支付方案。测试的时候,我直接把PayKit的createPayKitClient当作AI代理底层可调的HTTP客户端来跑的。读取402、签署请求的支付、重放同一个URL——这正是我从“代理侧”验证的支付步骤。
整个应用层的设计感觉非常薄。TypeScript示例里只要把接受的协议、运营方信息和一张价格表传给createPayKit,然后给Express路由绑一个pay.express('fortune')就行了。一个未付费的请求进来,网关直接回402;带着支付证明的请求则先验证、再结算,最后才进到业务处理函数。业务处理函数里只需要通过pay.payment(req)去读已经确认过的支付凭据,完全不需要在每个收费路由里同时维护x402分支和MPP分支。
仓库里的接口规范用更正式的方式把边界说清楚了:应用层只管声明一个带价格的门;调度层收集各个协议提供的支付方案、识别凭证;适配层负责验证和结算。最终落到应用手里的,是一个与协议无关的Payment对象。我对着文档paykit‑interface.md里的三层架构和require_payment、paid?、payment()三个原语,以及src/client/index.ts里的实现逐条核对过,不是把宣传语照单全收。
除了/api/v1/fortune,我还故意跑了一次/api/v1/joke。这次MPP路径玩了个费用拆分:0.003美元进了某个平台账户,剩下的才流向卖家,而回执上依旧清楚标着“卖家收入”的标签。换句话说,在支付层面做收入分拆,不需要业务方自己再造一套对账轮子。
那什么时候该用这套东西?简单记一句话:当你的API需要收极小额的稳定币,而且付款方能够控制钱包的时候,可以考虑它。但千万别把它当成一张信用卡网络来用——没有拒付、没有chargeback,包里也确实有我跑通demo之前撞上的小粗糙边缘。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.