HTTP 402 Payment Required这个状态码从1999年HTTP/1.1规范就定义了,一直写着”reserved for future use”,26年了没人真正用过。Stripe和Tempo联合搞了个Machine Payments Protocol(MPP),终于把402用起来了——而且不是给人用的,是给AI Agent用的。Agent请求一个付费API,服务器返回402加上支付要求,Agent自动完成支付,拿到资源。整个过程不需要人类介入,不需要注册账号,不需要填信用卡表单。这不是概念验证。Stripe已经上线了,有SDK,有文档,有真实商家在接入。
为什么需要机器支付协议
现在的AI Agent调用付费服务有多痛苦?注册账号、选套餐、填支付信息、处理订阅——每一步都是给人类设计的。Agent要么需要人类帮忙操作,要么得用Browserbase之类的工具去模拟人类操作网页。MPP的思路很直接:既然Agent是HTTP客户端,那支付也应该在HTTP层面解决。服务端返回402告诉你要付钱,请求头里带上支付凭证就行。跟HTTP Basic Auth的逻辑一样简单。目前支持两种支付方式:
| 方式 | 适用场景 | 结算通道 |
|---|---|---|
| Crypto(稳定币) | 小额高频交易 | 链上结算 |
| SPT(Shared Payment Token) | 信用卡、钱包等传统支付 | Stripe支付通道 |
协议怎么跑的
MPP的核心流程就四步:1. Agent发请求到付费API2. 服务器返回HTTP 402 + Challenge(告诉你要付多少、怎么付)3. Agent生成Credential(支付凭证),带着凭证重新请求4. 服务器验证支付,返回资源 + Receipt(收据)所有信息都在HTTP头里传递。Challenge在WWW-Authenticate头,Credential在Authorization头,Receipt在Receipt头。跟OAuth的token流程差不多,只不过换成了支付。一个典型的402响应长这样:
HTTP/1.1 402 Payment RequiredWWW-Authenticate: Payment challenge="eyJ...",request="eyJ..."Content-Type: application/json{"error": "payment_required", "amount": "0.01", "currency": "usd"}
Agent收到402后,根据Challenge里的支付方式生成Credential,重新发请求:
GET /api/premium-data HTTP/1.1Authorization: Payment credential="eyJ..."
服务器验证支付成功,返回数据并附上收据:
HTTP/1.1 200 OKReceipt: Payment receipt="eyJ..."Content-Type: application/json{"data": "你要的数据"}
整个过程对Agent来说就是:发请求 → 收到402 → 自动付款重试 → 拿到数据。SDK把这些全封装好了。
服务端接入:Express中间件方案
MPP提供了TypeScript/Python/Rust三种SDK。对前端开发者来说,TypeScript版本最顺手。用Express的话,几行代码就能把一个普通API变成付费API。先装依赖:
npm install mppx stripe
最简单的SPT(信用卡)接入:
import crypto from 'crypto';import express from 'express';import { Mppx, stripe } from 'mppx/server';const app = express();// 用于签名Challenge的密钥,生产环境应该持久化存储const mppSecretKey = crypto.randomBytes(32).toString('base64');const mppx = Mppx.create({ methods: [ stripe.charge({ networkId: 'internal', paymentMethodTypes: ['card', 'link'], secretKey: process.env.STRIPE_SECRET_KEY!, }), ], secretKey: mppSecretKey,});app.get('/api/analysis', async (req, res) => { const result = await mppx.charge({ amount: '1', currency: 'usd', decimals: 2, description: 'AI数据分析接口 - 单次调用', })(req); if (result.status === 402) { // 返回支付要求 return res.status(402).set(result.challenge.headers).json({ error: 'payment_required', }); } // 支付成功,返回数据并附上收据 const response = result.withReceipt( new Response(JSON.stringify({ data: '分析结果...' })) ); res.status(200).set(Object.fromEntries(response.headers)).json({ data: '分析结果...', });});app.listen(3000);
该方案的关键点:Mppx.create初始化时配置支持的支付方式,mppx.charge处理完整的Challenge-Credential-Receipt流程。如果请求没带支付凭证,返回402;带了合法凭证,自动创建Stripe PaymentIntent完成扣款。如果要支持稳定币支付(适合小额微交易),换成Tempo方式:
import { Mppx, tempo } from 'mppx/server';const PATH_USD = '0x20c0000000000000000000000000000000000000';const mppx = Mppx.create({ methods: [ tempo.charge({ currency: PATH_USD, recipient: '0x你的钱包地址', testnet: true, // 测试网 }), ], secretKey: mppSecretKey,});// charge时不需要指定currency,直接给金额const result = await mppx.charge({ amount: '0.01', // 0.01 USD recipient: '0x你的钱包地址',})(request);
两种方式也可以同时支持,用Mppx.compose让客户端自己选:
const mppx = Mppx.create({ methods: [ stripe.charge({ /* ... */ }), tempo.charge({ /* ... */ }), ], secretKey: mppSecretKey,});
客户端:Agent怎么自动付款
SDK的客户端更简单。核心思路是包装fetch函数,遇到402自动处理支付:
import { Mppx, stripe } from 'mppx/client';const client = Mppx.create({ methods: [ stripe.charge({ // SPT token,由Agent的支付服务提供 sharedPaymentToken: 'spt_xxx', }), ],});// 正常发请求就行,402会自动处理const response = await client.fetch('https://api.example.com/analysis');const data = await response.json();console.log(data); // 直接拿到数据,支付在后台完成了
Mppx.create返回一个增强版的fetch,碰到402会自动:解析Challenge → 生成Credential → 带凭证重试请求。对业务代码来说完全透明。MPP还支持MCP(Model Context Protocol)传输,AI Agent调用MCP工具时也能自动付款:
import { McpClient } from 'mppx/client';// 包装MCP客户端,工具调用遇到402自动付款const paidMcpClient = McpClient.wrap(originalMcpClient, { methods: [stripe.charge({ sharedPaymentToken: 'spt_xxx' })],});
这意味着Agent通过MCP调用外部工具时,如果工具收费,MPP能自动搞定支付,不需要Agent开发者写任何支付逻辑。
计费模式:不只是按次收费
MPP不只支持单次收费(charge),还支持会话式按量计费(session)。这对API服务商来说很实用。按次收费适合独立的API调用,比如一次图片生成、一次数据查询。会话计费适合流式场景,比如LLM的token流。服务器开一个支付通道,按实际消耗扣费:
// 服务端 - 流式按token计费import { tempo } from 'mppx/server';const sessionMethod = tempo.session({ currency: PATH_USD, recipient: walletAddress,});// 每个token 0.00001 USD// 通过SSE流式返回,边生成边扣费
该模式下Agent不需要预付一大笔钱,用多少付多少,粒度可以细到单个token。对AI Agent场景来说这很关键——Agent可能调用一个API只用了10个token就拿到答案了,不需要按月订阅。
安全设计
MPP的Challenge用HMAC签名绑定到具体请求,防止重放攻击。每个Challenge有过期时间,Credential只能用一次。几个值得注意的安全细节:Challenge绑定:Challenge里包含了请求的URL、方法、body哈希等信息。Agent不能拿一个便宜接口的Challenge去访问贵的接口。Body Digest:POST请求的body会计算哈希值放在Challenge里,防止支付后篡改请求内容。Secret Key:服务端的secretKey用来签名Challenge,确保Challenge确实是自己签发的,不是伪造的。生产环境这个key必须持久化存储,否则服务重启后之前发出的Challenge全部失效。
// 生产环境:从环境变量读取,不要每次随机生成const mppSecretKey = process.env.MPP_SECRET_KEY!;// 开发环境可以随机生成const mppSecretKey = crypto.randomBytes(32).toString('base64');
已经在用的场景
Stripe博客提到了几个已经接入MPP的商家:Browserbase:Agent按次付费使用无头浏览器。以前Agent要用Browserbase得注册账号、选套餐、拿API Key。现在直接请求,402付款,拿到浏览器session。PostalForm:Agent付费发送实体信件。对,物理世界的纸质信件。Agent在workflow里需要寄一封信?直接调API付款寄出。Prospect Butcher Co.:Agent帮人类订三明治。这个用例看起来搞笑但其实很实际——以后Agent帮你订外卖、买咖啡就是这个路子。这些用例有个共同点:都是Agent直接完成交易,不需要跳转到网页让人类操作。
和x402的关系
MPP不是唯一在搞机器支付的项目。Coinbase之前推了个x402协议,思路差不多也是基于HTTP 402。区别是x402只支持加密货币(Base链上的USDC),MPP同时支持法币和加密货币。Stripe在文档里提到他们同时支持MPP和x402,不排斥。但从SDK的完整度和商家接入便利性来看,MPP明显更成熟。毕竟背后是Stripe的支付基础设施,商家不需要单独搞加密钱包就能接入。
对前端开发者意味着什么
如果你在做API服务、SaaS产品、或者任何可能被AI Agent调用的服务,MPP值得关注。短期:给你的API加一层MPP支付网关,AI Agent就能直接付费使用。不需要维护用户系统、订阅管理、计费逻辑——Stripe全搞定。中期:微交易会成为新的商业模式。一个API调用收0.01美元,人类觉得太碎不值得付,但Agent完全不在乎。高频微交易的总量可能很可观。长期:当Agent能自己管理预算和支付时,”Agent经济”就不是空话了。Agent A调用Agent B的服务,Agent B调用Agent C的数据,每一跳都通过MPP自动结算。需要注意的是,MPP目前还在早期。稳定币支付只对美国商家开放,SDK的TypeScript版本最完整,Python和Rust还在追赶。Challenge的签名机制虽然设计合理,但在高并发场景下secretKey的管理和Challenge缓存需要额外考虑。
动手试试
Stripe提供了完整的示例代码仓库:
git clone https://github.com/stripe-samples/machine-paymentscd machine-paymentsnpm installcp .env.example .env# 填入你的 Stripe Secret Keynpm start
TypeScript SDK:
npm install mppx
协议规范和文档:mpp.devStripe接入文档:docs.stripe.com/payments/machine/mpp目前接入需要向Stripe申请开通machine payments功能,发邮件到machine-payments@stripe.com。402这个”保留给未来使用”的状态码等了26年,终于等到了它的未来。只不过这个未来的用户不是人类,是AI。