uni-app微信支付后需轮询服务端接口验签确认支付成功再跳转,不可仅依赖uni.requestPayment的success回调,因该回调仅表示用户完成支付操作而非资金到账,须结合后端notify_url接收XML通知、正确验签及严格校验订单状态。

uni-app调用微信小程序支付后如何正确处理回调
微信小程序的支付本身没有“服务端回调”机制,uni.requestPayment 只会返回前端支付结果(成功/失败/取消),所谓“支付后跳转”,必须靠前端主动判断 + 服务端验签配合,否则极易出现跳转错乱、重复跳转或状态不一致。
为什么不能只监听 uni.requestPayment 的 success 回调就跳转
因为微信支付的 success 仅表示“用户点击了确认支付并完成了手势/密码操作”,不代表支付已成功入账。极端情况下(如网络中断、微信后台异步通知失败、商户系统未收到回调),用户看到“支付成功”页面,但订单实际未支付成功。
-
uni.requestPayment的success回调触发时机早于微信服务器向你后端发送支付结果通知(notify_url) - 用户可能中途切出小程序、杀进程,导致 success 回调根本没执行
- 若仅靠前端跳转,无法校验签名,攻击者可伪造支付成功响应
推荐做法:支付后轮询 + 服务端验签兜底
前端发起支付后,不立即跳转,而是用定时器轮询自己后端接口,等后端确认支付成功(且验签通过)后再跳转。这是 uni-app 小程序中最稳妥的落地方式。
- 调用
uni.requestPayment前,先调用后端接口生成预支付参数(timeStamp、nonceStr、package、signType、paySign) - 支付成功后,立即启动
setInterval轮询/api/order/status?orderId=xxx - 后端该接口必须:查数据库订单状态 + 验证微信回调是否已到达并验签通过,二者都满足才返回
{ paid: true } - 轮询最多持续 30 秒(微信官方建议),超时则提示“请在微信支付记录中核实”,并提供手动刷新按钮
- 一旦收到
paid: true,清除定时器,uni.navigateTo跳转到成功页
示例片段(前端):
uni.requestPayment({
provider: 'wxpay',
orderInfo,
success: () => {
const timer = setInterval(() => {
uni.request({
url: '/api/order/status?orderId=' + orderId,
success: (res) => {
if (res.data.paid) {
clearInterval(timer)
uni.navigateTo({ url: '/pages/pay-success?orderId=' + orderId })
}
}
})
}, 2000)
},
fail: (err) => {
console.log('支付失败', err)
}
})
容易被忽略的关键点
很多团队卡在“轮询返回一直是未支付”,其实问题往往不在前端:
- 后端
notify_url接口未正确接收微信 POST 的原始 XML 数据(uni-app 云函数或 Node.js 服务需显式配置bodyParser.raw({ type: 'application/xml' })) - 验签时用了错误的
key(不是公众号后台的 API 密钥,而是微信商户平台「API安全」里设置的密钥) - 订单查询接口返回
paid: true的条件太宽松——比如只查了订单表status = 'paid',但没确认该状态是由微信回调更新的(防止人工误改) - 小程序域名校验未开启:登录微信公众平台 → 开发管理 → 开发者工具 → 小程序服务器域名,确保
request和socket域名都添加且生效
真正的支付闭环,80% 的坑都在服务端验签和状态同步逻辑里,前端只是触发和等待的环节。











