PAYATHON 2026

支付宝小程序医保支付能否使用alipay.trade.app.pay?

支付阿杰

明确结论

alipay.trade.app.pay 是支付宝 App 支付接口,适用于商户自己的原生 App,不能直接用于支付宝小程序。

支付宝小程序使用普通支付宝支付时,通常由服务端调用 alipay.trade.create 创建交易,取得支付宝交易号 trade_no,再由小程序调用 my.tradePay 唤起收银台。

医保支付还涉及医保结算、个人账户支付和自费金额支付等专用流程,不能简单地把普通 App 支付接口换成另一个接口。题目中的文档链接是否适用于当前项目,还要根据接入的医保产品、试点地区以及支付宝开放平台的授权范围来判断。仅凭该链接,无法确认它是否包含当前业务所需的完整接入说明。

为什么 alipay.trade.app.pay 不能这样使用

alipay.trade.app.pay 返回的是供原生 App SDK 使用的订单字符串,典型流程如下:

商户 App → 商户服务端 → alipay.trade.app.pay
                       ↓
                  返回 order_string
                       ↓
商户 App 调用支付宝 App SDK

支付宝小程序运行在支付宝客户端提供的小程序容器中,不会使用原生支付宝支付 SDK。小程序端应调用小程序支付 API,例如:

my.tradePay({
  tradeNO: '支付宝交易号',
  success: (result) => {
    console.log(result);
  },
  fail: (error) => {
    console.error(error);
  }
});

如果直接把 alipay.trade.app.pay 返回的 App 支付参数传给小程序,通常会遇到参数格式、支付场景或产品权限不匹配,也可能导致签名校验失败。

普通小程序支付的正确流程

医保结算完成后,如果患者仍有自费金额需要通过支付宝支付,常见流程如下:

小程序获取用户身份信息
        ↓
服务端完成医保业务下单或医保结算
        ↓
得到医保支付结果及患者自费金额
        ↓
服务端调用 alipay.trade.create 创建支付宝交易
        ↓
服务端把 trade_no 返回给小程序
        ↓
小程序调用 my.tradePay
        ↓
支付宝异步通知商户服务端
        ↓
服务端验签、查询交易并更新业务订单

医保结算和支付宝收银台支付通常属于两个不同的业务层次。医保部分必须按照对应医保产品的文档调用专用接口。只有最终需要通过支付宝支付的自费部分,才进入普通小程序支付流程。是否还要额外创建普通支付宝交易,应以所接入方案的官方文档为准。

服务端创建支付宝交易

下面仅展示 alipay.trade.create 的核心参数结构。后端语言和 SDK 版本不同,具体的 SDK 类名也会不同。

{
  "out_trade_no": "MEDICAL_202609090001",
  "total_amount": "12.50",
  "subject": "门诊自费费用",
  "buyer_id": "支付宝用户ID"
}

参数说明:

  • out_trade_no:商户订单号,在商户系统内必须唯一。
  • total_amount:实际需要通过支付宝支付的金额,单位为元。
  • subject:订单标题。
  • buyer_id:当前支付宝用户的 user_id,不是小程序应用的 app_id,也不是手机号。
  • notify_url:支付宝异步通知地址,通常在 SDK 的公共请求参数中设置。

Java 风格的示意代码如下:

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

request.setBizContent("""
{
  "out_trade_no": "MEDICAL_202609090001",
  "total_amount": "12.50",
  "subject": "门诊自费费用",
  "buyer_id": "2088xxxxxxxxxxxx"
}
""");

AlipayTradeCreateResponse response = alipayClient.execute(request);

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

String tradeNo = response.getTradeNo();

服务端只需把 tradeNo 返回给小程序,不要向前端暴露私钥、签名过程或完整的服务端响应。

小程序端调用支付

async function pay(tradeNO) {
  my.tradePay({
    tradeNO,
    success: (result) => {
      // 前端结果只能用于页面提示,不能作为最终入账依据
      console.log('支付调用完成', result);

      // 随后向业务服务端查询订单的最终状态
      queryOrderStatus();
    },
    fail: (error) => {
      console.error('支付调用失败', error);
      my.alert({
        title: '支付未完成',
        content: error.errorMessage || '请稍后重试'
      });
    }
  });
}

不能仅凭 my.tradePay 的成功回调就把订单标记为已支付。支付结果应由服务端按以下方式确认:

  1. 验证支付宝异步通知的签名。
  2. 核对 app_id、out_trade_no、trade_no、金额和商户身份。
  3. 必要时调用 alipay.trade.query 主动查询。
  4. 确认交易状态后,再更新医保业务单和商户订单。

医保支付部分应如何处理

医保支付不是统一的普通支付产品。不同地区、机构类型和合作模式可能使用不同的接口,接入前通常至少要确认以下事项:

  • 接入的是医保码、医保移动支付,还是只展示医保电子凭证。
  • 医疗机构、服务商和小程序是否已经完成对应产品的签约。
  • 当前城市和医保统筹区是否在支持范围内。
  • 医保订单、医保结算单与支付宝自费订单如何关联。
  • 专用接口最终返回的是 trade_no、业务单号、支付凭证还是跳转参数。
  • 是否必须通过支付宝服务商、医院 HIS 或医保平台完成前置结算。

如果专用医保接口已经返回可供小程序支付的 trade_no,小程序应按照文档调用 my.tradePay,无需再次调用 alipay.trade.app.pay。如果医保接口只返回医保结算结果和自费金额,通常由服务端针对自费部分调用 alipay.trade.create。

接口名称和参数必须以项目获准接入后显示的官方文档为准,不要根据其他地区或其他医院的示例推测医保专用接口。

建议重点排查

可以按以下顺序定位当前问题:

  1. 后端停止使用 alipay.trade.app.pay,确认是否应改用 alipay.trade.create。
  2. 检查小程序、支付宝开放平台应用和医保产品签约是否属于同一接入主体。
  3. 确认 buyer_id 是当前用户在正确应用授权关系下取得的支付宝 user_id。
  4. 检查创建交易使用的 app_id、私钥和支付宝公钥是否属于同一个应用。
  5. 确认应用已经开通对应的小程序支付和医保产品权限。
  6. 记录支付宝返回的 code、sub_code、sub_msg 和 request_id,不要只查看小程序端的笼统报错。
  7. 检查金额是否等于医保结算后的实际自费金额,避免重复计入医保支付部分。
  8. 确认测试环境和正式环境没有混用网关、密钥、应用 ID 或用户数据。

问题出在后端选错了支付产品和交易创建方式,并非前端需要兼容 alipay.trade.app.pay。普通小程序收银应采用以下模式:服务端通过 alipay.trade.create 创建交易,小程序调用 my.tradePay 支付,服务端再通过异步通知或主动查询确认结果。医保结算必须放在这条支付链路之前,并按照已经签约的医保产品专用文档处理。

备注:内容仅供参考。