← Создание агентов на Cloudflare / agents / tools / payments / mpp
Оплата из Agents SDK
Используйте Cloudflare Agents SDK для оплаты сервисов MPP. mppx SDK обрабатывает повторные попытки платежей для HTTP-запросов и вызовов инструментов Model Context Protocol (MCP).
Предварительные требования
Создайте проект Cloudflare Agents. Пополните счёт для способа оплаты, который принимает сервис.
Настройка платежей
-
Установите Agents SDK,
mppx, а такжеviem:npm i agents mppx viem -
Сохраните закрытый платёжный ключ как Секрет Worker:
npx wrangler secret put MPP_PRIVATE_KEY -
Создайте способ оплаты один раз:
src/payments.jsimport { tempo } from "mppx/client"; import { privateKeyToAccount } from "viem/accounts"; export function createPaymentMethods(privateKey) { const account = privateKeyToAccount(privateKey); return [tempo.charge({ account })]; }src/payments.tsimport { tempo } from "mppx/client"; import { privateKeyToAccount } from "viem/accounts"; export function createPaymentMethods(privateKey: string) { const account = privateKeyToAccount(privateKey as `0x${string}`); return [tempo.charge({ account })] as const; }
Оплата HTTP-сервиса
Создайте платёжный клиент в onStart(). Ограничивайте автоматические платежи доверенными origins:
import { Agent } from "agents";
import { Mppx } from "mppx/client";
import { createPaymentMethods } from "./payments";
export class BuyerAgent extends Agent {
methods;
payments;
async onStart() {
this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
this.payments = Mppx.create({
acceptPaymentPolicy: { origins: ["https://api.example.com"] },
methods: this.methods,
polyfill: false,
});
}
async buyReport() {
const response = await this.payments.fetch(
"https://api.example.com/reports/latest",
);
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
return response.json();
}
}import { Agent } from "agents";
import { Mppx } from "mppx/client";
import { createPaymentMethods } from "./payments";
type PaymentEnv = Env & { MPP_PRIVATE_KEY: string };
export class BuyerAgent extends Agent<PaymentEnv> {
methods!: ReturnType<typeof createPaymentMethods>;
payments!: ReturnType<typeof Mppx.create>;
async onStart() {
this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
this.payments = Mppx.create({
acceptPaymentPolicy: { origins: ["https://api.example.com"] },
methods: this.methods,
polyfill: false,
});
}
async buyReport() {
const response = await this.payments.fetch(
"https://api.example.com/reports/latest",
);
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
return response.json();
}
}Бесплатные эндпойнты проходят без изменений. Платные эндпойнты запускают повтор оплаты и возвращают Payment-Receipt заголовок.
Оплата инструмента MCP
Подключите Agent к addMcpServer(). Дождитесь установления соединения, прежде чем оборачивать его клиент:
import { Agent } from "agents";
import { McpClient } from "mppx/mcp/client";
import { createPaymentMethods } from "./payments";
export class BuyerAgent extends Agent {
methods;
async onStart() {
this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
}
async paidSearch() {
const connection = await this.addMcpServer(
"premium-search",
"https://mcp.example.com/mcp",
);
if (connection.state === "authenticating") {
return { authUrl: connection.authUrl };
}
await this.mcp.waitForConnections();
const server = this.getMcpServers().servers[connection.id];
const mcpConnection = this.mcp.mcpConnections[connection.id];
if (server?.state !== "ready" || !mcpConnection) {
throw new Error("MCP server is not ready.");
}
const client = McpClient.wrap(mcpConnection.client, {
methods: this.methods,
});
const result = await client.callTool({
name: "premium_search",
arguments: { query: "Cloudflare Agents" },
});
return { content: result.content, receipt: result.receipt };
}
}import { Agent } from "agents";
import { McpClient } from "mppx/mcp/client";
import { createPaymentMethods } from "./payments";
type PaymentEnv = Env & { MPP_PRIVATE_KEY: string };
export class BuyerAgent extends Agent<PaymentEnv> {
methods!: ReturnType<typeof createPaymentMethods>;
async onStart() {
this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
}
async paidSearch() {
const connection = await this.addMcpServer(
"premium-search",
"https://mcp.example.com/mcp",
);
if (connection.state === "authenticating") {
return { authUrl: connection.authUrl };
}
await this.mcp.waitForConnections();
const server = this.getMcpServers().servers[connection.id];
const mcpConnection = this.mcp.mcpConnections[connection.id];
if (server?.state !== "ready" || !mcpConnection) {
throw new Error("MCP server is not ready.");
}
const client = McpClient.wrap(mcpConnection.client, {
methods: this.methods,
});
const result = await client.callTool({
name: "premium_search",
arguments: { query: "Cloudflare Agents" },
});
return { content: result.content, receipt: result.receipt };
}
}Если paidSearch() возвращает authUrl, отправьте пользователя на этот URL и повторите попытку после авторизации.
Wrapper повторяет платный вызов инструмента с MPP Credential. Результат включает MPP Receipt как result.receipt.
По умолчанию оба клиента автоматически оплачивают совместимые Challenges. Используйте onChallenge для HTTP или onPaymentRequired для MCP, когда платёж требует одобрения. Суммы Challenge представляют собой целые числа в базовых единицах, а не десятичные отображаемые значения.
Оплата сервисов x402
mppx HTTP-клиент также распознаёт x402 Challenges. Настройте EVM-совместимый метод x402 рядом с методом MPP. Изменения на стороне сервиса не требуются. Инструкции по настройке см. в Используйте MPP с x402 ↗.
Чтобы принимать платежи, см. Принимайте платежи с помощью MPP. Для параметров подключения MCP см. API MCP-клиента.