前言:由于uni.requestPayment没有封装H5支付方法,我自己封装了统一方法可以多端适用。
代码如下:
有两种方法:
方法1:安装 jweixin-module 包,我的是1.6.0版本->引入->使用
方法2:使用微信浏览器自带的方法WeixinJSBridge.invoke,前提是必须是微信浏览器才可以,但是不用安装包。官方文档
detail.js中
import { request } from '@/utils/request.js';
// #ifdef H5
const jweixin = require("jweixin-module");
// #endif
// 微信支付
export const wxPayment = (data) => {
return new Promise((resolve, reject) => {
let orderInfo = {
"appid": data.appId,
"timestamp": data.timeStamp, // 支付签名时间戳
"noncestr": data.nonceStr, // 支付签名随机串,不长于 32
"package": "Sign=WXPay", // 固定值
"partnerid": data.partnerid, // 微信支付商户号
"prepayid": data.prepay_id, // 统一下单订单号
"sign": data.paySign, // 支付签名
}
// #ifdef H5
jweixin.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timeStamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.paySign, // 必填,签名,见附录1
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
jweixin.ready(function() {
jweixin.checkJsApi({
jsApiList: ['chooseWXPay'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
console.log('checkjsapi Success', res);
},
fail: function(res) {
console.log('checkjsapi fail', res);
}
});
jweixin.chooseWXPay({
timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位
package: `prepay_id=${data.prepay_id}`, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: data.paySign, // 支付签名
success: function(res) {
console.log('success',res);
resolve(res)
},
cancel: function(res) {
console.log('cancel', res)
},
fail: function(res) {
console.log('fail',res);
reject(res)
}
});
});
jweixin.error(function(res) {
console.log('err', res);
reject(res)
});
// WeixinJSBridge.invoke(
// 'getBrandWCPayRequest', {
// "appId": data.appId,
// "timeStamp": data.timeStamp, // 支付签名时间戳
// "nonceStr": data.nonceStr, // 支付签名随机串,不长于 32
// "package": `prepay_id=${data.prepay_id}`,
// "signType": data.signType, //微信签名方式:
// "paySign": data.paySign, //微信签名
// },
// function(res) {
// // 支付成功
// if (res.err_msg == "get_brand_wcpay_request:ok") {
// // 使用以上方式判断前端返回,微信团队郑重提示:
// //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// resolve(res)
// }
// // 支付过程中用户取消
// if (res.err_msg == "get_brand_wcpay_request:cancel") {
// }
// // 支付失败
// if (res.err_msg == "get_brand_wcpay_request:fail") {
// reject(res)
// }
// /**
// * 其它
// * 1、请检查预支付会话标识prepay_id是否已失效
// * 2、请求的appid与下单接口的appid是否一致
// * */
// if (res.err_msg == "调用支付JSAPI缺少参数:total_fee") {
// alert('调用支付JSAPI缺少参数:total_fee')
// }
// });
// #endif
// #ifndef H5
uni.requestPayment({
provider: 'wxpay',
orderInfo,
success: res => resolve(res),
fail: res => reject(res)
})
// #endif
})
}
detail.vue使用
import { wxPayment, wechatPay, } from "@/api/detail.js"
...
methods: {
// 立即购买
handelPay() {
// 扫码-1 公众号-2 小程序-3 app-4
let payType = 2
// #ifdef MP-WEIXIN
payType = 3
// #endif
// #ifdef APP-PLUS
payType = 4
// #endif
// 生成订单
wechatPay({
payType: payType,
goodsName: this.resource.resourceTitle,
price: this.resource.price,
resourceId: this.resourceId,
userId: this.userId,
openId: this.userOpenId,
}).then(res => {
console.log('res', res);
// 订单号
let orderNo = res.orderNo
wxPayment(res.result).then(res => {
console.log('微信支付res', res);
// 跳转至成功页面
this.$common._jumpToUrl('/pages/components/paySuccess', 1, { curOrderId: res.orderNo })
}).catch(err => {
console.log('微信支付err', err);
this.$common._showToast('支付失败')
})
}).catch(err => {
console.log('err', err);
this.$common._showToast('支付失败')
})
},
}
...
注意点:
- 支付时成功获取订单号,但是调微信提示支付验证签名失败
这种情况主要从以下分析: - 公众号是否具有支付权限。
- 看一下参数是否都传对,大小写需要注意。
- appId是否是后台传过来的,不要写死。
- 微信支付接口签名校验工具是否校验通过,有的时候虽然微信支付接口签名校验工具显示校验通过,但是仍然会提示,他只能校验不能保证参数的正确性。
- 秘钥key是否正确
- 如果以上都没问题,还要确认生成的签名是否缺少参数(我就是这种情况一天都在排除问题)