最近公司需要做一个微信扫码支付的功能,已完成用户扫描二维码完成付款,通过查询微信的开发文档,已完成上述功能,接下来我会进行分享并进行讲解有关微信扫支付的相关信息
项目需求:用户下单后,处理完订单,将订单状态改变后,给用户端生成二维码,用户通过扫描二维码完成付款
下面我会针对我写的代码逐一解释(链接我都会以xxx代替,只需要换成你的具体名称即可)
@RequestMapping("/xxx.do")
@ResponseBody
public Map<String, Object> weChatSweepPay(
@RequestParam(value="orderId",required=false) final Integer orderId,//订单id
@RequestParam(value="sessionId",required=false) final String sessionId,//登录标识
HttpServletRequest request,HttpServletResponse response
){
BasisWxagent agent = null;(微信的相关参数.如appId,secret之类的等,你们都知道)
//定义一个map集合
Map<String, Object> result = new HashMap<String, Object>();
//校验订单是否存在,
RepairOrder order = repairOrderService.getRepairOrderByPrimaryKey(orderId);
if(order == null) {
// TODO: 错误处理
result.put("errMsg", "订单不存在");
result.put("returnCode", "FAIL");
return result;
}
//定义这个主要作用是用户执行合并支付,用不到合并支付的直接就使用orderId即可
ArrayList<Integer> orderIdList = new ArrayList<>(); orderIdList.add(orderId);
result.put("orderIdList", orderIdList);
result.put("orderId", orderId);
//支付来源,用户区分是扫码支付还是微信支付
result.put("paySource",WxPayUtil.PAYSOURCE_WEIXINQR);
//微信定义的支付分类,(JSAPI:小程序,APP:安卓手机端;NATIVE:微信扫码支付;公众号:JSAPI)这里不懂的可以看微信开发文档
String trade_type;
//我们公司是将微信需要的参数放入表里了.这都是在去需要的数据
agent = WxAgent.getWorkerAppAgent();
//将需要的参数放入map集合
result.put("agentId", agent.getId());
Integer payType=9;
result.put("payType", payType);
//将map集合转为json串
String attach = JSONObject.fromObject(result).toString();
//定义支付的类型为扫码支付
trade_type = "NATIVE";
// 商户相关资料(需要提前申请,具体看文档即可,这里我就不再说明了)
String appid = agent.getAppId();
String partner = agent.getPartnerId();
String partnerkey = agent.getPartnerKey();
// 商户号
String mch_id = partner;
// 随机数
String nonce_str = WxPayUtil.generateNonceStr();
// 订单生成的机器 IP
String spbill_create_ip = request.getRemoteAddr();
// 这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。
String notify_url = Common.getRequestUrl(request, "/wxpay/notifyStatus.do");
// 非必输(都是微信需要的参数.我就不做解释了)
SortedMap<String, String> packageParams = new TreeMap<String, String>();
String body="微信扫码支付订单";
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("attach", attach);
String out_trade_no = WxPayUtil.getOutTradeNo(orderId, order.getOrderNumber(), WxPayUtil.PAYSOURCE_WEIXINQR);
//修改该订单的outtradenumber
repairOrderService.updateOutTradeNo(orderId, out_trade_no);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("total_fee",order.getAmount().toString());
logger.info("支付金额" + order.getAmount().toString());
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", notify_url);
packageParams.put("trade_type", trade_type);
String sign = WxPayUtil.createSign(packageParams, partnerkey);
packageParams.put("sign", sign);
String sign = WxPayUtil.createSign(packageParams, partnerkey);
packageParams.put("sign", sign);
String openid = "";
if (sessionId != null && !sessionId.isEmpty()) {
openid = WeiXinSession.getOpenId(sessionId);
}else {
openid = Common.getOpenId(request);
}
//把刚刚填入的参数在以微信需要的格式放入xml中(不要问为什么,腾讯规定的)
String xml = "<xml>"
+ "<appid>" + appid + "</appid>"
+ "<mch_id>" + mch_id + "</mch_id>"
+ "<nonce_str>" + nonce_str + "</nonce_str>"
+ "<sign>" + sign + "</sign>"
+ "<body><![CDATA[" + body + "]]></body>"
+ "<attach><![CDATA[" + attach + "]]></attach>"
+ "<out_trade_no>" + out_trade_no + "</out_trade_no>"
+"<total_fee>" + order.getAmount().toString() + "</total_fee>"
+ "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
+ "<notify_url>" + notify_url + "</notify_url>"
+ "<trade_type>" + trade_type + "</trade_type>"
+ ("NATIVE".equals(trade_type) ? "" : "<openid>" + openid + "</openid>")
+ "</xml>";
//通知微信的url(看文档即可)
String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//下面就需要将url我们自己写好的sml以post的方式提交给微信即可,我们使用的request的方式
String content = WeixinUtil.httpsRequestStringEntity(createOrderURL, "POST", xml);
//查看调用结果,如果调用成功,回返回SUCCESS
logger.info("调用结果" + content);
//接下来,就需要解析content,我们请求成功后,微信会在xml给我们返回一个url
try {
String content = WeixinUtil.httpsRequestStringEntity(createOrderURL, "POST", xml);
logger.info("调用结果" + content);
//解析xml(这里各位可以根据自己的方式,只要解析出来即可)
Map<String, String> mapfromXML = XMLUtil.MapfromXML(content);
if (mapfromXML.get("return_code").equals("SUCCESS")) {
//返回success后,获取到code_url.然后调用谷歌的二维码工具类,生成二维码即可
String code_url = mapfromXML.get("code_url");
//将qrCode二维码图片返回给app端,调用工具类
response.setContentType("image/png");
//调用工具类生成二维码
OutputStream out = null;
try {
out = response.getOutputStream();
QRCodeUtil.generateQRCodeWithLogo(request, code_url, 300, 300, "jpg", out);
logger.info("二维码生成成功!");
} catch (Exception e) {
// TODO: handle exception
logger.error("生成二维码异常!"+code_url);
e.printStackTrace();
}finally {
if(out!=null)
out.close();
}
}
} catch (Exception e1) {
e1.printStackTrace();
logger.error("提交支付查询订单失败!");
result.put("errcode", "-1");
result.put("errmsg", "支付失败请与管理员联系");
return result;
}
//如果你能走到这里,证明已经生成二维码了,接下来,就是用户付完款之后,微信支付回调,我们获取回调参数,执行订单状态修改的一系列操作今天太累了,改天再来分享
//如果您觉得有用,并且帮到了您,请帮忙为博主支付点辛苦费吧,钱不在多少,只需要一份您的认可
2017/09/23
-------------------------------阿甘菜鸟原创