Nevermined Payments Integration
概览
Nevermined 提供了 AI 代理的金融轨道 — 实时货币化、访问控制和支付。这项技能为您提供了所需的一切:
- 使用 x402支付协议 保护 API 端点
- 使用 基于信用的计费 按请求收费
- 与 Express.js、FastAPI、Strands代理、MCP服务器 或 Google A2A代理 集成
- 支持 订阅方 流程(购买计划、生成令牌、调用受保护的API)
- 通过 Google A2A 协议启用 代理到代理 支付
x402协议使用 HTTP 402 响应来宣传支付需求。客户端获取访问令牌并重试请求。服务器验证权限,执行工作负载,然后结算(消耗信用)。
快速开始清单
- 在 nevermined.app → 设置 → API密钥处 获取API密钥
- 安装SDK (
npm install @nevermined-io/payments或pip install payments-py) - (通过App UI或以编程方式 — 见
references/payment-plans.md)注册您的代理和计划 - 向您的路由/工具添加支付保护(见下面特定于框架的参考)
- 测试 — 无令牌调用(预期402),然后使用令牌调用(预期200)
环境设置
| 变量 | 必需 | 描述 |
|---|---|---|
NVM_API_KEY |
是 | 您的 Nevermined API密钥(在 nevermined.app → 设置 → API密钥处获得) |
NVM_ENVIRONMENT |
是 | sandbox 用于测试,live 用于生产 |
NVM_PLAN_ID |
是 | 注册时的计划ID |
NVM_AGENT_ID |
有时 | MCP服务器和具有多个代理的计划需要 |
BUILDER_ADDRESS |
注册时必需 | 接收支付的钱包地址 |
.env模板
# 必需
NVM_API_KEY=your-api-key-here
NVM_ENVIRONMENT=sandbox
NVM_PLAN_ID=your-plan-id-here
# MCP服务器或多代理计划必需
NVM_AGENT_ID=your-agent-id-here
# 注册必需
BUILDER_ADDRESS=0xYourWalletAddress
前提条件
- TypeScript/Express.js: Node.js 18+。您的
package.json必须包含"type": "module"以使@nevermined-io/payments/express子路径导入工作。 - Python/FastAPI: Python 3.9+。安装
pip install payments-py[fastapi]— 中间件需要[fastapi]额外包。
TypeScript
npm install @nevermined-io/payments
import { Payments } from '@nevermined-io/payments'
const payments = Payments.getInstance({
nvmApiKey: process.env.NVM_API_KEY!,
environment: 'sandbox'
})
Python
pip install payments-py
import os
from payments_py import Payments, PaymentOptions
payments = Payments.get_instance(
PaymentOptions(
nvm_api_key=os.environ["NVM_API_KEY"],
environment="sandbox"
)
)
核心工作流程(所有集成)
每个 Nevermined 支付集成都遵循这个5步模式:
- 客户端发送请求 无支付令牌
- 服务器返回402 带有
payment-required头(base64编码的JSON,带有计划信息) - **客户端通过
payments.x402.getX402AccessToken(planId, agentId)获取 x402令牌 - 客户端重试 使用
payment-signature头包含令牌 - 服务器验证 → 执行 → 结算(消耗信用),返回带有
payment-response头的响应
框架决策树
选择与您的堆栈匹配的集成:
| 框架 | 语言 | 参考 | 关键导入 |
|---|---|---|---|
| Express.js | TypeScript/JS | references/express-integration.md |
paymentMiddleware 来自 @nevermined-io/payments/express |
| FastAPI | Python | references/fastapi-integration.md |
PaymentMiddleware 来自 payments_py.x402.fastapi |
| Strands Agent | Python | references/strands-integration.md |
@requires_payment 来自 payments_py.x402.strands |
| MCP Server | TypeScript | references/mcp-paywall.md |
payments.mcp.start() / payments.mcp.registerTool() |
| Google A2A | TS / Python | references/a2a-integration.md |
payments.a2a.start() / payments.a2a.buildPaymentAgentCard() |
| Any HTTP | 任何 | references/x402-protocol.md |
通过facilitator API手动验证/结算 |
| Client-side | TS / Python | references/client-integration.md |
payments.x402.getX402AccessToken() |
SDK快速参考
TypeScript (@nevermined-io/payments)
// 初始化
const payments = Payments.getInstance({ nvmApiKey, environment })
// 注册代理+计划
const { agentId, planId } = await payments.agents.registerAgentAndPlan(
agentMetadata, agentApi, planMetadata, priceConfig, creditsConfig
)
// 订阅方:订购计划并获得令牌
await payments.plans.orderPlan(planId)
const balance = await payments.plans.getPlanBalance(planId)
const { accessToken } = await payments.x402.getX402AccessToken(planId, agentId)
// 服务器:验证和结算
const verification = await payments.facilitator.verifyPermissions({
paymentRequired, x402AccessToken: token, maxAmount: BigInt(credits)
})
const settlement = await payments.facilitator.settlePermissions({
paymentRequired, x402AccessToken: token, maxAmount: BigInt(creditsUsed)
})
// 辅助工具
import { buildPaymentRequired } from '@nevermined-io/payments'
import { paymentMiddleware, X402_HEADERS } from '@nevermined-io/payments/express'
// MCP服务器
payments.mcp.registerTool(name, config, handler, { credits: 5n })
const { info, stop } = await payments.mcp.start({ port, agentId, serverName })
// A2A服务器
const agentCard = payments.a2a.buildPaymentAgentCard(baseCard, { paymentType, credits, planId, agentId })
const server = await payments.a2a.start({ port, basePath: '/a2a/', agentCard, executor })
// A2A客户端
const client = payments.a2a.getClient({ agentBaseUrl, agentId, planId })
await client.sendMessage("Hello", accessToken)
Python (payments-py)
# 初始化
payments = Payments.get_instance(PaymentOptions(nvm_api_key=key, environment="sandbox"))
# 注册代理+计划
result = payments.agents.register_agent_and_plan(
agent_metadata, agent_api, plan_metadata, price_config, credits_config
)
# 订阅方:订购计划并获得令牌
payments.plans.order_plan(plan_id)
balance = payments.plans.get_plan_balance(plan_id)
token_res = payments.x402.get_x402_access_token(plan_id, agent_id)
# 服务器:验证和结算
verification = payments.facilitator.verify_permissions(
payment_required=pr, x402_access_token=token, max_amount=str(credits)
)
settlement = payments.facilitator.settle_permissions(
payment_required=pr, x402_access_token=token, max_amount=str(credits_used)
)
# 辅助工具
from payments_py.x402.helpers import build_payment_required
from payments_py.x402.fastapi import PaymentMiddleware
from payments_py.x402.strands import requires_payment
# A2A服务器
from payments_py.a2a.agent_card import build_payment_agent_card
from payments_py.a2a.server import PaymentsA2AServer
agent_card = build_payment_agent_card(base_card, { ... })
server = PaymentsA2AServer.start(agent_card=agent_card, executor=executor, payments_service=payments, port=3005)
# A2A客户端
client = payments.a2a.get_client(agent_base_url=url, agent_id=agent_id, plan_id=plan_id)
x402支付头
所有 x402 v2 集成使用这三个HTTP头:
| 头 | 方向 | 描述 |
|---|---|---|
payment-signature |
客户端 → 服务器 | x402访问令牌 |
payment-required |
服务器 → 客户端 (402) | Base64编码的JSON,带有计划要求 |
payment-response |
服务器 → 客户端 (200) | Base64编码的JSON结算收据 |
payment-required 负载结构:
{
"x402Version": 2,
"accepts": [{
"scheme": "nvm:erc4337",
"network": "eip155:84532",
"planId": "<plan-id>",
"extra": { "agentId": "<agent-id>" }
}]
}
支付计划类型
Nevermined 支持几种计划类型:
- 基于信用的:预付费余额,按请求扣除(API最常见)
- 基于时间的:固定期限内的访问(例如,30天无限)
- 按需支付(PAYG):按请求结算USDC,无信用余额
- 试用:免费有限访问,每个用户一次
- 混合:将信用与时间到期结合
见 references/payment-plans.md 了解计划注册代码。
常见模式
Express.js — 每条路线固定信用
import { paymentMiddleware } from '@nevermined-io/payments/express'
app.use(paymentMiddleware(payments, {
'POST /ask': { planId: PLAN_ID, credits: 1 },
'POST /generate': { planId: PLAN_ID, credits: 5 }
}))
FastAPI — 每条路线固定信用
from payments_py.x402.fastapi import PaymentMiddleware
app.add_middleware(
PaymentMiddleware,
payments=payments,
routes={
"POST /ask": {"plan_id": PLAN_ID, "credits": 1},
"POST /generate": {"plan_id": PLAN_ID, "credits": 5}
}
)
Express.js — 基于响应的动态信用
paymentMiddleware(payments, {
'POST /generate': {
planId: PLAN_ID,
credits: (req, res) => {
const tokens = res.locals.tokenCount || 100
return Math.ceil(tokens / 100)
}
}
})
FastAPI — 基于请求的动态信用
async def calculate_credits(request: Request) -> int:
body = await request.json()
max_tokens = body.get("max_tokens", 100)
return max(1, max_tokens // 100)
app.add_middleware(
PaymentMiddleware,
payments=payments,
routes={"POST /generate": {"plan_id": PLAN_ID, "credits": calculate_credits}}
)
MCP服务器 — 注册带支付墙的工具
payments.mcp.registerTool(
"weather.today",
{ title: "Today's Weather", inputSchema: z.object({ city: z.string() }) },
async (args, extra, context) => ({
content: [{ type: "text", text: `Weather in ${args.city}: Sunny, 25C` }]
}),
{ credits: 5n }
)
const { info, stop } = await payments.mcp.start({
port: 3000,
agentId: process.env.NVM_AGENT_ID!,
serverName: "my-server"
})
Strands代理 — 基于装饰器的支付
from strands import Agent, tool
from payments_py.x402.strands import requires_payment
@tool(context=True)
@requires_payment(payments=payments, plan_id=PLAN_ID, credits=1)
def analyze_data(query: str, tool_context=None) -> dict:
return {"status": "success", "content": [{"text": f"Analysis: {query}"}]}
agent = Agent(tools=[analyze_data])
Google A2A — 代理服务器与支付扩展
TypeScript
const agentCard = payments.a2a.buildPaymentAgentCard(baseAgentCard, {
paymentType: "dynamic",
credits: 1,
planId: process.env.NVM_PLAN_ID!,
agentId: process.env.NVM_AGENT_ID!,
})
const server = await payments.a2a.start({
port: 3005,
basePath: '/a2a/',
agentCard,
executor: new MyExecutor(),
})
Python
from payments_py.a2a.agent_card import build_payment_agent_card
from payments_py.a2a.server import PaymentsA2AServer
agent_card = build_payment_agent_card(base_agent_card, {
"paymentType": "dynamic",
"credits": 1,
"planId": os.environ["NVM_PLAN_ID"],
"agentId": os.environ["NVM_AGENT_ID"],
})
server = PaymentsA2AServer.start(
agent_card=agent_card,
executor=MyExecutor(),
payments_service=payments,
port=3005,
base_path="/a2a/",
)
Google A2A — 客户端发送付费任务
const client = payments.a2a.getClient({
agentBaseUrl: 'http://localhost:3005/a2a/',
agentId: AGENT_ID,
planId: PLAN_ID,
})
const { accessToken } = await payments.x402.getX402AccessToken(PLAN_ID, AGENT_ID)
const response = await client.sendMessage("Analyze this data", accessToken)
预先收集开发者信息
当开发者要求您集成 Nevermined 支付时,一次性收集所有所需信息,以生成代码。这避免了多次来回交互。
一次性询问开发者:
- 框架:Express.js、FastAPI、MCP服务器、Strands代理、Google A2A,还是通用HTTP?
- 要保护的路由:哪些端点需要支付保护,每个端点多少信用?(例如,
POST /chat = 1 credit, POST /generate = 5 credits) - 定价模型:固定信用每请求,还是基于请求/响应参数的动态定价?
- Nevermined API密钥:他们已经有
NVM_API_KEY了吗?如果没有,引导他们到 nevermined.app → 设置 → API密钥 - 计划ID:他们已经有
NVM_PLAN_ID了吗?如果没有,他们还需要注册脚本吗? - 环境:
sandbox(测试)还是live(生产)?
如果他们需要计划注册,还问:
- 计划名称和描述:例如,“Starter Plan — 100 API请求”
- 定价:USDC多少?(例如,100信用10 USDC)
- 计划信用:包含的总信用(例如,100)
- 构建者钱包地址(
BUILDER_ADDRESS):接收支付的钱包
向开发者提供的示例组合提示:
我需要设置 Nevermined 支付。这是我的信息:
- 框架:Express.js
- 路由:POST /chat(1信用),POST /summarize(3信用)
- 我需要一个注册脚本
- 计划:“Starter Plan”,100信用10 USDC
- 环境:sandbox
- 我的API密钥在NVM_API_KEY环境变量中
- 我的钱包:0x1234…
有了这些信息,一次性生成注册脚本和受支付保护的服务器。
代理和计划注册
使用SDK(推荐)
以编程方式注册您的代理和计划 — 见 references/payment-plans.md 了解完整代码。
// TypeScript
const { agentId, planId } = await payments.agents.registerAgentAndPlan(
{ name: 'My Agent', description: 'AI service', tags: ['ai'], dateCreated: new Date() },
{ endpoints: [{ POST: 'https://your-api.com/query' }] },
{ name: 'Starter Plan', description: '100 requests for $10', dateCreated: new Date() },
payments.plans.getERC20PriceConfig(10_000_000n, USDC_ADDRESS, process.env.BUILDER_ADDRESS!),
payments.plans.getFixedCreditsConfig(100n, 1n)
)
# Python
result = payments.agents.register_agent_and_plan(
agent_metadata={'name': 'My Agent', 'description': 'AI service', 'tags': ['ai']},
agent_api={'endpoints': [{'POST': 'https://your-api.com/query'}]},
plan_metadata={'name': 'Starter Plan', 'description': '100 requests for $10'},
price_config=get_erc20_price_config(10_000_000, USDC_ADDRESS, os.environ['BUILDER_ADDRESS']),
credits_config=get_fixed_credits_config(100, 1)
)
使用Nevermined App(无代码)
- 访问 nevermined.app 并登录
- 点击 “我的代理” → 注册一个新代理,包含元数据和端点
- 创建支付计划:设置定价、信用和期限
- 将计划链接到您的代理并发布
- 复制
agentId和planId到您的.env文件
使用CLI
# 1. 安装CLI
npm install -g @nevermined-io/cli
# 2. 配置(测试使用sandbox)
nvm config init --api-key "$NVM_API_KEY" --environment sandbox
# 3. 注册代理和计划一起
nvm agents register-agent-and-plan \
--agent-metadata '{"name":"My Agent","description":"AI service"}' \
--agent-api '{"endpoints":[{"POST":"https://your-api.com/query"}]}' \
--plan-metadata '{"name":"Starter Plan","description":"100 requests"}' \
--price-config '{"tokenAddress":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","price":10000000,"amountOfCredits":100}' \
--credits-config '{"minCreditsRequired":1,"minCreditsToCharge":1,"maxCreditsToCharge":10}'
# 4. 列出您的计划
nvm plans get-plans
# 5. 作为订阅方:订购计划并获得x402令牌
nvm plans order-plan $PLAN_ID
nvm x402token get-x402-access-token $PLAN_ID --agent-id $AGENT_ID
# 6. 测试您的运行服务器
curl -X POST http://localhost:3000/chat \
-H "Content-Type: application/json" \
-H "payment-signature: $TOKEN" \
-d '{"message": "Hello"}'
故障排除
| 症状 | 原因 | 修复 |
|---|---|---|
| HTTP 402返回 | 没有 payment-signature 头或令牌无效/过期 |
通过 getX402AccessToken 生成新令牌 |
| MCP错误-32003 | 支付所需 — 没有令牌、令牌无效或信用不足 | 检查订阅方是否购买了计划并有剩余信用 |
| MCP错误-32002 | 服务器配置错误 | 验证 NVM_API_KEY、NVM_PLAN_ID 和 NVM_AGENT_ID 设置是否正确 |
verification.isValid 为false |
令牌过期、错误的计划或信用不足 | 重新订购计划或生成新令牌 |
| 信用不扣除 | 请求后未调用结算 | 确保处理后调用 settlePermissions(中间件自动执行此操作) |
payment-required 头缺失 |
服务器未正确返回402 | 使用 buildPaymentRequired() 辅助工具或框架中间件 |
额外资源
- 文档:nevermined.ai/docs
- Nevermined App:nevermined.app — 注册代理,创建计划,管理订阅
- MCP搜索服务器:
https://docs.nevermined.app/mcp— 从任何MCP客户端搜索Nevermined文档 - 教程:github.com/nevermined-io/tutorials
- Discord:discord.com/invite/GZju2qScKq
- TypeScript SDK:
@nevermined-io/payments在npm上 - Python SDK:
payments-py在PyPI上