尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring AI Agent实战:订单系统对接支付宝MCP,TaoToken统一Key让支付渠道配置像说话一样简单

Spring AI Agent实战:订单系统对接支付宝MCP,TaoToken统一Key让支付渠道配置像说话一样简单 1. 订单系统接支付宝MCP到底难在哪Spring AI Agent 支付渠道对接的真实场景做订单系统的同学大概率都经历过这样的循环产品说这周要上支付宝你打开开放平台文档先被网关地址、应用私钥、支付宝公钥、AES 密钥绕一圈接着是签名算法 RSA2、参数排序、URL 编码再往下是异步通知验签、交易状态轮询、退款接口的 out_request_no 幂等。等你好不容易把AlipayTradePagePayRequest调通回头一看代码里散落着五六个配置文件、三套环境参数、两处硬编码的 appId换一个渠道微信、银联又要重来一遍。Spring AI Agent 加 MCP 这套组合解决的正是渠道调用入口不统一这件事。MCPModel Context Protocol你可以理解成给大模型和外部服务之间定了一个插座标准支付宝的支付能力被封装成一个 MCP Server暴露create_order、query_order、refund这类工具ToolSpring AI 的 Agent 通过 MCP Client 连上去用自然语言描述意图模型自己决定调哪个工具、传什么参数。订单系统这边只需要关心我要收钱和钱到了要改状态签名和参数拼装交给 MCP Server 内部处理。但真正落地时会撞上第二个问题模型调用本身也需要凭证。你要接 DeepSeek、Claude 或者别的模型来驱动 Agent每家一个 Key、一套 Base URL、一套计费口径测试环境切生产环境还得改配置。这就是本文要引入 TaoToken 的原因——它把模型调用收敛成一个统一 Key 和一个统一 API 入口https://taotoken.net/apiAgent 侧只认这一套凭证支付渠道的 MCP 配置和模型凭证解耦换模型不动支付代码换支付渠道不动模型配置。这篇适合谁手上有一个 Spring Boot 订单系统、想用 Spring AI 做 Agent 化改造、并且准备接支付宝沙箱也行的后端开发。读完之后你应该能拿到三样东西一份可复制的 MCP Server 与 MCP Client 配置、一段能跑通的订单支付 Agent 代码、一张验证渠道连通性和回调的检查清单。下面按先讲清问题、再备好 Key、然后贴配置、接着验证、最后排错的顺序走每一步都给完整命令和参数。2. 前置准备TaoToken 统一 Key 与支付宝沙箱参数怎么备齐这一章解决动手之前手里得有哪几样东西。很多人卡在第一步不是因为不会写代码而是凭证没备齐跑到一半报 401 又回头找 Key节奏全乱。我建议你按下面的顺序一次性备完后面配置阶段就能一路贴过去。先说 TaoToken 这一侧。它的定位是模型调用的统一入口你注册后在控制台创建一个 API Key这个 Key 同时能调对话模型、能配合 Coding Plan 做长期编码任务Base URL 统一填https://taotoken.net/api。对本文的场景来说Agent 需要一个能稳定跑工具调用的模型你可以在模型对话页面先确认目标模型可用再去 API Keys 页面生成密钥。生成时注意两点一是 Key 只在创建时完整显示一次复制到密码管理器二是给这个 Key 起个能区分的名字比如order-agent-dev后面测试环境和生产环境各用一个出问题好定位。具体操作路径我列一下你照着点就行打开官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite注册并登录。进控制台的 API Keys 页面deep linkhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite点创建拿到形如sk-开头的字符串。想先验证模型通不通去模型对话页https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite发一句话试试确认账号状态正常。如果你打算长期跑 Agent 编码和调试Coding Plan 页面https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite有对应的套餐说明按需选。再说支付宝这一侧。个人开发者没有商户资质完全不影响练手用沙箱环境即可。你需要去支付宝开放平台创建应用选网页/移动应用开通电脑网站支付或手机网站支付然后在沙箱里拿到四个关键参数appId、应用私钥、支付宝公钥、网关地址沙箱是https://openapi-sandbox.dl.alipaydev.com/gateway.do。另外原文提到调用 MCP 服务需要在开放平台申请 MCP 场景受限密钥这一步别忘了否则 MCP Server 侧鉴权会失败。把两边的参数整理成一张表后面配置直接查参数来源用途存放建议TaoToken API KeyTaoToken 控制台 API KeysAgent 调模型环境变量TAOTOKEN_API_KEYTaoToken Base URL固定https://taotoken.net/api模型请求入口配置文件模型 ID模型对话页确认指定 Agent 用哪个模型配置文件支付宝 appId开放平台沙箱标识商户应用环境变量应用私钥开放平台密钥工具生成请求签名密钥文件勿入库支付宝公钥开放平台下载回调验签密钥文件MCP 场景受限密钥开放平台申请MCP Server 鉴权环境变量这里有个容易忽略的点TaoToken 的 Key 和支付宝的密钥是两套完全独立的东西前者管模型怎么被调用后者管支付请求怎么被签名。把它们分开存、分开轮换是这套架构比传统写法更清爽的地方。你可以在.env里只放 TaoToken 的 Key支付宝密钥走文件挂载避免一个配置文件泄露带走全部凭证。3. 可复制配置Spring AI MCP Server 与 Client 的完整片段这一章是全文的技术核心给的是能直接落盘的配置和代码。整体结构分两个 Spring Boot 应用mcp-server-order负责本地订单业务建单、改状态、退款order-agent负责接模型、连 MCP、对外暴露/buy和/callback。两个应用通过 MCP 协议通信order-agent同时连两个 MCP Server本地的订单服务和远端的支付宝服务。先看mcp-server-order的pom.xml依赖关键是spring-ai-starter-mcp-server-webmvc它让 MCP Server 以 SSE 方式暴露dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /dependency /dependencies它的application.yml要开 Web 端口SSE 模式必须并配好数据源spring: ai: mcp: server: name: mcp-server-order version: 0.0.1 datasource: url: jdbc:mysql://127.0.0.1:3306/demodb?useSSLfalseuseUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: xgourd password: xgourd123 server: port: 8081订单工具类用Tool注解暴露能力模型看到的是 description 里的自然语言所以描述要写清楚什么时候该调Service AllArgsConstructor public class OrderService { private final OrderRepository orderRepository; Tool(description 根据客户购买的套餐本地生成一笔待支付订单) public Order createOrder(ToolParam(description 客户手机号) String phoneNo, ToolParam(description 购买套餐的数字编号) String pkgNo) { return orderRepository.save(new Order() .setOrderNo(System.currentTimeMillis() ) .setProductNo(pkgNo) .setOrderAmount(PKGS.get(pkgNo)) .setCustomerId(phoneNo) .setCreateTime(new Date()) .setOrderStatus(0)); } Tool(description 完成本地订单更新状态为已支付并记录支付宝交易号) public void complete(ToolParam(description 本地订单号) String orderNo, ToolParam(description 支付宝订单号) String alipayTradeNo) { Order order orderRepository.findByOrderNo(orderNo).orElseThrow(); orderRepository.save(order.setOrderStatus(2).setAlipayTradeNo(alipayTradeNo)); } }工具注册用一个Bean收口Bean public ToolCallbackProvider dataTool(OrderService orderService) { return MethodToolCallbackProvider.builder().toolObjects(orderService).build(); }再看order-agent的pom.xml需要 MCP Client 和模型 starterdependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.alibaba/groupId artifactIdfastjson/artifactId /dependency /dependencies它的application.yml是全文最该抄走的一段注意模型部分走 TaoToken 的统一入口MCP 部分用 SSE 连两个 Serverspring: application: name: order-agent ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: https://taotoken.net/api chat: options: model: deepseek-v3 mcp: client: sse: connections: ali: url: https://mcp.api-inference.modelscope.net sse-endpoint: /cb8d2f1aad9341/sse order: url: http://localhost:8081 toolcallback: enabled: false logging: level: [io.modelcontextprotocol.client]: debug [io.modelcontextprotocol.spec]: debug这里解释三个参数为什么这么填。base-url指向 TaoToken 的 API 入口api-key从环境变量注入避免明文model填你在模型对话页确认过的 ID。MCP 的ali连接指向支付宝 MCP 服务的 SSE 端点order连接指向本地 8081。原文踩过的坑值得强调Spring AI 里用 stdio 方式调支付宝 MCP 对参数限制很死改成 SSE 才调通所以这里统一走 SSE。Agent 入口类把 MCP Client 注入 ChatClient并暴露下单和回调两个接口SpringBootApplication RestController public class AgentApplication { private final ChatClient chatClient; public AgentApplication(ListMcpSyncClient mcpClients, ChatClient.Builder builder) { this.chatClient builder .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients)) .build(); } PostMapping(/buy) public void buy(RequestParam String phone, RequestParam String plan, HttpServletResponse response) throws IOException { String prompt 请根据用户输入信息: 手机号: %s, 套餐号: %s 1. 生成一笔本地订单; 2. 将订单号、订单金额、订单主题作为参数生成支付宝订单返回支付链接; 3. 输出格式{url:https://xxx} .formatted(phone, plan); String resp chatClient.prompt(prompt).call().content() .replace(json, ).replace(, ); String url JSON.parseObject(resp).getString(url); response.sendRedirect(url); } GetMapping(/callback) public String callback(RequestParam MapString, String params) { String prompt 根据回调参数: %s, 完成本地订单 1. 将本地订单状态更新为已支付, 并记录支付宝交易号; 2. 本地订单号是 out_trade_no, 支付宝交易号是 trade_no .formatted(JSON.toJSONString(params)); return chatClient.prompt(prompt).call().content(); } }如果你用 Claude Code 做辅助开发可以在~/.claude/settings.json里把模型入口也指到统一通道三件套是 Base URLhttps://taotoken.net/api、Key 用同一个TAOTOKEN_API_KEY、Model ID 与上面一致Cline 的 MCP 配置同理把order和ali两个 SSE 连接照抄进它的 MCP servers 配置即可。Codex 用户则在auth.json里填同一套 Base URL 和 Key保证本地调试和线上 Agent 用的是同一份凭证。4. 验证请求与成功结果用测试订单跑通支付链路配置贴完不等于通了这一章给的是怎么确认它真的在工作。验证分三层模型层、MCP 工具层、支付回调层逐层往上任何一层失败都能快速定位。第一层先确认 TaoToken 的模型通道可用。不用写代码直接用 curl 打一次对话接口curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: deepseek-v3, messages: [{role: user, content: 回复 ok}] }返回体里choices[0].message.content有内容就说明 Key 和 Base URL 都对。如果这里就报 401别往下走先回第 5 章排错。第二层确认 MCP Server 的工具被 Agent 识别到。启动mcp-server-order和order-agent后看order-agent的日志把 MCP 的 debug 级别打开后应该能看到类似Discovered tool: createOrder、Discovered tool: complete以及支付宝侧的工具列表。这一步的关键是工具数量对得上本地订单服务至少两个工具支付宝服务至少包含下单和查询。如果工具列表是空的说明 SSE 连接没建立检查url和sse-endpoint是否拼错。第三层发一笔真实测试订单。用 curl 打/buycurl -i -X POST http://localhost:8080/buy?phone13800000000plan1预期结果是 302 重定向Location头指向支付宝沙箱的收银台地址。你在浏览器里打开这个地址用沙箱买家账号付款付款完成后支付宝会回调你配置的notify_url也就是/callback。回调进来后看日志应该能看到订单回调: {out_trade_no..., trade_no..., trade_statusTRADE_SUCCESS}随后 Agent 调complete工具把本地订单状态从0改成2并写入alipay_trade_no。验证成功的标志我整理成一张检查清单你逐项打勾检查项预期结果失败指向模型 curl 请求返回 choices 内容Key/Base URL 错Agent 启动日志发现本地支付宝工具SSE 连接失败/buy请求302 到沙箱收银台工具调用参数错沙箱付款页面显示支付成功沙箱账号/金额问题/callback日志收到 out_trade_no 和 trade_nonotify_url 未配置数据库订单status2 且有交易号complete 工具未触发实测下来最容易出问题的是回调这一步沙箱的notify_url必须是公网可访问地址本地localhost收不到异步通知。调试阶段可以用内网穿透工具把 8080 暴露出去注意这里说的是开发调试用的端口映射不是任何网络访问工具或者干脆先用同步查询接口确认支付状态等回调链路单独验证时再处理。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth 报错这一章按真实报错信息组织你遇到哪个直接对号入座。所有报错都来自这套 Spring AI MCP TaoToken 的组合不是泛泛而谈。401 Unauthorized。出现在模型请求阶段说明TAOTOKEN_API_KEY没被正确注入。先确认环境变量在当前 shell 里echo $TAOTOKEN_API_KEY有值再确认 Spring 配置里写的是${TAOTOKEN_API_KEY}而不是硬编码的空串。还有一种情况是 Key 被复制时带了空格或换行粘到配置文件里肉眼看不出来用cat -A检查一下行尾。如果 Key 本身过期或被删去 API Keys 页面重新生成一个。local proxy failed。这个报错通常出现在 MCP Client 尝试连接 SSE 端点时本质是连接建立失败。检查三件事mcp-server-order是否真的在 8081 上监听curl http://localhost:8081/sse看有没有响应、支付宝 MCP 的sse-endpoint路径是否完整少一个斜杠就连不上、以及防火墙是否拦了本地端口。原文提到 stdio 方式调支付宝 MCP 有参数限制如果你还在用 stdio 配置换成 SSE 大概率就好了。reading choices 相关报错。典型信息是Cannot read field choices或返回体解析失败说明模型返回的不是标准 chat completion 结构。原因通常是base-url填错比如填成了官网首页而不是https://taotoken.net/api或者model字段填了一个不存在的 ID。用第 4 章的 curl 先验证curl 通而代码不通就是配置加载顺序问题检查application.yml有没有被application-{profile}.yml覆盖。OAuth 相关报错。出现在支付宝 MCP 服务鉴权阶段提示 token 无效或授权失败。支付宝的 MCP 场景受限密钥和应用私钥是两回事前者用于 MCP 服务鉴权后者用于支付请求签名别混用。确认受限密钥是在开放平台对应应用下申请的且应用状态是已上线或沙箱可用。如果报错里带invalid_client检查appId和密钥是否属于同一个应用。工具调用参数不匹配。模型调createOrder时传了pkgNo基础套餐而不是数字1导致PKGS.get()返回 null。解决办法是在ToolParam的 description 里写死数字编号 1/2/3并在 prompt 里明确要求传数字。这类问题不是配置错是提示词工程多调几次 description 就稳了。回调验签失败。/callback收到参数但验签不过常见原因是支付宝公钥用错用了应用公钥而非支付宝公钥或者回调参数在 JSON 序列化时顺序变了。验签要在序列化之前用原始参数做别先转 Map 再转 JSON。生产环境务必加验签逻辑沙箱调试阶段可以先跳过但上线前必须补。6. 下一步把统一 Key 用在长期编码与 Agent 迭代上走到这里你的订单系统应该已经能用自然语言驱动支付了用户说帮我下单个基础套餐Agent 自己建单、调支付宝、拿回支付链接回调进来自己改状态。这套链路的可维护性比传统写法高在两点——支付渠道被 MCP 封装后换渠道只改 MCP 连接配置模型调用被 TaoToken 收敛后换模型只改base-url和model两个字段。如果你打算把这套 Agent 长期跑下去比如加退款流程、加订单查询、加多轮对话式客服模型调用量会涨起来这时候可以看看 Coding Plan 的套餐https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite它更适合持续性的编码和 Agent 任务。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteMCP 相关的参数细节和错误码都在里面排错时比翻博客快。最后给一个我踩过的坑作为收尾调试阶段把 MCP 的 debug 日志开着io.modelcontextprotocol.client和io.modelcontextprotocol.spec两个 logger 设成 debug工具调用的入参和出参都会打出来模型传错参数一眼就能看到。等链路稳定了再关掉不然日志量会很大。支付这种链路能看见每一步的输入输出比任何文档都管用。
返回列表