public String getOpenId(){ String code = getPara( "code" ); String openid = "" ; if (StringUtils.isEmpty(openid) && !StringUtils.isEmpty(code)) { SnsAccessToken token = SnsAccessTokenApi.getSnsAccessToken( "你的APPID" , "你的appsecret密码" , code); openid = token.getOpenid(); } getSession().setAttribute( "openandid" ,openid); return openid; } public void index() throws Exception{ String openid = getOpenId(); //得到金额 String money= getPara( "money" ); Map<String ,String > map= new HashMap<String,String>(); //获取随机串 String nonceStr=UUID.randomUUID().toString().substring( 0 , 32 ); //可以是支付物品的订单号。一个号码,看自己怎么给 String out_trade_no= "123456789" ; //支付金额。微信默认支付是(1=0.01)的比例,下面是将金额换算成微信可识别的 BigDecimal re1= new BigDecimal(expressCharge); BigDecimal re2= new BigDecimal(Float.toString( 100 .00f)); Float aa = re1.multiply(re2).floatValue(); String total_fee = String.valueOf(aa); String[] smill = total_fee.split( "\\." ); total_fee = smill[ 0 ]; //微信的appid String appid= "XXXXXXXXXXXXXXXXX" ; String mch_id= "XXXXXXXXX" ; //商户号 String body= "xxxxxxx" ; //商品信息,可以自己起最好写英文 //密匙,商户平台的支付API密匙,注意是商户平台,不是微信平台 String key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" ; long timestamp = System.currentTimeMillis() / 1000 ; map.put( "appid" , appid ); map.put( "mch_id" , mch_id); map.put( "nonce_str" ,nonceStr); map.put( "body" , body); map.put( "out_trade_no" , out_trade_no); map.put( "total_fee" , total_fee); map.put( "spbill_create_ip" ,getRequest().getRemoteAddr()); //这里是支付成功后返回的地址,微信会以XML形式放回数据,就是本篇文章的下一类(例:wxxml())方法名。 map.put( "notify_url" , "http://www.XXXX.com/XXXX/XXXX/xxxx/wxxml" ); map.put( "trade_type" , "JSAPI" ); map.put( "openid" , openid); //传入OpenId //这里传入Map集合和key商户支付密匙 String paySign=getPayCustomSign(map,key); map.put( "sign" ,paySign); //将map转为XML格式 String xml= ArrayToXml(map); //统一下单,这里不用改 String url = "https://api.mch.weixin.qq.com/pay/unifiedorder" ; String xmlStr = HttpKit.post(url, xml); //prepayid由微信返回的 。 String prepayid = "" ; if (xmlStr.indexOf( "SUCCESS" ) != - 1 ) { Map<String, String> map2 = doXMLParse(xmlStr); prepayid = (String) map2.get( "prepay_id" ); } String paySign2=getPayCustomSign(signMap,key); setAttr( "model" , model); setAttr( "appId" , appid); setAttr( "paytimestamp" , String.valueOf(timestamp)); setAttr( "paynonceStr" , nonceStr); setAttr( "paypackage" , "prepay_id=" +prepayid); setAttr( "paysignType" , "MD5" ); setAttr( "paySign" , paySign2); //去到确认支付页面,返回页面方式不同,(例:pay.html页面),下面 render( "/XXXX/pay.html" ); } /** * 获取支付所需签名 * @param ticket * @param timeStamp * @param card_id * @param code * @return * @throws Exception */ public static String getPayCustomSign(Map<String, String> bizObj,String key) throws Exception { String bizString = FormatBizQueryParaMap(bizObj, false ); return sign(bizString, key); } /** * 字典排序 * @param paraMap * @param urlencode * @return * @throws Exception */ public static String FormatBizQueryParaMap(Map<String, String> paraMap, boolean urlencode) throws Exception { String buff = "" ; try { List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(paraMap.entrySet()); Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { return (o1.getKey()).toString().compareTo( o2.getKey()); } }); for ( int i = 0 ; i < infoIds.size(); i++) { Map.Entry<String, String> item = infoIds.get(i); //System.out.println(item.getKey()); if (item.getKey() != "" ) { String key = item.getKey(); String val = item.getValue(); if (urlencode) { val = URLEncoder.encode(val, "utf-8" ); } buff += key + "=" + val + "&" ; } } if (buff.isEmpty() == false ) { buff = buff.substring( 0 , buff.length() - 1 ); } } catch (Exception e) { throw new Exception(e.getMessage()); } return buff; } //支付所需签名处调用此方法 public static String sign(String content, String key) throws Exception{ String signStr = "" ; signStr = content + "&key=" + key; return MD5(signStr).toUpperCase(); } //上一方法,MD5加密处理 public final static String MD5(String s) { char hexDigits[]={ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' }; try { byte [] btInput = s.getBytes(); MessageDigest mdInst = MessageDigest.getInstance( "MD5" ); mdInst.update(btInput); byte [] md = mdInst.digest(); int j = md.length; char str[] = new char [j * 2 ]; int k = 0 ; for ( int i = 0 ; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf ]; str[k++] = hexDigits[byte0 & 0xf ]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null ; } } //转为XML格式 public static String ArrayToXml(Map<String, String> arr) { String xml = "<xml>" ; Iterator<Entry<String, String>> iter = arr.entrySet().iterator(); while (iter.hasNext()) { Entry<String, String> entry = iter.next(); String key = entry.getKey(); String val = entry.getValue(); if (IsNumeric(val)) { xml += "<" + key + ">" + val + "</" + key + ">" ; } else xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">" ; } xml += "</xml>" ; return xml; } public static boolean IsNumeric(String str) { if (str.matches( "\\d *" )) { return true ; } else { return false ; } } //解析XML private Map<String, String> doXMLParse(String xml) throws XmlPullParserException, IOException { InputStream inputStream = new ByteArrayInputStream(xml.getBytes()); Map<String, String> map = null ; XmlPullParser pullParser = XmlPullParserFactory.newInstance() .newPullParser(); pullParser.setInput(inputStream, "UTF-8" ); // 为xml设置要解析的xml数据 int eventType = pullParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: map = new HashMap<String, String>(); break ; case XmlPullParser.START_TAG: String key = pullParser.getName(); if (key.equals( "xml" )) break ; String value = pullParser.nextText(); map.put(key, value); break ; case XmlPullParser.END_TAG: break ; } eventType = pullParser.next(); } return map; } |