您的当前位置:首页正文

微信小程序微信支付(统一支付)

2024-11-29 来源:个人技术集锦

因为使用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}&notify_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格式,但是要转换,前端不好转,让后端帮忙比较好

第二段代码放在第一地段代码的//--------------------------下面,把第一段代码的调起微信支付给去掉,最好让后端调用,因为后面小程序发布不给通过。

显示全文