包含以下主要步骤:
- 检查并设置商品ID
- 调用购买接口获取支付参数
- 检查网络状态
- 发起微信支付
- 处理支付结果
async handleBuyVip() {
let that = this;
try {
// Step1: 调用购买接口获取支付的参数
const res = await buyVip({
goods_id: this.goods_id
});
if (res && res.data) {
// 缓存订单信息(用于可能的重新支付场景)
that.orderInfo = res.data;
// Step2: 网络状态检查
await uni.getNetworkType({
success: (networkRes) => {
if (networkRes.networkType === 'none') {
uni.showToast({
title: '网络未连接,请检查网络',
icon: 'none'
});
return Promise.reject('network unavailable') // 主动中断流程
}
// Step3: 发起支付请求
return new Promise((resolve, reject) => {
// 添加loading状态防止重复点击
uni.showLoading({
title: '发起支付中' })
uni.requestPayment({
...that.orderInfo, // 需要包含以下参数:
// timeStamp: 时间戳(单位秒)
// nonceStr: 随机字符串
// package: 统一下单接口返回的 prepay_id 格式如:prepay_id=***
// signType: 签名算法
// paySign: 签名
// 注意:不同小程序平台参数可能不同
success: res => {
uni.hideLoading()
// 支付成功后续处理
console.log("支付成功", res);
setTimeout(() => {
uni.navigateBack();
}, 1000);
resolve()
},
fail: err => {
uni.hideLoading()
console.error('支付失败', err)
// 区分用户取消支付和真正支付失败的情况
if (err.errCode === 6001) {
uni.showToast({
title: '您取消了支付', icon: 'none' })
} else {
uni.showToast({
title: '支付失败', icon: 'none' })
}
setTimeout(() => {
uni.navigateBack();
}, 1000);
reject(err)
}
});
});
}
});
} else {
// 处理接口异常情况
console.error('接口返回数据异常', res);
uni.showToast({
title: res?.msg || '获取支付信息失败',
icon: 'none'
});
}
} catch (error) {
// 统一错误处理
console.error('流程异常:', error);
uni.showToast({
title: error.message || '购买会员失败',
icon: 'none'
});
}
},
注意事项说明
1. 支付参数验证
时间戳单位:微信小程序要求timeStamp
为秒级时间戳(10位数字),需注意与毫秒级时间戳的区分。
参数完整性:确保orderInfo
包含以下必需参数:
{
timeStamp: '', // 支付签名时间戳
nonceStr: '', // 随机字符串
package: '', // 统一下单接口返回的 prepay_id
signType: '', // 签名算法 MD5/HMAC-SHA256/RSA等
paySign: '', // 签名
}
2. 网络状态处理
必要性检查:在发起支付前检查网络状态,避免在弱网环境下出现支付中断
异常处理:当检测到无网络时,建议:
- 显示明确的错误提示
- 记录失败日志
- 提供重试按钮
3. 支付结果处理
成功处理建议:
- 立即更新本地用户VIP状态
- 发送支付成功通知
- 跳转前建议先获取最新用户信息
失败处理建议:
- 区分用户主动取消
(errCode 6001)
和系统错误 - 保留在当前页面允许重新支付
- 记录失败日志用于后续分析
4. 用户体验优化
防止重复点击:
// 在方法开始处添加
if (this.isPaying) return
this.isPaying = true
// 在finally中添加
.finally(() => {
this.isPaying = false
})
加载状态提示:使用uni.showLoading()
防止用户误操作
跳转延迟:支付结果提示至少保持1秒后再跳转
5. 跨平台兼容
参数差异:不同小程序平台(微信/支付宝/百度)的支付参数可能不同
平台检测:
#ifdef MP-WEIXIN
// 微信专用参数
#endif
#ifdef MP-ALIPAY
// 支付宝专用参数
#endif
6. 安全注意事项
敏感信息处理:不要在客户端存储或传输支付密钥
签名验证:确保签名在服务端生成,客户端仅做参数传递
防重复支付:服务端需要校验订单状态
7. 错误监控
异常捕获:使用try-catch
包裹异步操作
日志记录:关键节点添加日志记录(建议使用唯一订单号跟踪)
错误上报:使用uni.report()
或第三方监控服务