微信支付 java 服務端demo (v3版本app支付 springMVC框架中)
阿新 • • 發佈:2019-01-03
//靜態資源 /** * @author 徐小驥 * @version :2016-5-9 上午11:43:48 */ public class WeixinPayConstants { public static final String appid = "XXXXXX";//在微信開發平臺登記的app應用 public static final String appsecret = "XXXXXXXXX"; public static final String partner = "XXXXXXXXX";//商戶號 public static final String partnerkey ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";//不是商戶登入密碼,是商戶在微信平臺設定的32位長度的api祕鑰, public static final String createOrderURL="https://api.mch.weixin.qq.com/pay/unifiedorder"; public static final String backUri="http://XXXXXXXX/api/weixin/topay.jhtml";//微信支付下單地址 public static final String notify_url="http://XXXXXXXXXX/api/weixin/notify.jhtml";//非同步通知地址 } // /** * @author 徐小驥 * @version :2016-5-9 上午11:46:48 */ @Controller("weixinPayController") @RequestMapping("/api/weixin") public class WeixinPayController { @Resource(name = "memberServiceImpl") private MemberService memberService; @Resource(name = "orderServiceImpl") private RecordsConsumptionService recordsConsumptionService; //商戶相關資料 private static String appid = WeixinPayConstants.appid; private static String appsecret = WeixinPayConstants.appsecret; private static String partner = WeixinPayConstants.partner; private static String partnerkey = WeixinPayConstants.partnerkey; @RequestMapping(value = "/topay") @ResponseBody public void topay(HttpServletRequest request,HttpServletResponse response) throws Exception{ request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String orderNo= request.getParameter("Orderid"); String mobile= request.getParameter("mobile"); PrintWriter out = response.getWriter(); String json=null; JSONObject retMsgJson=new JSONObject(); if(orderNo==null||mobile==null){ retMsgJson.put("msg", "error"); retMsgJson.put("body", "資料請求異常"); json=retMsgJson.toString(); out.write(json); out.close(); return; } Member member=memberService.findListByMobile(mobile);//獲取使用者資料 Order order=orderService.find(Long.valueOf(orderNo));//獲取訂單資料 //驗證訂單與支付會員關係 if(member==null||order==null){ retMsgJson.put("msg", "error"); retMsgJson.put("body", "資料請求異常"); json=retMsgJson.toString(); out.write(json); out.close(); return; } if(!order.getMember().equals(member)){ retMsgJson.put("msg", "error"); retMsgJson.put("body", "無許可權處理訂單"); json=retMsgJson.toString(); out.write(json); out.close(); return; } if(!order.getPaymentStatus().equals(Order.PaymentStatus.unpaid)){ retMsgJson.put("msg", "error"); retMsgJson.put("body", "訂單狀態異常"); json=retMsgJson.toString(); out.write(json); out.close(); return; } String userId = member.getId().toString(); String money = order.getAmount().toString();//獲取訂單金額 //金額轉化為分為單位 float sessionmoney = Float.parseFloat(money); String finalmoney = String.format("%.2f", sessionmoney); finalmoney = finalmoney.replace(".", ""); String currTime = TenpayUtil.getCurrTime(); //8位日期 String strTime = currTime.substring(8, currTime.length()); //四位隨機數 String strRandom = TenpayUtil.buildRandom(4) + ""; //10位序列號,可以自行調整。 String strReq = strTime + strRandom; //商戶號 String mch_id = partner; //子商戶號 非必輸 //String sub_mch_id=""; //裝置號 非必輸 String device_info=""; //隨機數 String nonce_str = strReq; String body = order.getName(); //附加資料 String attach = userId; //商戶訂單號 String out_trade_no = order.getSn()+"|"+System.currentTimeMillis();//訂單編號加時間戳 int intMoney = Integer.parseInt(finalmoney); //總金額以分為單位,不帶小數點 String total_fee = String.valueOf(intMoney); //訂單生成的機器 IP String spbill_create_ip = request.getRemoteAddr(); String notify_url =WeixinPayConstants.notify_url;//微信非同步通知地址 String trade_type = "APP";//app支付必須填寫為APP //對以下欄位進行簽名 SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", appid); packageParams.put("attach", attach); packageParams.put("body", body); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str); packageParams.put("notify_url", notify_url); packageParams.put("out_trade_no", out_trade_no); packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("total_fee", total_fee); packageParams.put("trade_type", trade_type); RequestHandler reqHandler = new RequestHandler(request, response); reqHandler.init(appid, appsecret, partnerkey); String sign = reqHandler.createSign(packageParams);//獲取簽名 String xml="<xml>"+ "<appid>"+appid+"</appid>"+ "<attach>"+attach+"</attach>"+ "<body><![CDATA["+body+"]]></body>"+ "<mch_id>"+mch_id+"</mch_id>"+ "<nonce_str>"+nonce_str+"</nonce_str>"+ "<notify_url>"+notify_url+"</notify_url>"+ "<out_trade_no>"+out_trade_no+"</out_trade_no>"+ "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+ "<total_fee>"+total_fee+"</total_fee>"+ "<trade_type>"+trade_type+"</trade_type>"+ "<sign>"+sign+"</sign>"+ "</xml>"; String allParameters = ""; try { allParameters = reqHandler.genPackage(packageParams); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } String createOrderURL = WeixinPayConstants.createOrderURL; String prepay_id=""; try { prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml); if(prepay_id.equals("")){ retMsgJson.put("msg", "error"); json=retMsgJson.toString(); out.write(json); out.close(); return; } } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //獲取到prepayid後對以下欄位進行簽名最終傳送給app SortedMap<String, String> finalpackage = new TreeMap<String, String>(); String timestamp = Sha1Util.getTimeStamp(); finalpackage.put("appid", appid); finalpackage.put("timestamp", timestamp); finalpackage.put("noncestr", nonce_str); finalpackage.put("partnerid", WeixinPayConstants.partner); finalpackage.put("package", "Sign=WXPay"); finalpackage.put("prepayid", prepay_id); String finalsign = reqHandler.createSign(finalpackage); retMsgJson.put("msg", "ok"); retMsgJson.put("appid", appid); retMsgJson.put("timestamp", timestamp); retMsgJson.put("noncestr", nonce_str); retMsgJson.put("partnerid", WeixinPayConstants.partner); retMsgJson.put("prepayid", prepay_id); retMsgJson.put("package", "Sign=WXPay"); retMsgJson.put("sign", finalsign); json=retMsgJson.toString(); out.write(json); out.close(); } //微信非同步通知 @RequestMapping(value = "/notify") @ResponseBody public void notify(HttpServletRequest request,HttpServletResponse response) throws Exception{ request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); response.setHeader("Access-Control-Allow-Origin", "*"); InputStream in=request.getInputStream(); ByteArrayOutputStream out=new ByteArrayOutputStream(); byte[] buffer =new byte[1024]; int len=0; while((len=in.read(buffer))!=-1){ out.write(buffer, 0, len); } out.close(); in.close(); String msgxml=new String(out.toByteArray(),"utf-8");//xml資料 System.out.println(msgxml); Map map = new GetWxOrderno().doXMLParse(msgxml); String result_code=(String) map.get("result_code"); String out_trade_no = (String) map.get("out_trade_no"); String total_fee = (String) map.get("total_fee"); String sign = (String) map.get("sign"); Double amount=new Double(total_fee)/100;//獲取訂單金額 String attach= (String) map.get("attach"); String sn=out_trade_no.split("\\|")[0];//獲取訂單編號 Long memberid=Long.valueOf(attach); Member member=memberService.find(memberid); Order order=orderService.findBySn(sn); if(result_code.equals("SUCCESS")&&member!=null&&order!=null){ //驗證簽名 float sessionmoney = Float.parseFloat(order.getAmount().toString()); String finalmoney = String.format("%.2f", sessionmoney); finalmoney = finalmoney.replace(".", ""); int intMoney = Integer.parseInt(finalmoney); //總金額以分為單位,不帶小數點 String order_total_fee = String.valueOf(intMoney); String fee_type = (String) map.get("fee_type"); String bank_type = (String) map.get("bank_type"); String cash_fee = (String) map.get("cash_fee"); String is_subscribe = (String) map.get("is_subscribe"); String nonce_str = (String) map.get("nonce_str"); String openid = (String) map.get("openid"); String return_code = (String) map.get("return_code"); String sub_mch_id = (String) map.get("sub_mch_id"); String time_end = (String) map.get("time_end"); String trade_type = (String) map.get("trade_type"); String transaction_id = (String) map.get("transaction_id"); //需要對以下欄位進行簽名 SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", appid); packageParams.put("attach", order.getMember().getId().toString()); //用自己系統的資料:會員id packageParams.put("bank_type", bank_type); packageParams.put("cash_fee", cash_fee); packageParams.put("fee_type", fee_type); packageParams.put("is_subscribe", is_subscribe); packageParams.put("mch_id", partner); packageParams.put("nonce_str", nonce_str); packageParams.put("openid", openid); packageParams.put("out_trade_no", out_trade_no); packageParams.put("result_code", result_code); packageParams.put("return_code", return_code); packageParams.put("sub_mch_id", sub_mch_id); packageParams.put("time_end", time_end); packageParams.put("total_fee", order_total_fee); //用自己系統的資料:訂單金額 packageParams.put("trade_type", trade_type); packageParams.put("transaction_id", transaction_id); RequestHandler reqHandler = new RequestHandler(request, response); reqHandler.init(appid, appsecret, partnerkey); String endsign = reqHandler.createSign(packageParams); if(sign.equals(endsign)){//驗證簽名是否正確 官方簽名工具地址:https://pay.weixin.qq.com/wiki/tools/signverify/ if("訂單沒有支付"){ try{ //處理自己的業務邏輯 response.getWriter().write(setXml("SUCCESS", "OK")); //告訴微信已經收到通知了 }catch(Exception e){ System.out.println("微信支付非同步通知異常"); } }else if("訂單支付了"){ response.getWriter().write(setXml("SUCCESS", "OK")); //告訴微信已經收到通知了 } } } } public static String setXml(String return_code,String return_msg){ return "<xml><return_code><![CDATA["+return_code+"]]></return_code><return_msg><![CDATA["+return_msg+"]]></return_msg></xml>"; } }
附上本文微信app支付開發所用到的工具類下載地址
http://download.csdn.net/detail/xu_xiao_ji/9516695