PAYATHON 2026

uniapp 开发的支付宝小程序支付完成后如何跳回小程序

支付阿杰

结论

在支付宝小程序中发起支付,应使用小程序原生支付 API my.tradePay。支付结束后,支付宝会关闭收银台并返回当前小程序。小程序可以在支付回调中跳转到订单结果页。

如果目前使用 alipay.trade.wap.pay、alipay.trade.page.pay,或通过 WebView、外部链接打开收银台,那么支付完成页中“完成”按钮的去向通常不受小程序控制。设置 return_url 也无法保证用户返回当前小程序。这种情况需要更换支付接入方式,修改支付成功页解决不了问题。

原因

支付宝的网页支付和小程序支付采用不同的流程:

  • 网页支付会离开小程序上下文,支付完成页由支付宝控制。
  • 小程序支付通过 my.tradePay 拉起原生收银台,支付结束后会回到调用该 API 的小程序页面。
  • return_url 用于网页支付完成后的浏览器跳转,并不等同于“返回支付宝小程序”。
  • 前端收到支付成功回调,只能说明收银台返回了相应结果。订单的最终状态仍应通过服务端查询或异步通知确认。

推荐实现流程

1. 服务端创建支付宝交易

服务端调用适用于支付宝小程序场景的交易创建接口,例如 alipay.trade.create,获取支付宝交易号 trade_no。

应用私钥和签名逻辑不能放在小程序前端。具体请求参数应以当前接入的支付产品和支付宝开放平台文档为准。

服务端可以向小程序返回如下数据:

{
  "tradeNo": "2026xxxxxxxxxxxxxxxx"
}

2. 小程序调用 my.tradePay

在 uni-app 项目中,可以通过支付宝平台条件编译调用支付 API:

// #ifdef MP-ALIPAY
my.tradePay({
  tradeNO: tradeNo,
  success: (res) => {
    const resultCode = String(res.resultCode)

    if (resultCode === '9000') {
      // 收银台返回支付成功,但仍建议向服务端确认订单状态
      confirmOrderStatus()
      return
    }

    if (resultCode === '8000') {
      uni.showToast({
        title: '支付结果确认中',
        icon: 'none'
      })
      confirmOrderStatus()
      return
    }

    if (resultCode === '6001') {
      uni.showToast({
        title: '已取消支付',
        icon: 'none'
      })
      return
    }

    uni.showToast({
      title: '支付未完成',
      icon: 'none'
    })
  },
  fail: (err) => {
    console.error('tradePay fail:', err)

    uni.showToast({
      title: '支付调用失败',
      icon: 'none'
    })
  }
})
// #endif

这里的 tradeNo 是服务端创建交易后返回的支付宝交易号,不是商户订单号。

3. 向服务端确认订单状态

不要只根据 resultCode === '9000',就将订单永久标记为已支付。前端应再次查询自己的服务端,确认订单状态:

function confirmOrderStatus() {
  uni.request({
    url: 'https://example.com/api/orders/status',
    method: 'GET',
    data: {
      orderNo: currentOrderNo
    },
    success: (res) => {
      if (res.data && res.data.paid === true) {
        uni.redirectTo({
          url: `/pages/order/result?orderNo=${encodeURIComponent(currentOrderNo)}`
        })
      } else {
        uni.showToast({
          title: '支付结果确认中,请稍后查看订单',
          icon: 'none'
        })
      }
    },
    fail: () => {
      uni.showToast({
        title: '订单状态查询失败',
        icon: 'none'
      })
    }
  })
}

服务端应根据支付宝异步通知或主动查询结果更新订单状态,同时完成签名验证、金额校验和幂等处理。

如果当前使用的是网页支付

先检查后端是否调用了以下接口:

alipay.trade.wap.pay
alipay.trade.page.pay

如果调用了其中一个接口,当前拉起的就是网页收银台。在这套流程中,支付成功页和“完成”按钮通常由支付宝客户端控制,小程序无法通过普通前端代码改变其行为。

支付流程应调整为:

小程序请求创建订单
    → 服务端调用小程序适用的交易创建接口
    → 服务端返回 trade_no
    → 小程序调用 my.tradePay
    → 收银台关闭并回到小程序
    → 小程序向服务端确认订单状态

不要将小程序页面路径直接填写到网页支付的 return_url。小程序页面不是普通的 HTTP 页面,这种设置通常无法建立可靠的返回链路。

注意事项

  • my.tradePay 必须在支付宝小程序环境中调用。
  • 支付 API 一般应由用户点击按钮触发,不应在页面加载时自动、连续拉起。
  • 支付完成后的业务跳转由小程序在回调中处理,可以使用 uni.redirectTo、uni.navigateTo 或 uni.switchTab。
  • 如果目标页面属于 tabBar,必须使用 uni.switchTab,不能使用 uni.redirectTo。
  • 用户可能在支付后直接关闭小程序,因此服务端必须能通过异步通知独立完成订单更新。
  • 支付参数和可用接口可能受到支付宝产品签约、应用类型及当前平台规则的限制。接入前,应确认对应应用已在支付宝开放平台获准使用相关支付产品。

备注:内容仅供参考。