java微信支付原理_微信app支付java后台流程、原理分析及nei网穿透

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 "&timestamp=" + 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 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值