个人觉得核心部分的代码:
签名:
//参数:开始生成签名 SortedMap<Object,Object> parameters = new TreeMap<Object,Object>(); parameters.put("appid", appid); parameters.put("mch_id", mch_id); parameters.put("nonce_str", nonce_str); parameters.put("body", body); parameters.put("nonce_str", nonce_str); parameters.put("detail", detail); parameters.put("attach", attach); parameters.put("out_trade_no", out_trade_no); parameters.put("total_fee", total_fee); parameters.put("time_start", time_start); parameters.put("time_expire", time_expire); parameters.put("notify_url", notify_url); parameters.put("trade_type", trade_type); parameters.put("spbill_create_ip", spbill_create_ip);
/** * 微信支付签名算法sign * @param characterEncoding * @param parameters * @return */ @SuppressWarnings("rawtypes") public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){ StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + Key); System.out.println("字符串拼接后是:"+sb.toString()); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }
将一坨参数包装成XML格式丢给微信:
/** * 构造xml参数 * @param xml * @return */ public static String xmlInfo(Unifiedorder unifiedorder){ //构造xml参数的时候,至少有10个必传参数 /* * <xml> <appid>wx2421b1c4370ec43b</appid> <attach>支付测试</attach> <body>JSAPI支付测试</body> <mch_id>10000100</mch_id> <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str> <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url> <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid> <out_trade_no>1415659990</out_trade_no> <spbill_create_ip>14.23.150.211</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <sign>0CB01533B8C1EF103065174F50BCA001</sign> </xml> */ if(unifiedorder!=null){ StringBuffer bf = new StringBuffer(); bf.append("<xml>"); bf.append("<appid><![CDATA["); bf.append(unifiedorder.getAppid()); bf.append("]]></appid>"); bf.append("<mch_id><![CDATA["); bf.append(unifiedorder.getMch_id()); bf.append("]]></mch_id>"); bf.append("<nonce_str><![CDATA["); bf.append(unifiedorder.getNonce_str()); bf.append("]]></nonce_str>"); bf.append("<sign><![CDATA["); bf.append(unifiedorder.getSign()); bf.append("]]></sign>"); bf.append("<body><![CDATA["); bf.append(unifiedorder.getBody()); bf.append("]]></body>"); bf.append("<detail><![CDATA["); bf.append(unifiedorder.getDetail()); bf.append("]]></detail>"); bf.append("<attach><![CDATA["); bf.append(unifiedorder.getAttach()); bf.append("]]></attach>"); bf.append("<out_trade_no><![CDATA["); bf.append(unifiedorder.getOut_trade_no()); bf.append("]]></out_trade_no>"); bf.append("<total_fee><![CDATA["); bf.append(unifiedorder.getTotal_fee()); bf.append("]]></total_fee>"); bf.append("<spbill_create_ip><![CDATA["); bf.append(unifiedorder.getSpbill_create_ip()); bf.append("]]></spbill_create_ip>"); bf.append("<time_start><![CDATA["); bf.append(unifiedorder.getTime_start()); bf.append("]]></time_start>"); bf.append("<time_expire><![CDATA["); bf.append(unifiedorder.getTime_expire()); bf.append("]]></time_expire>"); bf.append("<notify_url><![CDATA["); bf.append(unifiedorder.getNotify_url()); bf.append("]]></notify_url>"); bf.append("<trade_type><![CDATA["); bf.append(unifiedorder.getTrade_type()); bf.append("]]></trade_type>"); bf.append("</xml>"); return bf.toString(); } return ""; }
//构造xml参数 String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder); String wxUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String method = "POST"; String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
因为body部分是商品的名称什么的,设计到中文,这个过程可能毁在统一下单的时候提醒:body不是UTF-8编码(我擦,我就在这里折腾了半天的 http://blog.csdn.net/xb12369/article/details/50512633)
然后开始统一下单得到预支付ID,包装好给app端,app端处理好后再由微信开始回调,回调就会跳转到你的回调地址上,微信说建议校验下签名,照做就是的!
/** * 微信支付回调 * @param request * @param resposne */ @RequestMapping(value="/notifyUrlWeixin") public void notifyWeixinPayment(HttpServletRequest request,HttpServletResponse response){ try{ BufferedReader reader = request.getReader(); String line = ""; StringBuffer inputString = new StringBuffer(); try{ PrintWriter writer = response.getWriter(); while ((line = reader.readLine()) != null) { inputString.append(line); } if(reader!=null){ reader.close(); } System.out.println("----[微信回调]接收到的报文---"+inputString.toString()); if(!StringUtils.isEmpty(inputString.toString())){ WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(inputString.toString()); if("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())){ SortedMap<Object,Object> parameters = new TreeMap<Object,Object>(); parameters.put("appid", wxPayResult.getAppid()); parameters.put("attach", wxPayResult.getAttach()); parameters.put("bank_type", wxPayResult.getBank_type()); parameters.put("cash_fee", wxPayResult.getCash_fee()); parameters.put("fee_type", wxPayResult.getFee_type()); parameters.put("is_subscribe", wxPayResult.getIs_subscribe()); parameters.put("mch_id", wxPayResult.getMch_id()); parameters.put("nonce_str", wxPayResult.getNonce_str()); parameters.put("openid", wxPayResult.getOpenid()); parameters.put("out_trade_no", wxPayResult.getOut_trade_no()); parameters.put("result_code", wxPayResult.getResult_code()); parameters.put("return_code", wxPayResult.getReturn_code()); parameters.put("time_end", wxPayResult.getTime_end()); parameters.put("total_fee", wxPayResult.getTotal_fee()); parameters.put("trade_type", wxPayResult.getTrade_type()); parameters.put("transaction_id", wxPayResult.getTransaction_id()); //反校验签名 String sign = WXSignUtils.createSign("UTF-8", parameters); if(sign.equals(wxPayResult.getSign())){ //修改订单的状态 orderService.alipayNotifyPayment(wxPayResult.getOut_trade_no(), wxPayResult.getTransaction_id(),2); writer.write(HttpXmlUtils.backWeixin("SUCCESS","OK")); }else{ writer.write(HttpXmlUtils.backWeixin("FAIL","签名失败")); } }else{ writer.write(HttpXmlUtils.backWeixin("FAIL",wxPayResult.getReturn_msg())); System.out.println("---------微信支付返回Fail----------"+wxPayResult.getReturn_msg()); } if(writer!=null){ writer.close(); } }else{ writer.write(HttpXmlUtils.backWeixin("FAIL","未获取到微信返回的结果")); } }catch(Exception e){ e.printStackTrace(); } }catch(Exception ex){ ex.printStackTrace(); } }
到这里差不多这个流程就算完了!!!!
下面是源码地址:http://download.csdn.net/detail/xb12369/9403396
注:1、修改资源文件中的 resources/sys.properties
#weixin apy
appid=你们的appid
mch_id=你们的mch_id
notify_url=你们的回调地址
2、key weixin/Utils/WXSignUtils.java
//http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3
//商户Key:改成公司申请的即可
//32位密码设置地址:http://www.sexauth.com/ jdex1hvufnm1sdcb0e81t36k0d0f15nc
private static String Key = "你们的Key";
好了后新建一个Test的项目就可以直接运行了
有人问我appid是啥,我。。。。。我说什么好呢?我是说还是不说呢?
o(︶︿︶)o 唉,说了没意思,这是最最基础的,不说有别扭,想想,还是贴出来咯~~
师傅领进门,修行靠个人呐