uni-app微信支付总结

公司开发的app中涉及到微信支付,app使用的是uni-app,后台开发语言是java。

开发中遇到的坑

问题:

根据官方文档完成支付代码后,点击支付,跳转到微信立即返回了app中,报"requestPayment:fail error"错误。

解决方法:

查找官方文档,查看大小写问题。


https://ask.dcloud.net.cn/question/74068
https://ask.dcloud.net.cn/question/97255

不断在网上查找前辈们在支付上遇到的坑,得到:清理微信或卸载微信重新安装之后可以支付,但是按照前辈们的方法试了,可以支付成功一次,之后就有事报"requestPayment:fail error"错误,显示”包名不对,检查包名是否与开放平台的一致“问题。




https://developers.weixin.qq.com/community/develop/doc/000e6eb72388a85c89c91dac45b400

查找到需要修改微信开放平台上的签名,重新生成签名之后,app上还是报"requestPayment:fail error"错误,显示”包名不对,检查包名是否与开放平台的一致“问题。相比较之前较好的是,后台有提示信息INFO wxpay java sdk - [run,150] - try get remain report msg,查找网上信息,需要在后台pom.xml中加入下面代码,成功了!

<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
		    </plugin>


最终实现代码

uni-app支付代码:

<view class="flex justify-center">
	<button class="cu-btn lines-blue round btn-padding shadow" :disabled="flag" @tap="payMoney">支付</button>
</view>
let data = {
					fee: that.sum,
					goodsId: goodsId,
					productsId: productsId,
					quantity: quantitys,
					customerId: dealerId
				}
				uni.request({
					url: this.Global + '/common/dealer/v1/wxPay/getPayment',
					method: 'POST',
					header: {
						"Content-Type": 'application/x-www-form-urlencoded;charset=utf-8',
					},
					data: data,
					success: function(res) {
						that.flag = false;
						if (res.statusCode != 200) {
							wx.showToast({
								icon: 'none',
								title: '服务器故障,暂时不能支付' + res.Data
							})
							return;
						}
						if (res.data.msgCode == 1) {
							that.flag = false;
							uni.showToast({
								title: res.data.errMsg,
								icon: 'none',
								duration: 4000
							})
							return;
						}
						var ret = res.data;
						console.log(ret);
						var orderInfo = {
							appid: ret.appid,
							partnerid: ret.partnerid,
							prepayid: ret.prepayid,
							package: ret.package,
							noncestr: ret.noncestr,
							timestamp: ret.timestamp,
							sign: ret.sign
						}
						uni.requestPayment({
							provider: 'wxpay',
							orderInfo: JSON.stringify(orderInfo),
							success: function(res) {
								that.flag = false;
								wx.showModal({
									icon: 'none',
									title: '支付成功',
									content: '支付成功',
									showCancel: false
								});
								uni.redirectTo({
									url: '../index/index'
								});
							},
							fail: function(res) {
								that.flag = false;
								console.log(res);
								wx.showToast({
									icon: 'none',
									title: res.errMsg
								})
							},
							complete: function(res) {
								that.flag = false;
								console.log(res);
							}
						});
					}
				});

java后台代码:

版本一(未经测试版):

paraMap.put("appid", AppID); // 商家平台ID
            paraMap.put("body", "recharge");
            paraMap.put("mch_id", mchID); // 商户ID
            paraMap.put("nonce_str", WXPayUtil.generateNonceStr()); // UUID
            paraMap.put("out_trade_no", orderNumber);// 订单号,每次都不同
            paraMap.put("spbill_create_ip", "127.0.0.1");
            paraMap.put("fee_type", "CNY");
            paraMap.put("total_fee", String.valueOf((int)((Math.round(Double.parseDouble(fee) * 100) * 0.01d)*100))); // 支付金额,单位分
            paraMap.put("trade_type", "APP"); // 支付类型
            paraMap.put("notify_url", notifyurl+"/api/common/dealer/v1/wxPay/notify");// 此路径是微信服务器调用支付结果通知路径随意写
            paraMap.put("device_info", customerId+"");
            paraMap.put("time_expire", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(new Date().getTime() + 60000)));//交易结束时间(1分钟后)
            String sign = WXPayUtil.generateSignedXml(paraMap, appKey);
            //paraMap.put("sign", sign);
            //String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式
            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            // String xmlStr = HttpRequest.sendPost(unifiedorder_url,
            // xml);//发送post请求"统一下单接口"返回预支付id:prepay_id
            String xmlStr = HttpRequest.httpsRequest(unifiedorder_url, "POST", sign);
            // 以下内容是返回前端页面的json数据
            String prepay_id = "";// 预支付id
            String nonceStr = "";
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = (String) map.get("prepay_id");
                nonceStr = (String) map.get("nonce_str");
            }
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appid", AppID);
            payMap.put("partnerid", mchID);
            payMap.put("prepayid", prepay_id);
            payMap.put("timestamp", WXPayUtil.getCurrentTimestamp() + "");
            //这边的随机字符串必须是第一次生成sign时,微信返回的随机字符串,不然小程序支付时会报签名错误
            payMap.put("noncestr", nonceStr);
            payMap.put("package", "Sign=WXPay");
            String paySign = WXPayUtil.generateSignature(payMap, appKey);
            payMap.put("sign", paySign);
            //将这个6个参数传给前端
            return payMap;

版本二(最终实现版):

WXPay wxpay = new WXPay(wxPayAppConfig);
            Map<String, String> data = new HashMap<>();
            data.put("appid", wxPayAppConfig.getAppID());
            data.put("body", "recharge");
            data.put("mch_id", wxPayAppConfig.getMchID());

            data.put("nonce_str", WXPayUtil.generateNonceStr());
            //异步通知地址(请注意必须是外网)
            data.put("notify_url", notifyurl + "/api/common/dealer/v1/wxPay/notify");

            data.put("out_trade_no", orderNumber);
            //自己的服务器IP地址
            data.put("spbill_create_ip", "127.0.0.1");
            data.put("total_fee", String.valueOf((int)((Math.round(Double.parseDouble(fee) * 100) * 0.01d)*100)));

            //交易类型
            data.put("trade_type", "APP");
            //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据

            data.put("sign", WXPayUtil.generateSignature(data, wxPayAppConfig.getKey(),
                    WXPayConstants.SignType.MD5));
            data.put("device_info", customerId+"");
            data.put("time_expire", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(new Date().getTime() + 60000)));//交易结束时间(1分钟后)


            //使用官方API请求预付订单
            Map<String, String> response = wxpay.unifiedOrder(data);
            String return_code = response.get("return_code");
            if ("SUCCESS".equals(response.get("return_code"))) {//主要返回以下5个参数
                Map<String, String> param = new HashMap<>();
                param.put("appid", wxPayAppConfig.getAppID());
                param.put("partnerid", wxPayAppConfig.getMchID());
                param.put("prepayid", response.get("prepay_id"));
                //param.put("noncestr", WXPayUtil.generateNonceStr());
                param.put("package", "Sign=WXPay");
                param.put("noncestr", WXPayUtil.generateNonceStr());
                param.put("timestamp", WXPayUtil.getCurrentTimestamp()+"");
                //param.put("package", response.get("sign"));
                param.put("sign", WXPayUtil.generateSignature(param, wxPayAppConfig.getKey(),
                        WXPayConstants.SignType.MD5));
                return param;
            }
            paraMap.put("errMsg", "统一下单失败 " + return_code);