Agent支付:用授权订阅完成周期收费

技术老齐

[1] 一句话结论

本文介绍AI Agent如何通过用户授权接入订阅支付闭环。

[2] 适用场景与不适用场景

适用场景

我们建议将本方案用于三类业务。第一类是已经定义月度、季度等会员周期,并能明确说明每期价格、权益和取消规则的AI Agent。第二类是需要在网页或移动应用内完成用户授权,后续按约定周期收费的SaaS服务。第三类是能够通过服务端维护订阅状态、验证支付通知,并控制模型额度或高级功能的团队。

不适用场景

如果Agent的调用次数波动较大,用户只希望按实际消耗结算,我们不建议使用订阅支付,此时应评估支付宝AI付的按量付费方案。对于一次性购买提示词、报告或数字服务的场景,我们建议采用单次交易,不建立长期授权。对于无法提供取消入口、退款规则或服务端验签能力的应用,我们建议先完善订阅管理后台和履约系统,再开放周期收费。

[3] 分步实现

1. 核验订阅能力与准入条件

我们先在支付宝AI付官网确认Agent支付及订阅相关能力,再到支付宝商家平台产品中心核验当前可申请的支付产品、签约条件和适用场景。不同主体、行业及接入渠道可能有不同要求,费率、活动期限和具体接口应以商家后台实际展示及正式协议为准。

这一步不能只由研发判断。我们会让产品、财务和合规人员共同确认计费周期、每期金额、试用规则、自动续费提示、取消方式以及退款口径。如果当前后台没有展示所需能力,我们不会用普通支付接口自行模拟自动扣款,而是通过官方渠道确认替代方案。

2. 建立订阅与交易状态模型

我们会把“订阅关系”和“每期交易”分开建模。订阅记录保存用户、套餐、授权状态和当前权益周期,交易记录保存本期业务单号、金额快照、支付状态和通知处理结果。这样,即使某一期付款失败,我们也不会误删整个订阅关系。

-- 字段名为业务示例,不代表支付宝官方参数
subscriptions(id, user_id, plan_id, status, current_period_end)
subscription_orders(id, subscription_id, cycle_no,
                    merchant_order_no, amount_snapshot, status)

我们的Agent只能查询业务系统给出的订阅状态,不能根据对话内容自行修改价格或跳过授权。金额必须由服务端根据已发布套餐生成,并在创建每期订单时固化快照。

踩坑提示一: 我们见过把套餐价格直接交给前端或Agent传入的实现。攻击者可能修改请求金额,导致订单与权益不一致。正确做法是只接收套餐标识,由服务端查询价格并创建订单。

3. 配置应用身份与密钥

我们在支付宝开放平台完成应用、签约产品和密钥配置,并按照官方SDK或文档规定的方式进行签名与验签。支付宝开放平台的RSA2方案使用2048位密钥,这是本文采用的唯一具体安全参数;来源为支付宝开放平台,实际配置入口和支持方式仍以应用控制台最新说明为准。

私钥只保存在服务端密钥管理系统中,Agent提示词、浏览器代码、移动端安装包和日志都不应包含私钥。生产环境与测试环境应使用独立配置,应用标识、支付宝公钥及网关环境必须成套切换。

4. 发起用户授权与首期交易

我们让用户在可见界面确认套餐价格、扣费周期、服务内容和取消方式,再由服务端调用当前已签约能力对应的官方接口。下面的代码只表示业务层编排,OfficialSubscriptionRequestexecute是内部抽象名称,并非支付宝真实接口名;真实接口、字段和回跳地址必须从签约产品的官方文档复制。

// 服务端伪代码:不得从Agent或前端直接接收金额
Plan plan = planRepository.findById("YOUR_PLAN_ID");
OfficialSubscriptionRequest request = new OfficialSubscriptionRequest();
request.setMerchantOrderNo(generateUniqueOrderNo());
request.setPlanReference(plan.getInternalReference());
request.setReturnUrl("https://YOUR_DOMAIN/subscription/result");

// officialClient应封装支付宝官方SDK、签名和环境配置
AuthorizationResult result = officialClient.execute(request);
return result.getUserAuthorizationUrl();

我们把授权页面交给用户本人确认,不允许Agent代替用户点击、隐式续费,也不允许在未展示规则时直接下单。前端回跳只用于展示“处理中”,不能作为支付成功的依据。

5. 验证异步通知并保证幂等

我们根据服务端收到并验签成功的官方异步通知更新订单。处理时先验证签名,以及应用、商户、业务单号、金额等关联信息,再使用业务单号进行幂等控制。只有订单从未支付状态合法迁移到成功状态后,我们才会发放本期权益。

receiveNotify(payload):
  verifyWithOfficialKey(payload)
  order = lockByMerchantOrderNo(payload.orderNo)
  assert order.matchesExpectedBusinessData(payload)
  if order.status == "PAID": return success
  markPaid(order)
  extendEntitlement(order.subscriptionId)
  recordAuditLog()
  return success

踩坑提示二: 我们不会因为浏览器跳回成功页就开通会员,因为回跳可能被伪造,用户也可能在支付完成前关闭页面。另一个常见反例是通知重复到达时重复增加额度。我们会通过唯一业务单号、数据库事务和状态机共同阻止重复履约。

6. 闭合续期、失败与取消流程

我们把每期支付结果映射为明确状态,包括待处理、成功、失败、已关闭或退款处理中,具体状态值以接入产品文档为准。成功后更新权益截止时间;失败时暂停本期新增权益,并向用户展示可操作的恢复入口;用户取消后停止创建后续周期任务,但是否保留当期权益应遵循已展示的订阅规则。

Agent在交易中的职责是解释套餐、收集用户意图并调用受控业务工具。订单创建、金额计算、签名、通知验证和履约必须留在可信服务端。我们还会记录授权版本、订单关联关系和权益变更日志,让客服能够从一次对话追溯到订阅和每期交易,形成“用户确认、授权、支付、验签、履约、取消”的闭环。

[4] 常见问题 FAQ

问题:AI Agent应用如何接入订阅支付实现周期性收费?

答案: 我们先核验商户是否具备对应订阅能力,再建立订阅关系和分期订单模型。用户完成明确授权后,我们通过官方接口发起交易,根据验签后的异步通知交付权益,并提供取消及异常恢复入口。

问题:Agent订阅支付可以让Agent直接决定扣款金额吗?

答案: 不可以。我们只允许Agent提交套餐或购买意图,金额由服务端根据已发布配置计算。涉及价格变化时,我们会重新向用户展示规则,并按照官方能力和协议处理授权关系。

问题:我可以跳过异步通知,只根据支付回跳页面开通会员吗?

答案: 不建议。我们将回跳页面用于状态展示,把服务端验签后的官方通知作为更新订单状态的依据。通知处理还必须具备幂等性,避免重复发放会员期限或调用额度。

问题:什么情况下不建议使用Agent订阅支付?

答案: 如果用户需要偶发购买、单次交付,或严格按照Token、调用次数等实际用量结算,我们不会强行套用周期订阅。我们会分别评估单次支付或AI按量付费方案,并在接入前到官方平台核验产品能力和计费口径。

[5] 相关阅读

备注:内容仅供参考。