1 packagecom.qtkj.app.weixinpay.controller;2
3 importjava.io.ByteArrayOutputStream;4 importjava.io.IOException;5 importjava.io.InputStream;6 importjava.io.PrintWriter;7 importjava.io.UnsupportedEncodingException;8 importjava.math.BigDecimal;9 importjava.text.ParseException;10 importjava.text.SimpleDateFormat;11 importjava.util.Date;12 importjava.util.HashMap;13 importjava.util.LinkedHashMap;14 importjava.util.Map;15
16 importjavax.servlet.http.HttpServletRequest;17 importjavax.servlet.http.HttpServletResponse;18
19 importorg.jdom2.JDOMException;20 importorg.springframework.beans.factory.annotation.Autowired;21 importorg.springframework.stereotype.Controller;22 importorg.springframework.ui.Model;23 importorg.springframework.web.bind.annotation.RequestMapping;24 importorg.springframework.web.bind.annotation.RequestMethod;25 importorg.springframework.web.bind.annotation.RequestParam;26 importorg.springframework.web.bind.annotation.ResponseBody;27
28 importcom.qtkj.admin.common.CacheXmlConfig;29 importcom.qtkj.admin.settings.entity.SiteConfig;30 importcom.qtkj.admin.user.entity.User;31 importcom.qtkj.admin.user.service.UserService;32 importcom.qtkj.app.weixinpay.handler.ClientRequestHandler;33 importcom.qtkj.app.weixinpay.handler.PrepayIdRequestHandler;34 importcom.qtkj.app.weixinpay.util.ConstantUtil;35 importcom.qtkj.app.weixinpay.util.MD5Util;36 importcom.qtkj.app.weixinpay.util.TenpayUtil;37 importcom.qtkj.app.weixinpay.util.UUID;38 importcom.qtkj.app.weixinpay.util.WXUtil;39 importcom.qtkj.app.weixinpay.util.XMLUtil;40 importcom.qtkj.user.entity.Trade;41 importcom.qtkj.user.service.TradeService;42 importcom.qtkj.util.NumberUtils;43 importcom.qtkj.util.PageHelper;44
45
46 /**
47 *
Title:WeiXinPayController
48 *Description:
49 *Company:
50 *@authorZHAO51 *@date 2017年10月27日52 */53 @Controller54 public classWeiXinPayController {55
56 @Autowired57 privateTradeService tradeservice;58
59 @Autowired60 privateTradeService tradeService;61
62 @Autowired63 privateUserService userService;64
65 //------------------------------------------------------------------------------------------------------------------------------------------------------------------
66
67 /**
68 * 9.1.生成订单69 *@authorZhao70 *@date 2017年10月31日71 *@paramrequest72 *@paramresponse73 *@parammodel74 *@paramlegalMoney 充值法币金额(legalMoney)75 *@paramtotalPrice 充值金额(RMB)76 *@paramuserId 用户id77 *@return
78 *@throwsException79 */
80 @RequestMapping("api/weixin/createOrder")81 @ResponseBody82 publicModel doWeinXinRequest(HttpServletRequest request,HttpServletResponse response,Model model,83 @RequestParam("totalPrice") String totalPrice,84 @RequestParam("legalMoney") String legalMoney,85 @RequestParam("userId") String userId86 ) throwsException {87 Map resultMap = new LinkedHashMap<>();88 try{89
90 //---------------2 生成订单号 开始------------------------91 //2.1.当前时间 yyyyMMddHHmmss
92 String currTime =TenpayUtil.getCurrTime();93 //2.2 8位日期
94 String strTime = currTime.substring(8, currTime.length());95 //2.3四位随机数
96 String strRandom = TenpayUtil.buildRandom(4) + "";97 //2.4 10位序列号,可以自行调整。
98 String strReq = strTime +strRandom;99 //2.5 订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行
100 String out_trade_no =strReq;101 //---------------生成订单号 结束 ------------------------102
103 //3.获取生成预支付订单的请求类
104 PrepayIdRequestHandler prepayReqHandler = newPrepayIdRequestHandler(request, response);105
106 //3.1封装数据
107 String nonce_str = WXUtil.getNonceStr(); //订单号
108 out_trade_no =String.valueOf(UUID.next());109 String timestamp = WXUtil.getTimeStamp(); //超时时间110
111 //3.2---------------------------------------------- ***** 统一下单开始 ***** -----------------------------------------------------------
112 prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID); //平台应用appId
113 prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID); //商户号
114 prepayReqHandler.setParameter("nonce_str", nonce_str); //随机字符串
115 prepayReqHandler.setParameter("body", ConstantUtil.BODY); //商品描述
116 prepayReqHandler.setParameter("out_trade_no", out_trade_no); //订单号
117 prepayReqHandler.setParameter("total_fee",String.valueOf(totalPrice)); //订单价格
118 prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr()); //获取客户端ip
119 prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL); //回调通知
120 prepayReqHandler.setParameter("trade_type", "APP"); //支付类型
121 prepayReqHandler.setParameter("time_start", timestamp); //时间戳
122 prepayReqHandler.setGateUrl(ConstantUtil.GATEURL); //设置预支付id的接口url123
124 //3.3 注意签名(sign)的生成方式,具体见官方文档(传参都要参与生成签名,且参数名按照字典序排序,最后接上APP_KEY,转化成大写)
125 prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign()); //sign 签名126
127 //3.4 提交预支付,获取prepayid
128 String prepayid =prepayReqHandler.sendPrepay();129 //---------------------------------------------- ***** 统一下单 结束 ***** --------------------------------------------------------------130
131 //3.5 若获取prepayid成功,将相关信息返回客户端
132 if (prepayid != null && !prepayid.equals("")) {133
134
135 //---------------4.封装订单数据开始 ------------------------
136 此处用于封装你自己实体类的订单信息137
138 例:Trade trade = newTrade();139
140 //---------------4.封装订单数据开始 ------------------------
141
142 String signs =
143 "appid=" + ConstantUtil.APP_ID +
144 "&noncestr=" + nonce_str +
145 "&package=Sign=WXPay"+
146 "&partnerid="+ ConstantUtil.PARTNER_ID +
147 "&prepayid=" + prepayid +
148 "×tamp=" + timestamp+
149 "&key="+ConstantUtil.APP_KEY;150
151 resultMap.put("appid", ConstantUtil.APP_ID);152 resultMap.put("partnerid", ConstantUtil.PARTNER_ID); //商家id
153 resultMap.put("prepayid", prepayid); //预支付id
154 resultMap.put("package", "Sign=WXPay"); //固定常量
155 resultMap.put("noncestr", nonce_str); //与请求prepayId时值一致
156 resultMap.put("timestamp", timestamp); //等于请求prepayId时的time_start
157 resultMap.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());//签名方式与上面类似
158 model.addAttribute("orderNum", out_trade_no);159 model.addAttribute("resultMap", resultMap);160 model.addAttribute("msg", "获取prepayid成功,生成订单成功");161 model.addAttribute("status",0);162 }else{163 model.addAttribute("msg", "获取prepayid失败");164 model.addAttribute("status",1);165 }166 } catch(Exception e) {167 model.addAttribute("msg", "订单生成失败");168 model.addAttribute("status",2);169 }170 returnmodel;171 }172
173 /**
174 * 9.2 接收微信支付成功通知175 *@paramrequest176 *@paramresponse177 *@throwsIOException178 *@throwsjava.io.IOException179 *@throwsParseException180 */
181 @RequestMapping(value = "api/weixin/notify")182 public voidgetnotify(HttpServletRequest request, HttpServletResponse response)183 throwsIOException, ParseException {184 System.err.println("微信支付回调");185 System.err.println("微信支付回调");186 //1.创建输入输出流
187 PrintWriter writer =response.getWriter();188 InputStream inStream =request.getInputStream();189 ByteArrayOutputStream outSteam = newByteArrayOutputStream();190 byte[] buffer = new byte[1024];191 int len = 0;192 while ((len = inStream.read(buffer)) != -1) {193 outSteam.write(buffer, 0, len);194 }195 outSteam.close();196 inStream.close();197 //2.将结果转换
198 String result = new String(outSteam.toByteArray(), "utf-8");199 System.out.println("微信支付通知结果:" +result);200 Map map = null;201 try{202 //3.解析微信通知返回的信息
203 map =XMLUtil.doXMLParse(result);204 System.err.println(map);205 } catch(JDOMException e) {206 e.printStackTrace();207 }208 //4.若支付成功,则告知微信服务器收到通知
209 if (map.get("return_code").equals("SUCCESS")) {210 if (map.get("result_code").equals("SUCCESS")) {211 System.out.println("充值成功!");212 //4.1 修改当前订单状态为:付款成功 2
213 System.err.println("交易号:"+Long.valueOf(map.get("out_trade_no")));214 //Trade trade = tradeservice.selectByOrderNumber((String)(map.get("out_trade_no")));
215 Trade trade = tradeservice.selectByTradeNumber((String)(map.get("out_trade_no")));216 if(trade !=null){217 trade.setTradeType((byte)2); //设置状态
218 trade.setPaymentTime(newDate());219 trade.setPayTime(newDate());220 if(tradeservice.updateByPrimaryKeySelective(trade) > 0){221 //更新成功
222 System.err.println("通知微信后台");223 String notifyStr = XMLUtil.setXML("SUCCESS", "");224 writer.write(notifyStr);225 writer.flush();226 }227 }else{228 String notifyStr = XMLUtil.setXML("ERROR", "");229 writer.write(notifyStr);230 writer.flush();231 }232 }233 }234 }235
236 /**
237 *微信支付成功后.通知页面238 *@authorZhao239 *@date 2017年11月2日240 *@paramrequest241 *@return
242 *@throwsUnsupportedEncodingException243 */
244 @RequestMapping(value="api/weixin/return",method={RequestMethod.POST,RequestMethod.GET})245 @ResponseBody246 public Model returnUrl(@RequestParam("id") String id,HttpServletRequest request,Model model) throwsUnsupportedEncodingException {247 System.err.println("。。。。。。 微信同步通知 。。。。。。");248 System.err.println("。。。。。。 微信同步通知 。。。。。。");249 System.err.println("。。。。。。 微信同步通知 。。。。。。");250 Map returnMap = newHashMap();251 try{252
253 Trade trade =tradeservice.selectByTradeNumber(id);254 //返回值Map
255 if(trade !=null && trade.getTradeStatus() == 2){256 257 User user =userService.selectByPrimaryKey(trade.gettUserId());
258 returnMap.put("tradeType", trade.getTradeType()); //支付方式
259 returnMap.put("phoneNum", user.getPhoneNumber()); //支付帐号
260 returnMap.put("tradeMoney", trade.getTradeMoney()+""); //订单金额
261 }else{262 model.addAttribute("msg", "查询失败");263 model.addAttribute("status", 0);264 }265 model.addAttribute("returnMap", returnMap);266 System.err.println(returnMap);267 model.addAttribute("msg", "查询成功");268 model.addAttribute("status", 0);269 } catch(Exception e) {270 model.addAttribute("msg", "查询失败");271 model.addAttribute("status", 1);272 }273
274 returnmodel;275 }276 }