一、生成二维码~到支付
1、二维码插件qrious.js
a. 引入jquery和qrious.js
b.在页面上创建一个dom流作为容器,用于存放二维码
例如:
//也可以用标签
c.定义二维码对象
var qr = window.qr = new QRious({
element : document.getElementById("qrious"),//容器
value : code_url,//二维码所装载的url
size:230
});
2、后台和微信交互,返回支付url,前端将此url装载进二维码中
2.1、controller层
/*微信支付url*/
@RequestMapping("/getWeixinPayCodeUrl")
@ResponseBody
public Object weixinPayByQRCode(String total_fee) throws Exception {
String out_trade_no = String.valueOf(new Date().getTime());
Map resultMap = userConsumeService.getWeixinPayCodeUrl(out_trade_no, total_fee);
return resultMap;
}
2.2、service实现层
@Override
public Map getWeixinPayCodeUrl(String out_trade_no, String total_fee) throws Exception {
Map resultMap = new HashMap();
//判断金额是否和消费记录中一致
String consume_money = sqlSessionTemplate.selectOne("com.entry.order.UserConsume.getConsumeFeeById", out_trade_no);
if (StringUtils.isBlank(total_fee) || !total_fee.equals(consume_money)){
resultMap.put("status","error");
}
int Fee = (int)(Double.parseDouble(total_fee)*100);
//参数分装
Map paramMap = new HashMap();
paramMap.put("appid", ConstantUtil.APP_ID);// 微信开发平台应用id ok
paramMap.put("mch_id", ConstantUtil.PARTNER_ID); // 财付通商户号
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
paramMap.put("body", "EStore");//随意填(目前我没发现有啥用)
paramMap.put("out_trade_no", out_trade_no);//订单号
paramMap.put("total_fee", String.valueOf(Fee));//金额
paramMap.put("spbill_create_ip", "127.0.0.1");//终端ip(用不着)
paramMap.put("notify_url", "127.0.0.1");//通知地址(我这里采取的监测订单的方式,这个可以选择不填)
paramMap.put("trade_type", "NATIVE");//交易类型(扫码支付)
String paramXml = WXPayUtil.generateSignedXml(paramMap, ConstantUtil.PARTNER_KEY);
//发送请求
String xmlResult = HttpUtils.sendHttp("https://api.mch.weixin.qq.com/pay/unifiedorder", paramXml);
Map stringMap = WXPayUtil.xmlToMap(xmlResult);
//获取结果
resultMap.put("status","success");
resultMap.put("code_url",stringMap.get("code_url")); //该url用于和微信支付对接(装载进二维码中即可)
resultMap.put("out_trade_no",out_trade_no);
resultMap.put("total_fee",total_fee);
return resultMap;
}
2.3、注意点
a. WXPayUtil是微信提供的java开发SDK,从官网下载下来后,打包进maven仓库中,引入依赖即可使用
b. 微信的支付订单id非系统订单id,用各种算法生成不重复的数字最好(这里我图简单,就用的当前时间毫秒值),我们提交订单到微信时,就是用的这个id,查询支付状态时也是用的这个id,所以最好在前端页面保存这个id,当我们生成二维码时,可以将此id传到后台,监控该订单的支付状态.
c. 注意点2中,微信的支付订单id不可重复!否则不会返回code_url(请求过一次该id就被微信记录,无论是否支付成功)
二、查询订单支付状态
1、生成二维码之后就发送请求查询支付状态
var queryWeixinPayStatus = function () {
$.ajax({
type : "post",
url : "/EStore-web-boss/web/alipay/queryWeixinPayStatus",
data : {
out_trade_no : $("#weixinPayOrderId").text()//微信支付订单id
},
success : function(response){
if(response.status = "success"){
//弹框提示支付成功,5秒跳转至订单页面
$("#weixinQRCode").html($("#weixinPayError"));
$(".pb_btns").hide();
//倒计时
var i = 5;
var intervalid = setInterval(function(){
if (i == 0) {
clearInterval(intervalid);
location.href = '/EStore-web-boss/myOrder.html';
}
$("#second").text(i);
i--;
}, 1000);
}
}
})
}
2、后台循环查询订单支付状态
2.1、controller层
//查询微信支付状态
@RequestMapping("queryWeixinPayStatus")
@ResponseBody
public Object queryWeixinPayStatus(String out_trade_no) throws Exception {
Map resultMap = new HashMap();
while (true){
Map map = userConsumeService.queryWeixinPayStatus(out_trade_no);
if (map == null){
resultMap.put("status","error");
break;
}
if ("SUCCESS".equals(map.get("trade_state"))){
resultMap.put("status","success");
break;
}
Thread.sleep(3000);
}
return resultMap;
}
2.2、service实现层
@Override
public Map queryWeixinPayStatus(String out_trade_no){
//封装参数
Map paramMap = new HashMap();
paramMap.put("appid", ConstantUtil.APP_ID);
paramMap.put("mch_id", ConstantUtil.PARTNER_ID);
paramMap.put("out_trade_no", out_trade_no);
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
String paramXml = null;
try {
paramXml = WXPayUtil.generateSignedXml(paramMap, ConstantUtil.PARTNER_KEY);
//发送请求
String xmlResult = HttpUtils.sendHttp("https://api.mch.weixin.qq.com/pay/orderquery", paramXml);
//获取结果
Map stringMap = WXPayUtil.xmlToMap(xmlResult);
return stringMap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}