接入微信支付
最近在用uni-app开发H5公众号网页,为什么选用这种方式呢?
有两个方面的考量:
1. 老项目本身基于uni-app;2. 考虑到后期可能会部署至多端。
uni-app在跨平台方面独树一帜,各种你能想到的平台,基本都能兼容。
在接入微信支付这方面,我踩了一些坑,现在把填坑的方式摆出来。
难点在哪?
整个开发流程下来,难点在服务端,因为服务端要做的事情很多。
包括:去微信服务器下单,更新本系统订单状态,关闭订单,退款等等。
服务端的难点也有对应方案,比如Java有WxJava这个库,里面实现了微信支付的便捷调用。
其他语言应该也有类似的库,感谢这些大神贡献了这些库。提升了大家的开发效率。
前端方面难点在于调试,必须在指定的域名环境下面调试,至少我是这样:
每次开发完,必须发版到线上进行调试,有问题又改,改了又发版调试。循环往复。
重点来了
提示: 此处针对uni-app + Vue 3 环境。
按正常几步走:
1. 安装依赖库
安装依赖:
npm install weixin-js-sdk
2. 导入微信支付工具js
保存路径: /common/wechatPayUtil.js
/*
* 微信(公众号)支付工具js
*/
import jWeixin from 'weixin-js-sdk'
export default {
install(app) {
app.config.globalProperties.$weChatPay = function(data, callback, errorCallback) {
let [appId, timeStamp, nonceStr, signature, packages, sign] = [data.appId, data.timeStamp, data
.nonceStr, data
.paySign, data.package, data.paySign
];
jWeixin.config({
debug: false,
appId,
timeStamp,
nonceStr,
signature,
jsApiList: ['chooseWXPay']
});
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
appId: appId,
timeStamp: timeStamp,
nonceStr: nonceStr,
package: packages,
signType: 'RSA',
paySign: sign
},
res => {
// 坑1: 微信支付新规则,支付成功时不会返回这,所以此处的代码成功时不会被调用.
// 支付成功时,如果没开通"点金计划",页面会被关闭,具体参考(1)
//
// 失败时:页面不会被关闭,会正常调用后续代码.
uni.showModal({
title: '提示',
content: `支付返回数据: ${JSON.stringify(res)}`,
})
if (res.err_msg == 'get_brand_wcpay_request:ok') {
callback(res)
} else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
errorCallback(res)
}
}
)
};
}
};
3. main.js
在main.js中注册上面的支付工具js文件:
import {
createSSRApp
} from 'vue'
import App from './App';
import wechatPayApi from './common/wechatPayUtil.js'
export function createApp() {
const app = createSSRApp(App)
app.use(wechatPayApi);
return {
app
}
}
4. 在具体页面调用
4.1 按钮
如果你没使用uv-ui(①),可以直接复制checkWeixinJSBridge(item),item是订单信息:
<uv-button
style="margin-left: 10rpx"
type="primary"
class="comment-botton"
@click="checkWeixinJSBridge(item)"
icon="edit-pen"
icon-color="#fff"
text="立即支付"
></uv-button>
4.2 js代码
注意: 请求后台接口的地址和方法,需要根据你自己的实际情况调整。
// 微信官方提供的兼容方法.
checkWeixinJSBridge(item) {
if (typeof WeixinJSBridge == 'undefined') {
//
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', this.callWechatPay(item), false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', this.callWechatPay(item));
document.attachEvent('onWeixinJSBridgeReady', this.callWechatPay(item));
}
} else {
this.callWechatPay(item);
}
},
// 调用微信支付
callWechatPay(item) {
if (!item.orderId) {
uni.showToast({
icon: 'error',
title: '支付订单获取失败,请稍候重试!'
});
return;
}
uni.showLoading({
title: '拉取支付信息中...请稍等'
});
const parent = this;
let url = '查询微信支付所需参数-后台接口';
let params = {
orderId: item.orderId,
// 参数......
};
uni.request({
url: url,
method: 'POST',
data: params,
success: (res) => {
let result = res.data;
let wepayObj = {
appId: result.appId,
timeStamp: result.timeStamp,
nonceStr: result.nonceStr,
package: result.package,
signType: 'RSA',
paySign: result.sign
};
parent.$weChatPay(
wepayObj,
function(res) {
// 这个地方不会被调用.
// 因为微信规则修改,支付成功后,需要开通"点金计划",会跳转到点金计划的页面.
//
console.log('成功', res);
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 跳转订单列表.
uni.redirectTo({
url: './index'
});
},
function(e) {
// 支付失败时,这里会被调用.
uni.showToast({
title: '支付失败或取消支付',
icon: 'error'
});
console.log('支付失败或取消支付', e);
}
);
},
fail: (err) => {}
});
}
有个疑问?
只看到了从服务端拉取支付订单信息,服务端啥时候去微信下单的?
很简单,前端提交订单的时候,服务端就去微信下单了。
下单之后,经过服务端计算,返回微信支付所需参数,前端拿着参数去提交支付。
大概流程是,
明白了吗?
相关链接:
①:uv-ui官方:
https://www.uvui.cn/
相关文章:
微信JSSDK安装问题:
微信支付“点金计划”相关:
微信支付JSAPI官方文档: