微信APP支付Java后台总结
2018-01-22 14:07
716 查看
微信APP支付大致的流程和支付宝APP支付有很大不同(想了解支付宝APP支付的同学点这里),其中略坑的一点就是MD5加密的方法需要自己写,好在微信官方给出了测试地址。
APP_ID : 服务号的应用ID
APP_SECRET : 服务号的应用密钥
TOKEN : 服务号的配置token
MCH_ID : 商户号
API_KEY : API密钥
SIGN_TYPE : 签名加密方式
CERT_PATH : 微信支付证书名称、
Java代码
支付回调
微信的支付回调是用流形式传输的,所以要先对流形式的数据进行解析再得到我们需要的东西。
代码中包含一些常用的工具类,是从别人的资源来下载来的,觉得很好用。
前置准备
微信的东西比支付宝要复杂一点,要先去注册开发者账号,然后一系列巴拉巴拉……,然后得到下面列出的我们开发需要的参数,下面的参数中TOKEN和CERT_PATH是需要退款和设计到其他功能才需要的,如果只做APP支付功能的同学可以忽略。APP_ID : 服务号的应用ID
APP_SECRET : 服务号的应用密钥
TOKEN : 服务号的配置token
MCH_ID : 商户号
API_KEY : API密钥
SIGN_TYPE : 签名加密方式
CERT_PATH : 微信支付证书名称、
支付流程
具体的流程大概就是后台拿到(或生成)自己的订单号后,拿着一堆参数按ASCII码(即abc…)排序后用MD5加密后调用微信的服务器地址拿到一个prepayId,再将prepayId和当前的参数再次排序和加密(二次加密)生成sign后返回前端进行支付,支付完成后,微信的后台会回调我们的后台接口。Java代码
maven依赖`<!-- 微信支付依赖 --> <dependency> <groupId>org.xmlpull</groupId> <artifactId>xmlpull</artifactId> <version>1.1.3.1 </version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.3</version> <classifier>jdk15</classifier> </dependency> <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.5</version> </dependency> <!-- https://mvnrepository.com/artifact/com.ning/async-http-client --> <dependency> <groupId>com.ning</groupId> <artifactId>async-http-client</artifactId> <version>1.8.13</version> </dependency>`
Java代码
@ResponseBody @RequestMapping(value="/wxpaySign",method=RequestMethod.POST) public JsonResult getWXPaySign(double totalAmount,String userId,String out_trade_no,String ip) throws JDOMException, IOException{ //预备参数 WXPayDTO wxPayDTO = new WXPayDTO(); String subject = "******"; String body = "******"; String nonceStr = setNonceStr(); long timeStamp = (long)CommonUtil.getSecondTimestamp(new Date()); String packageStr = "Sign=WXPay"; String total_fee = String.valueOf(CommonUtil.double100ToInt(totalAmount)); SortedMap<String,String> payMap = genOrderData(PayConstants.WX_APP_ID,body,out_trade_no, nonceStr,packageStr,PayConstants.WX_PARTNER_ID,total_fee,subject,ip); //设置WXPayDTO wxPayDTO.setAppId(PayConstants.WX_APP_ID); //商家id wxPayDTO.setPartnerId(PayConstants.WX_PARTNER_ID); wxPayDTO.setPrepayId(out_trade_no); //订单 wxPayDTO.setNonceStr(nonceStr); //设置随机串 wxPayDTO.setTimeStamp(timeStamp); //设置时间戳 wxPayDTO.setPackageStr(packageStr); wxPayDTO.setSign(payMap.get("sign")); wxPayDTO.setPrepayId(payMap.get("prepayid")); return new JsonResult(Message.M2000,wxPayDTO); }
private SortedMap<String, String> genOrderData(String appId, String body, String out_trade_no, String nonceStr, String packageStr, String partnerId,String total_fee,String subject,String ip) throws JDOMException, IOException { SortedMap<String, String> paraMap = new TreeMap<String,String>(); //按照官方文档的要求,这里参数名ASCII码从小到大排序(字典序); paraMap.put("appid", appId); paraMap.put("body",body); paraMap.put("mch_id",partnerId); //微信商户账号 paraMap.put("nonce_str",nonceStr); //32位不重复的编号 paraMap.put("notify_url", PayConstants.WX_Notify_Url); //设置一个回调的地址 paraMap.put("out_trade_no", out_trade_no); //订单号 paraMap.put("spbill_create_ip", ip);//前端传回来的ip paraMap.put("total_fee",total_fee); //设置金额 paraMap.put("trade_type","APP"); //方式为APP支付 //用上面封装的参数生成sign String sign = PayCommonUtil.createSign("UTF-8", paraMap,PayConstants.WX_API_KEY); //这里的sign用二次签名生成的sign paraMap.put("sign",sign); //统一下单地址 //将上面集合内容转成xml String xml = getRequestXML(paraMap); String xmlStr = HttpUtil.postData(PayConstants.WX_Notify_Url,xml); //将返回的xml转换成map Map map = XMLUtil.doXMLParse(xmlStr); //预付商品id String prepay_id = (String) map.get("prepay_id"); //这里要对参数进行二次签名 SortedMap<String, String> secParaMap = new TreeMap<String,String>(); secParaMap.put("appid", appId); secParaMap.put("partnerid",partnerId); secParaMap.put("prepayid", prepay_id); //这里不确定是不是要重新生成一个随机串,再改 secParaMap.put("noncestr", nonceStr); secParaMap.put("timestamp", CommonUtil.getTimeStamp()); secParaMap.put("package", "Sign=WXPay"); String secSign = PayCommonUtil.createSign("UTF-8", secParaMap, PayConstants.WX_API_KEY); secParaMap.put("sign", secSign); secParaMap.put("prepayid", prepay_id); return secParaMap; }
支付回调
微信的支付回调是用流形式传输的,所以要先对流形式的数据进行解析再得到我们需要的东西。
@RequestMapping(value = "payNotifyUrl", produces = "application/json;charset=UTF-8") @ResponseBody public String payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception { //读取参数 InputStream inputStream ; StringBuffer sb = new StringBuffer(); inputStream = request.getInputStream(); String s ; BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); while ((s = in.readLine()) != null){ sb.append(s); } in.close(); inputStream.close(); //解析xml成map Map<String, String> m = new HashMap<String, String>(); m = XMLUtil.doXMLParse(sb.toString()); //过滤空 设置 TreeMap SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>(); Iterator it = m.keySet().iterator(); while (it.hasNext()) { String parameter = (String) it.next(); String parameterValue = m.get(parameter); String v = ""; if(null != parameterValue) { v = parameterValue.trim(); } packageParams.put(parameter, v); } //判断签名是否正确 if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,PayConstants.WX_API_KEY)) { //------------------------------ //处理业务开始 //------------------------------ String resXml = ""; if("SUCCESS".equals((String)packageParams.get("result_code"))){ // 这里是支付成功 //////////执行自己的业务逻辑//////////////// String mch_id = (String)packageParams.get("mch_id"); String openid = (String)packageParams.get("openid"); String is_subscribe = (String)packageParams.get("is_subscribe"); String out_trade_no = (String)packageParams.get("out_trade_no"); String total_fee = (String)packageParams.get("total_fee"); System.out.println("mch_id:"+mch_id); System.out.println("openid:"+openid); logger.info("is_subscribe:"+is_subscribe); logger.info("out_trade_no:"+out_trade_no); logger.info("total_fee:"+total_fee); //////////执行自己的业务逻辑//////////////// logger.info("支付成功"); //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了. resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; } else { logger.info("支付失败,错误信息:" + packageParams.get("err_code")); resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> "; } //------------------------------ //处理业务完毕 //------------------------------ BufferedOutputStream out = new BufferedOutputStream( response.getOutputStream()); out.write(resXml.getBytes()); out.flush(); out.close(); } else{ logger.info("通知签名验证失败"); } return "SUCCESS"; }
代码中包含一些常用的工具类,是从别人的资源来下载来的,觉得很好用。
相关文章推荐
- 微信APP支付(IOS手机端+java后台)版
- 微信APP支付(Java后台生成签名具体步骤)
- 微信APP支付-Java后台实现
- 微信APP支付(Java后台生成签名具体步骤)
- 微信APP支付(Java后台生成签名具体步骤)
- 微信APP支付-Java后台实现
- 微信APP支付(IOS手机端+java后台)版
- 微信APP支付-Java后台实现
- 微信app支付java后台流程、原理分析及nei网穿透 转载自(http://www.cnblogs.com/MrRightZhao/p/7930916.html)
- 微信APP支付-Java后台实现
- 微信APP支付Java后端回调处理
- 支付宝微信app 支付签名后台完整demo
- 微信APP支付,后台回调
- 微信APP支付Java代码
- java服务端微信APP支付接口详解
- java服务端–微信APP支付接口
- 微信App支付总结(返回-1什么的最e心)
- 支付宝APP支付之Java后台生成签名具体步骤
- 微信APP支付Java后端回调处理
- java实现微信App支付服务端