微信支付 java 服务端demo (v3版本app支付 springMVC框架中)

来源:互联网 发布:六角碎片游戏源码 编辑:程序博客网 时间:2024/05/22 04:43
[java] view plain copy
  1. //静态资源  
  2.   
  3. /**  
  4.  * @author 徐小骥 
  5.  * @version :2016-5-9 上午11:43:48  
  6.  */  
  7.   
  8. public class WeixinPayConstants {  
  9.     public static final String appid = "XXXXXX";//在微信开发平台登记的app应用  
  10.     public static final String appsecret = "XXXXXXXXX";  
  11.     public static final String partner = "XXXXXXXXX";//商户号  
  12.     public static final String partnerkey ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";//不是商户登录密码,是商户在微信平台设置的32位长度的api秘钥,  
  13.     public static final String createOrderURL="https://api.mch.weixin.qq.com/pay/unifiedorder";  
  14.     public static final String backUri="http://XXXXXXXX/api/weixin/topay.jhtml";//微信支付下单地址  
  15.     public static final String notify_url="http://XXXXXXXXXX/api/weixin/notify.jhtml";//异步通知地址  
  16. }  
  17.   
  18. //  
  19.   
  20. /**  
  21.  * @author 徐小骥 
  22.  * @version :2016-5-9 上午11:46:48  
  23.  */  
  24. @Controller("weixinPayController")  
  25. @RequestMapping("/api/weixin")  
  26. public class WeixinPayController {  
  27. @Resource(name = "memberServiceImpl")  
  28. private MemberService memberService;  
  29. @Resource(name = "orderServiceImpl")  
  30. private RecordsConsumptionService  recordsConsumptionService;  
  31. //商户相关资料   
  32. private static String appid = WeixinPayConstants.appid;  
  33. private static String appsecret = WeixinPayConstants.appsecret;  
  34. private static String partner = WeixinPayConstants.partner;  
  35. private static String partnerkey = WeixinPayConstants.partnerkey;  
  36. @RequestMapping(value = "/topay")   
  37. @ResponseBody public void topay(HttpServletRequest request,HttpServletResponse response) throws Exception{  
  38.     request.setCharacterEncoding("UTF-8");  
  39.     response.setCharacterEncoding("UTF-8");  
  40.     response.setContentType("text/html;charset=UTF-8");  
  41.     String orderNo= request.getParameter("Orderid");  
  42.     String mobile= request.getParameter("mobile");  
  43.     PrintWriter out = response.getWriter();  
  44.     String json=null;  
  45.      JSONObject retMsgJson=new JSONObject();  
  46.     if(orderNo==null||mobile==null){  
  47.         retMsgJson.put("msg""error");  
  48.         retMsgJson.put("body""数据请求异常");  
  49.         json=retMsgJson.toString();                   
  50.         out.write(json);  
  51.         out.close();  
  52.         return;  
  53.     }  
  54.     Member member=memberService.findListByMobile(mobile);//获取用户数据  
  55.     Order order=orderService.find(Long.valueOf(orderNo));//获取订单数据  
  56.      //验证订单与支付会员关系  
  57.      if(member==null||order==null){  
  58.         retMsgJson.put("msg""error");  
  59.         retMsgJson.put("body""数据请求异常");  
  60.         json=retMsgJson.toString();                   
  61.         out.write(json);  
  62.         out.close();  
  63.         return;  
  64.     }  
  65.     if(!order.getMember().equals(member)){  
  66.         retMsgJson.put("msg""error");  
  67.         retMsgJson.put("body""无权限处理订单");  
  68.         json=retMsgJson.toString();                   
  69.         out.write(json);  
  70.         out.close();  
  71.         return;  
  72.     }  
  73.     if(!order.getPaymentStatus().equals(Order.PaymentStatus.unpaid)){  
  74.         retMsgJson.put("msg""error");  
  75.         retMsgJson.put("body""订单状态异常");  
  76.         json=retMsgJson.toString();                   
  77.         out.write(json);  
  78.         out.close();  
  79.         return;  
  80.     }  
  81.     String userId = member.getId().toString();    
  82.     String money = order.getAmount().toString();//获取订单金额  
  83.     //金额转化为分为单位  
  84.     float sessionmoney = Float.parseFloat(money);  
  85.     String finalmoney = String.format("%.2f", sessionmoney);  
  86.     finalmoney = finalmoney.replace(".""");  
  87.             String currTime = TenpayUtil.getCurrTime();  
  88.             //8位日期  
  89.             String strTime = currTime.substring(8, currTime.length());  
  90.             //四位随机数  
  91.             String strRandom = TenpayUtil.buildRandom(4) + "";  
  92.             //10位序列号,可以自行调整。  
  93.             String strReq = strTime + strRandom;          
  94.             //商户号  
  95.             String mch_id = partner;  
  96.             //子商户号  非必输  
  97.             //String sub_mch_id="";  
  98.             //设备号   非必输  
  99.             String device_info="";  
  100.             //随机数   
  101.             String nonce_str = strReq;  
  102.             String body = order.getName();  
  103.             //附加数据  
  104.             String attach = userId;  
  105.             //商户订单号  
  106.             String out_trade_no = order.getSn()+"|"+System.currentTimeMillis();//订单编号加时间戳  
  107.             int intMoney = Integer.parseInt(finalmoney);              
  108.             //总金额以分为单位,不带小数点  
  109.             String total_fee = String.valueOf(intMoney);  
  110.             //订单生成的机器 IP  
  111.             String spbill_create_ip = request.getRemoteAddr();  
  112.             String notify_url =WeixinPayConstants.notify_url;//微信异步通知地址           
  113.             String trade_type = "APP";//app支付必须填写为APP  
  114.                         //对以下字段进行签名  
  115.             SortedMap<String, String> packageParams = new TreeMap<String, String>();  
  116.             packageParams.put("appid", appid);    
  117.             packageParams.put("attach", attach);   
  118.             packageParams.put("body", body);    
  119.             packageParams.put("mch_id", mch_id);      
  120.             packageParams.put("nonce_str", nonce_str);    
  121.             packageParams.put("notify_url", notify_url);    
  122.             packageParams.put("out_trade_no", out_trade_no);      
  123.             packageParams.put("spbill_create_ip", spbill_create_ip);   
  124.             packageParams.put("total_fee", total_fee);  
  125.             packageParams.put("trade_type", trade_type);    
  126.             RequestHandler reqHandler = new RequestHandler(request, response);  
  127.             reqHandler.init(appid, appsecret, partnerkey);        
  128.             String sign = reqHandler.createSign(packageParams);//获取签名  
  129.             String xml="<xml>"+  
  130.                     "<appid>"+appid+"</appid>"+  
  131.                     "<attach>"+attach+"</attach>"+  
  132.                     "<body><![CDATA["+body+"]]></body>"+  
  133.                     "<mch_id>"+mch_id+"</mch_id>"+  
  134.                     "<nonce_str>"+nonce_str+"</nonce_str>"+  
  135.                     "<notify_url>"+notify_url+"</notify_url>"+  
  136.                     "<out_trade_no>"+out_trade_no+"</out_trade_no>"+  
  137.                     "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+  
  138.                     "<total_fee>"+total_fee+"</total_fee>"+  
  139.                     "<trade_type>"+trade_type+"</trade_type>"+  
  140.                     "<sign>"+sign+"</sign>"+  
  141.                     "</xml>";  
  142.             String allParameters = "";  
  143.             try {  
  144.                 allParameters =  reqHandler.genPackage(packageParams);  
  145.              } catch (Exception e) {  
  146.                 // TODO Auto-generated catch block  
  147.                 e.printStackTrace();  
  148.             }  
  149.             String createOrderURL = WeixinPayConstants.createOrderURL;  
  150.             String prepay_id="";  
  151.             try {  
  152.                 prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);  
  153.                 if(prepay_id.equals("")){  
  154.                 retMsgJson.put("msg""error");  
  155.                 json=retMsgJson.toString();                   
  156.                 out.write(json);  
  157.                 out.close();  
  158.                 return;  
  159.                  }  
  160.             } catch (Exception e1) {  
  161.                 // TODO Auto-generated catch block  
  162.                 e1.printStackTrace();  
  163.              }  
  164.                         //获取到prepayid后对以下字段进行签名最终发送给app  
  165.                        SortedMap<String, String> finalpackage = new TreeMap<String, String>();  
  166.             String timestamp = Sha1Util.getTimeStamp();  
  167.             finalpackage.put("appid", appid);    
  168.             finalpackage.put("timestamp", timestamp);    
  169.             finalpackage.put("noncestr", nonce_str);    
  170.             finalpackage.put("partnerid", WeixinPayConstants.partner);   
  171.             finalpackage.put("package""Sign=WXPay");                
  172.             finalpackage.put("prepayid", prepay_id);    
  173.             String finalsign = reqHandler.createSign(finalpackage);  
  174.                     retMsgJson.put("msg""ok");  
  175.                     retMsgJson.put("appid", appid);  
  176.                     retMsgJson.put("timestamp", timestamp);  
  177.                     retMsgJson.put("noncestr", nonce_str);  
  178.                     retMsgJson.put("partnerid", WeixinPayConstants.partner);  
  179.                     retMsgJson.put("prepayid", prepay_id);  
  180.                     retMsgJson.put("package""Sign=WXPay");  
  181.                     retMsgJson.put("sign", finalsign);  
  182.                     json=retMsgJson.toString();                   
  183.                     out.write(json);  
  184.                     out.close();  
  185. }  
  186. //微信异步通知  
  187. @RequestMapping(value = "/notify")   
  188. @ResponseBody public void notify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
  189.     request.setCharacterEncoding("UTF-8");  
  190.     response.setCharacterEncoding("UTF-8");  
  191.     response.setContentType("text/html;charset=UTF-8");  
  192.     response.setHeader("Access-Control-Allow-Origin""*");   
  193.     InputStream in=request.getInputStream();  
  194.     ByteArrayOutputStream out=new ByteArrayOutputStream();  
  195.     byte[] buffer =new byte[1024];  
  196.     int len=0;  
  197.     while((len=in.read(buffer))!=-1){  
  198.         out.write(buffer, 0, len);  
  199.     }  
  200.     out.close();  
  201.     in.close();  
  202.     String msgxml=new String(out.toByteArray(),"utf-8");//xml数据  
  203.     System.out.println(msgxml);     
  204.     Map map =  new GetWxOrderno().doXMLParse(msgxml);  
  205.     String result_code=(String) map.get("result_code");  
  206.     String out_trade_no  = (String) map.get("out_trade_no");  
  207.     String total_fee  = (String) map.get("total_fee");  
  208.     String sign  = (String) map.get("sign");  
  209.     Double amount=new Double(total_fee)/100;//获取订单金额  
  210.     String attach= (String) map.get("attach");  
  211.     String sn=out_trade_no.split("\\|")[0];//获取订单编号  
  212.     Long memberid=Long.valueOf(attach);  
  213.     Member member=memberService.find(memberid);  
  214.     Order order=orderService.findBySn(sn);  
  215.     if(result_code.equals("SUCCESS")&&member!=null&&order!=null){  
  216.       //验证签名  
  217.         float sessionmoney = Float.parseFloat(order.getAmount().toString());  
  218.         String finalmoney = String.format("%.2f", sessionmoney);  
  219.         finalmoney = finalmoney.replace(".""");  
  220.         int intMoney = Integer.parseInt(finalmoney);              
  221.         //总金额以分为单位,不带小数点  
  222.         String order_total_fee = String.valueOf(intMoney);  
  223.         String fee_type  = (String) map.get("fee_type");  
  224.         String bank_type  = (String) map.get("bank_type");  
  225.         String cash_fee  = (String) map.get("cash_fee");  
  226.         String is_subscribe  = (String) map.get("is_subscribe");  
  227.         String nonce_str  = (String) map.get("nonce_str");  
  228.         String openid  = (String) map.get("openid");  
  229.         String return_code  = (String) map.get("return_code");  
  230.         String sub_mch_id  = (String) map.get("sub_mch_id");  
  231.         String time_end  = (String) map.get("time_end");  
  232.         String trade_type  = (String) map.get("trade_type");  
  233.         String transaction_id  = (String) map.get("transaction_id");  
  234.                 //需要对以下字段进行签名  
  235.         SortedMap<String, String> packageParams = new TreeMap<String, String>();  
  236.         packageParams.put("appid", appid);    
  237.         packageParams.put("attach", order.getMember().getId().toString()); //用自己系统的数据:会员id  
  238.         packageParams.put("bank_type", bank_type);    
  239.         packageParams.put("cash_fee", cash_fee);    
  240.         packageParams.put("fee_type", fee_type);      
  241.         packageParams.put("is_subscribe", is_subscribe);    
  242.         packageParams.put("mch_id", partner);    
  243.         packageParams.put("nonce_str", nonce_str);        
  244.         packageParams.put("openid", openid);   
  245.         packageParams.put("out_trade_no", out_trade_no);  
  246.         packageParams.put("result_code", result_code);    
  247.         packageParams.put("return_code", return_code);        
  248.         packageParams.put("sub_mch_id", sub_mch_id);   
  249.         packageParams.put("time_end", time_end);  
  250.         packageParams.put("total_fee", order_total_fee);    //用自己系统的数据:订单金额  
  251.         packageParams.put("trade_type", trade_type);   
  252.         packageParams.put("transaction_id", transaction_id);  
  253.         RequestHandler reqHandler = new RequestHandler(request, response);  
  254.         reqHandler.init(appid, appsecret, partnerkey);        
  255.         String endsign = reqHandler.createSign(packageParams);  
  256.         if(sign.equals(endsign)){//验证签名是否正确  官方签名工具地址:https://pay.weixin.qq.com/wiki/tools/signverify/   
  257.             if("订单没有支付"){  
  258.                 try{  
  259.                 //处理自己的业务逻辑  
  260.                 response.getWriter().write(setXml("SUCCESS""OK"));    //告诉微信已经收到通知了  
  261.                 }catch(Exception e){  
  262.                     System.out.println("微信支付异步通知异常");  
  263.                 }  
  264.             }else if("订单支付了"){  
  265.                 response.getWriter().write(setXml("SUCCESS""OK"));    //告诉微信已经收到通知了  
  266.             }  
  267.       
  268.         }  
  269.     }  
  270.     }  
  271.     public static String setXml(String return_code,String return_msg){  
  272.         return "<xml><return_code><![CDATA["+return_code+"]]></return_code><return_msg><![CDATA["+return_msg+"]]></return_msg></xml>";  
  273. }  
  274. }  
  275.    

附上本文微信app支付开发所用到的工具类下载地址
http://download.csdn.net/detail/xu_xiao_ji/9516695