PAYATHON 2026

聚合支付如何完成商户进件并通过h5支付结算

支付小周

结论

这个场景通常适合使用支付宝开放平台的当面付服务商模式。服务商协助商户完成签约或进件,再通过应用授权代商户调用交易接口。

用户扫码进入页面后,如果页面运行在支付宝客户端内,服务端可以调用 alipay.trade.create 创建交易,H5 页面再通过支付宝 JSAPI tradePay 调起付款。收款主体必须是实际商户,资金才会按照该商户的签约结算规则进入其支付宝账户,或结算至绑定的银行账户。

这里需要区分两种“结算”需求:

  • 如果只是要求每笔资金直接归属于对应商户,使用当面付服务商模式即可,不要先收进平台账户,再由平台自行转账。
  • 如果平台还需要抽佣、分账、延迟结算或资金托管,当面付本身无法提供这些能力,需要另行申请支付宝当前开放的平台型资金产品。产品是否可用、支持哪些支付渠道,要以支付宝开放平台对具体应用和行业的审核结果为准。

为什么不能直接使用普通 H5 支付

“扫码进入 H5”和“手机网站支付”不是同一个场景。

如果用户使用支付宝扫描二维码,页面在支付宝 WebView 中打开,并通过 JSAPI 调起付款,典型流程如下:

支付宝扫码
  → 打开支付宝内 H5
  → 获取用户支付宝身份
  → 服务端创建当面付交易
  → H5 调用 tradePay
  → 支付宝异步通知
  → 服务端确认交易结果

alipay.trade.wap.pay 则用于手机浏览器网页支付,通常会跳转到支付宝客户端或支付宝收银台。它和客户端内的 JSAPI 支付在产品权限、调用方式及商户签约范围上并不完全相同,不能因为页面使用 H5 技术,就一律按照手机网站支付处理。

直付通主要用于平台型交易、二级商户管理和资金结算。如果当前直付通方案没有开放所需的 H5 或 JSAPI 支付渠道,更换前端调用方式也无法绕过产品权限。

商户接入流程

1. 创建服务商应用

服务商需要在支付宝开放平台创建第三方应用,并配置应用公钥、支付宝公钥、网关地址、回调地址及所需的产品权限。

私钥只能保存在服务端,不能写进 H5 页面或小程序代码。

2. 完成商户签约或进件

根据支付宝向服务商开放的能力,可以选择商户自主签约、服务商代签约,或使用支付宝提供的商户入驻接口。可用的进件接口、必填资质和审核流程取决于行业及应用权限,不能只根据通用接口名称判断。

进件完成后,至少需要保存以下信息:

  • 商户支付宝 user_id,也常称 PID;
  • 商户授权产生的 app_auth_token;
  • 授权范围和授权状态;
  • 产品签约状态;
  • 商户主体与门店信息;
  • 结算账户配置。

进件成功不代表商户已经取得支付权限。正式创建交易前,还要确认商户已经签约当面付,并且服务商应用获得了代调用权限。

3. 获取付款用户身份

调用 alipay.trade.create 时,通常需要付款人的支付宝 user_id。H5 页面可以通过支付宝网页授权获取 auth_code,再由服务端用它换取用户身份。

授权回调和用户信息换取必须在服务端完成,不能信任前端自行提交的 buyer_id。

4. 以实际商户身份创建交易

下面是服务端调用的示意代码。示例省略了部分配置和异常处理,实际字段应以当前支付宝 SDK 及开放平台文档为准。

AlipayClient alipayClient = new DefaultAlipayClient(
    "https://openapi.alipay.com/gateway.do",
    serviceProviderAppId,
    serviceProviderPrivateKey,
    "json",
    "UTF-8",
    alipayPublicKey,
    "RSA2"
);

AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
request.setNotifyUrl("https://pay.example.com/alipay/notify");

JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", orderNo);
bizContent.put("total_amount", "10.00");
bizContent.put("subject", "门店消费");
bizContent.put("buyer_id", buyerUserId);
bizContent.put("seller_id", merchantAlipayUserId);

request.setBizContent(bizContent.toJSONString());

AlipayTradeCreateResponse response =
    alipayClient.execute(request, null, merchantAppAuthToken);

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

String tradeNo = response.getTradeNo();

调用时要使用对应商户的 app_auth_token,收款主体也必须是已经完成签约的实际商户。是否需要显式传入 seller_id,要根据应用授权模式和支付宝当前的接口要求确定。

5. H5 调起支付宝支付

服务端创建交易后,只把支付宝交易号返回给前端:

<script>
function startAlipay(tradeNo) {
  if (!window.AlipayJSBridge) {
    document.addEventListener(
      'AlipayJSBridgeReady',
      function () {
        startAlipay(tradeNo);
      },
      { once: true }
    );
    return;
  }

  AlipayJSBridge.call(
    'tradePay',
    { tradeNO: tradeNo },
    function (result) {
      console.log(result.resultCode);
      // 此处只用于展示结果,不能据此确认订单已支付。
    }
  );
}
</script>

部分运行环境可能使用 ap.tradePay 等封装。具体调用方式应以支付宝客户端当前的 JSAPI 文档和应用接入方式为准,不要混用不同容器的调用示例。

6. 接收通知并确认订单

前端显示支付成功,不代表服务端已经确认收到资金。服务端必须完成以下处理:

  1. 验证异步通知签名;
  2. 核对 app_id、seller_id、out_trade_no 和金额;
  3. 检查 trade_status;
  4. 保证订单更新操作具有幂等性;
  5. 必要时调用交易查询接口再次确认;
  6. 验证通过后,向支付宝返回规定的成功响应。

通知中的金额、商户号和订单状态都要与本地订单比对,不能直接采用。

资金如何到达商户账户

交易虽然由服务商应用代为创建,但收款主体应当是实际商户。支付宝会按照该商户签署的协议处理资金。服务商不能通过修改回调地址或业务参数来改变资金归属。

“资金进入商户支付宝账户”和“自动结算至银行卡”也不是一回事。是否自动结算及何时到账,取决于商户的结算协议、结算周期、银行卡配置、风险状态和支付宝实际开放的结算能力,业务代码不能自行假定资金会实时到账。

如果平台需要从每笔交易中收取技术服务费,应先确认是否具备合法且受支付宝支持的分账或服务费能力。不建议让平台统一收款后,再在线下向商户转账。这种方式可能带来二清、账务、税务和合规风险。

接入时容易忽略的问题

  • 二维码应指向 HTTPS 页面,并配置支付宝要求的授权回调域名。
  • 金额必须由服务端根据订单重新校验,不能直接信任 H5 提交的值。
  • 每个 out_trade_no 必须全局唯一,重复请求需要进行幂等处理。
  • app_auth_token 是敏感凭证,需要加密存储,并处理失效、撤销和重新授权。
  • 测试环境与生产环境的应用、密钥、商户签约和网关地址不能混用。
  • 服务商代调用成功,不代表商户进件、产品签约和收款权限都已经生效。
  • 如果二维码还可能由微信或系统浏览器等环境扫描,需要识别运行环境并提供降级提示。支付宝 JSAPI 无法在普通浏览器中直接调用。

因此,如果业务流程是“支付宝扫码进入支付宝内 H5,再调用 JSAPI 付款,资金直接归属于各商户”,应优先申请并确认当面付服务商模式。如果还涉及分账、抽佣或平台统一结算,需要将资金方案单独提交支付宝评估,不能只靠当面付接口完成。

备注:内容仅供参考。