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);