PAYATHON 2026

获取支付宝订单号tradeNO后,uniapp(app端)如何唤起支付?

支付老李

结论

通常情况下,仅凭支付宝交易号 tradeNO,无法在 uni-app App 端直接唤起支付宝支付。

支付宝支付要求 uni.requestPayment 的 orderInfo 参数是完整的签名订单字符串。这个字符串需要由服务端调用支付宝 App 支付接口生成,不能用支付宝交易号代替。支付流程如下:

  1. App 请求业务服务端创建订单。
  2. 服务端调用支付宝 alipay.trade.app.pay,生成签名后的 orderString。
  3. App 将 orderString 作为 orderInfo 传给 uni.requestPayment。
  4. 最终支付结果以支付宝服务端异步通知为准。

有些项目虽然把变量命名为 tradeNO,其中保存的却是完整的支付宝签名订单字符串。这种情况下可以直接将它作为 orderInfo 使用,但要先确认变量的实际内容。

tradeNO 和 orderInfo 的区别

以下几个字段容易混淆:

  • out_trade_no:商户系统生成的业务订单号。
  • trade_no:支付宝创建交易后生成的支付宝交易号。
  • orderInfo:App 支付 SDK 所需的完整签名参数字符串。

支付宝 App 支付除了订单编号,还需要金额、商品信息、应用 ID、回调地址、时间戳和签名等参数。单独的 trade_no 或 out_trade_no 无法完成客户端支付调用。

uni-app App 端调用方式

假设服务端返回以下数据:

{
  "code": 0,
  "data": {
    "orderString": "app_id=...&biz_content=...&charset=utf-8&method=alipay.trade.app.pay&sign=..."
  }
}

App 端可以这样调用:

async function payWithAlipay() {
  try {
    const response = await uni.request({
      url: 'https://example.com/api/payment/alipay/create',
      method: 'POST',
      data: {
        orderId: 'YOUR_BUSINESS_ORDER_ID'
      }
    });

    const result = response.data;

    if (result.code !== 0 || !result.data?.orderString) {
      throw new Error(result.message || '创建支付宝订单失败');
    }

    uni.requestPayment({
      provider: 'alipay',
      orderInfo: result.data.orderString,
      success(payResult) {
        console.log('支付宝 SDK 返回成功:', payResult);

        // 不要仅凭这里的结果更新订单状态
        // 应继续向业务服务端查询订单的最终支付状态
        queryOrderStatus();
      },
      fail(error) {
        console.error('支付宝支付未完成:', error);

        // 用户取消、SDK 异常和支付失败都会进入这里,
        // 最终状态仍建议向服务端查询确认
      }
    });
  } catch (error) {
    console.error('发起支付失败:', error);
    uni.showToast({
      title: error.message || '发起支付失败',
      icon: 'none'
    });
  }
}

调用支付前,也可以先检查当前 App 是否支持支付宝支付:

uni.getProvider({
  service: 'payment',
  success(result) {
    if (result.provider.includes('alipay')) {
      payWithAlipay();
    } else {
      uni.showToast({
        title: '当前环境不支持支付宝支付',
        icon: 'none'
      });
    }
  },
  fail(error) {
    console.error('获取支付服务失败:', error);
  }
});

如果 tradeNO 实际是完整订单字符串

有些项目会把服务端返回的支付参数误命名为 tradeNO。如果它的内容类似这样:

app_id=...&biz_content=...&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=...&sign=...

它就不是单独的支付宝交易号,而是支付 SDK 需要的订单字符串,可以直接使用:

uni.requestPayment({
  provider: 'alipay',
  orderInfo: tradeNO,
  success(result) {
    console.log('支付调用完成:', result);
  },
  fail(error) {
    console.error('支付调用失败:', error);
  }
});

如果内容只是一个编号,例如:

2026xxxxxxxxxxxxxxxxxxxx

就不能直接传给 orderInfo,需要由服务端重新生成 App 支付订单字符串。

服务端需要做什么

服务端需要完成这些工作:

  1. 根据业务订单读取实际金额,不能直接信任客户端传入的金额。
  2. 调用支付宝 alipay.trade.app.pay。
  3. 使用商户私钥完成签名。
  4. 将生成的订单字符串返回给 App。
  5. 接收支付宝异步通知并验签。
  6. 验证商户号、应用 ID、订单号、金额和支付状态。
  7. 以幂等方式更新业务订单。

以下伪代码仅用于说明数据流,具体写法取决于服务端语言和使用的支付宝 SDK:

const orderString = alipaySdk.appPay({
  notify_url: 'https://example.com/api/payment/alipay/notify',
  bizContent: {
    out_trade_no: businessOrderNo,
    total_amount: orderAmount,
    subject: orderSubject,
    product_code: 'QUICK_MSECURITY_PAY'
  }
});

return {
  code: 0,
  data: {
    orderString
  }
};

签名必须由服务端完成,不能把商户私钥放进 uni-app 客户端代码。

注意事项

1. 只适用于 App 端

uni.requestPayment 配合 provider: 'alipay' 的方式适用于打包后的 App。H5 和小程序等平台有各自的支付接入方式,不能直接套用。

2. 检查支付模块配置

需要在 uni-app 项目的 App 模块配置中启用支付宝支付能力,然后重新制作自定义基座或重新打包。如果只修改配置,仍然使用旧基座,支付模块可能不会生效。

3. 使用真机测试

支付宝 App 支付依赖原生 SDK 和支付宝客户端,需要在安装了支付宝的真机上测试。普通浏览器无法完整验证这条支付链路。

4. 客户端回调不是最终凭证

success 只表示支付宝 SDK 返回了成功结果。业务订单是否支付成功,应以服务端收到并通过验签的异步通知为准,也可以由服务端主动查询支付宝订单后确认。

5. 不要重复创建支付订单

用户重复点击支付按钮时,客户端要做好按钮防抖,服务端也要进行幂等处理。订单已经支付、已经关闭或金额不一致时,服务端应拒绝再次生成支付参数。

拿到 tradeNO 后,先确认它是支付宝交易号,还是名称有误的完整支付订单字符串。支付宝交易号不能直接唤起支付,只有完整的支付订单字符串才能传给 uni.requestPayment 的 orderInfo。

备注:内容仅供参考。