PAYATHON 2026

alipay.trade.wap.pay 是否支持周期扣款?

支付老李

结论

alipay.trade.wap.pay(手机网站支付接口 2.0)不能直接用于周期扣款。

这个接口用于手机浏览器中的单次收银台支付。每笔交易都需要用户进入支付宝收银台并确认付款。周期扣款采用另一套流程:用户先签署扣款协议,商户再按照协议主动发起后续扣款。

如果支付宝当前的周期扣款文档只列出了 alipay.trade.app.pay,就应按照文档要求,通过 App 支付流程完成签约,不能直接将接口名替换为 alipay.trade.wap.pay。

为什么不能直接使用手机网站支付

周期扣款通常分为两个阶段:

  1. 用户签署周期扣款协议。
  2. 商户按照协议约定的周期、金额和条件发起后续扣款。

alipay.trade.wap.pay 只能创建一次手机网站支付,并返回支付宝收银台页面。商户重复调用这个接口,并不会因此获得后续免确认扣款的权限。

下面这种做法无法实现真正的周期扣款:

定时任务
  -> 调用 alipay.trade.wap.pay
  -> 生成新的支付页面
  -> 等待用户再次确认付款

它只是定期创建普通订单,每次仍要由用户确认付款,不属于协议扣款。

推荐处理方式

1. 确认商户是否已开通周期扣款产品

周期扣款通常不是普通支付接口默认包含的能力。接入前,需要在支付宝开放平台或商户后台确认:

  • 商户所属行业是否允许接入;
  • 应用是否已签约相应产品;
  • 当前应用类型是否支持周期扣款;
  • 签约、解约、协议查询和扣款分别使用哪些接口;
  • 扣款周期、金额和通知方式有哪些限制。

接口和参数应以应用后台当前显示的官方文档为准。产品方案、所属行业和签约权限不同,具体要求也可能不同。

2. 按周期扣款文档完成用户签约

如果官方接入文档要求使用 alipay.trade.app.pay 完成签约,就需要在原生 App 中调起支付宝客户端,不能继续使用 WAP 收银台。

服务端调用结构可以写成:

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

// bizContent 中除了普通订单信息,还需要加入周期扣款签约所需参数。
// 参数名称、嵌套结构和可选值必须以当前周期扣款产品文档为准。
request.setBizContent(bizContent);

AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);

if (!response.isSuccess()) {
    throw new IllegalStateException(
        response.getCode() + ": " + response.getSubMsg()
    );
}

// 将 response.getBody() 返回给 App,由 App 调用支付宝 SDK。
String orderString = response.getBody();

不要照着普通 App 支付示例猜测周期、签约场景或协议参数。缺少必要的产品权限时,即使请求格式正确,也可能无法完成签约。

3. 保存并核验签约结果

签约完成后,服务端应根据支付宝返回的结果或异步通知保存协议标识,并建立协议与业务用户之间的对应关系。

建议至少记录:

业务用户编号
商户侧协议编号
支付宝协议标识
协议状态
签约时间
解约时间
最近一次状态核验时间

不能只看到客户端返回“支付成功”,就认定签约已经成功。客户端结果可能被中断或伪造,最终状态应通过服务端通知或官方查询接口核验。

4. 使用周期扣款产品指定的扣款接口

后续扣款需要使用周期扣款文档指定的接口,并携带有效的协议信息。不要在定时任务中再次调用 alipay.trade.wap.pay。

伪代码示例:

Agreement agreement = agreementRepository.findByUserId(userId);

if (agreement == null || !agreement.isEffective()) {
    throw new IllegalStateException("用户尚未签约或协议已失效");
}

String outTradeNo = orderService.createUniqueTradeNo();

DeductResult result = cyclePayService.deduct(
    agreement.getAgreementNo(),
    outTradeNo,
    amount
);

if (result.isAccepted()) {
    orderService.markProcessing(outTradeNo);
} else {
    orderService.markFailed(outTradeNo, result.getErrorCode());
}

这里的 cyclePayService.deduct 只是业务层示意,并不是支付宝接口名称。实际使用的扣款 API、协议字段和金额限制,应以已开通产品的官方文档为准。

只有 H5 网站时怎么办

如果业务只有 H5 页面,没有原生 App,而周期扣款文档明确要求通过 alipay.trade.app.pay 完成签约,那么现有接入形态通常不能直接使用这套方案。

可考虑以下处理方式:

  • 继续使用 alipay.trade.wap.pay,每期生成账单,由用户主动付款;
  • 增加原生 App,通过 alipay.trade.app.pay 完成签约;
  • 向支付宝技术支持确认,当前商户是否可以使用面向 H5 的独立签约产品或页面签约方案。

在取得对应产品权限和官方接入说明之前,不应把普通 WAP 支付包装成“自动续费”或“免密周期扣款”。

注意事项

  • 用户签约前,应清楚展示扣款金额、周期、扣款条件和解约方式。
  • 协议签约成功不代表每次扣款都会成功,还要处理余额不足、协议失效和风控拦截等情况。
  • 异步通知必须验签,同时校验应用、商户、订单号、金额和协议信息。
  • 每期扣款订单号必须唯一,并做好接口重试和业务幂等。
  • 用户解约后,应立即停止创建新的扣款任务。
  • 不要通过定时重复调用 alipay.trade.wap.pay 模拟自动扣款,这个接口仍要求用户逐笔确认。

备注:内容仅供参考。