因为使用uni-app开发项目,从uni-app使用微信的云开发没有实现出来,所以使用前后端结合开发,没有使用微信云开发
必要条件
1,需要注册企业级的小程序且向腾讯打款支付300元进行过微信认证,然后你的微信公众平台控制台才会有微信支付等更多功能
2, 注册微信支付商户号并在微信公众平台控制台中接入并绑定商户号
3,
微信支付官方有操作文档
然后前端开始撰写代码
其实就是先获取到openid然后调用统一下单成功后调起微信支付,结合官方文档开发
import md5 from 'js-md5'; //签名需要md5加密要导入md5插件
import $request from './api.js' //自己封装的ajax请求
//封装成js cont需要的是支付的金额主体内容等,从使用的页面传入
function JsApiPay(cont) {
var nonce = "2022" + new Date().getTime() //随机字符串
var stamp = new Date().getTime() //时间戳
var trade_no = "abc2022" + new Date().getTime() //商户订单号
var macId = '' //商户号 mac_id
var notifyUrl = '' //回调地址 支付成功后会反参给改地址中
var that = this
wx.login({ //登录获取的code来获得openid
provider: 'weixin',
async success(code) {
console.log(code);
await wx.request({
url: 'https://api.weixin.qq.com/sns/jscode2session',
method: 'GET',
data: {
appid: '', //你的小程序的APPID
secret: '', //你的小程序的secret,
js_code: code.code
},
success: async (cts) => {
//openid
let open = cts.data.openid
console.log(open);
// 后端调用统一下单接口 (统一下单给后端调用)吧需要的参数传给后端
//------------------------------------------
$request.post(`/WXPay/WXPay/createdWxPay`, {
"body":trade_no,
"nonce": nonce,
"openId": open,
"outTradeNo": trade_no,
"totalFee": cont.total
}).then((ret) => {
if (ret.data.code == 200) {
console.log(ret);
//小程序/JSPAI支付签名还是用所有的必传的入参(不包括签名)以 键名=值& 的形势拼接起来,然后用md5加密并全部字母为大写 拼接可以直接使用这个需要填入你自己的appid等数据 key就是支付的API密钥
let PaymentSignStr =
`appId=&nonceStr=${nonce}&package=prepay_id=${ret.data.result.xml.prepay_id}&signType=MD5&timeStamp=${stamp}&key=`
PaymentSignStr = md5(PaymentSignStr).toUpperCase()
console.log(PaymentSignStr);
//调起微信支付
wx.requestPayment({
timeStamp: stamp.toString(),
nonceStr: nonce.toString(),
package: "prepay_id=" + ret.data.result.xml.prepay_id, //"prepay_id="必须这样写否则报错没有金额
signType: 'MD5',
paySign: PaymentSignStr,
success(req) {
console.log('成功', req);
wx.showToast({
icon: 'success',
title: '支付成功',
duration: 2000
});
return req
},
fail(err) {
wx.showToast({
icon: 'error',
title: '取消支付',
duration: 2000
});
console.log('错误', err);
return err
}
})
} else {
wx.showToast({
icon: 'error',
title: '统一下单失败',
duration: 2000
});
}
})
},
fail(err) {
reject(new Error('取到openid失败'))
}
})
},
fail(err) {
reject(new Error('微信登录失败'))
}
})
// 支付结束
}
export {
JsApiPay
}
商户的api秘钥,key值的获取,在微信商户后控制台中获取
第二段代码统一下单
//统一下单的签名,是将你调用的这个接口的所有必传的入参(不包括签名)以 键名=值& 的形势拼接起来,拼接的顺序要和入参一样,然后使用md5加密并全部字母为大写
let signStr = `appid=&body=${cont.body}&mch_id=${macId}&nonce_str=${nonce}¬ify_url=${notifyUrl}&openid=${open}&out_trade_no=${trade_no}&spbill_create_ip=127.0.0.1&total_fee=${cont.total}&trade_type=JSAPI&key=`
signStr = md5(signStr).toUpperCase()
//统一下单 data入参必须是xmL格式,获取prepay_id
await wx.request({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
method: 'POST',
headers: {
"content-type": "application/json;charset='utf-8'",
},
data: "<xml><appid><![CDATA[你的appid]]></appid><body><![CDATA["+cont.body+"]]></body><mch_id><![CDATA["+macId+"]]></mch_id><nonce_str><![CDATA[" +nonce +"]]></nonce_str><notify_url><![CDATA["+notifyUrl+"]]></notify_url><openid><![CDATA[" +open + "]]></openid><out_trade_no><![CDATA[" +trade_no +"]]></out_trade_no><spbill_create_ip><![CDATA[127.0.0.1]]></spbill_create_ip><total_fee><![CDATA["+cont.total+"]]></total_fee><trade_type><![CDATA[JSAPI]]></trade_type><sign>" +signStr + "</sign></xml>",
async success(res) {
if (res.statusCode == 200) {
//将xml格式转为json,再转对象
let pride = res.data
pride = pride.replace(/[\r\n]/g, '')
//小程序/JSPAI支付签名还是用所有的必传的入参(不包括签名)以 键名=值& 的形势拼接起来,然后用md5加密并全部字母为大写
let PaymentSignStr =
`appId=&nonceStr=${nonce}&package=prepay_id=${ret.data.result.xml.prepay_id}&signType=MD5&timeStamp=${stamp}&key=`
PaymentSignStr = md5(PaymentSignStr).toUpperCase()
console.log(PaymentSignStr);
//调起微信支付
wx.requestPayment({
timeStamp: stamp.toString(),
nonceStr: nonce.toString(),
package:"prepay_id="+ret.data.result.xml.prepay_id,
//"prepay_id="必须这样写否则报错没有金额
signType: 'MD5',
paySign: PaymentSignStr,
success(req) {
console.log('成功',req);
},
fail(err) {
console.log('错误',err);
}
})
}
}
})
复杂点在于:
1,签名的拼接,是将你调用的这个接口的所有必传的入参(不包括签名)以 键名=值& 的形势拼接起来,拼接的顺序要和入参一样,然后使用md5加密并全部字母为大写
2,统一下单的data必须是xml格式,但是要转换,前端不好转,让后端帮忙比较好
第二段代码放在第一地段代码的//--------------------------下面,把第一段代码的调起微信支付给去掉,最好让后端调用,因为后面小程序发布不给通过。