/** * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 * @return boolean */ public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) { StringBuffer sb = new StringBuffer(); @SuppressWarnings("rawtypes") Set es = packageParams.entrySet(); @SuppressWarnings("rawtypes") Iterator it = es.iterator(); while(it.hasNext()) { @SuppressWarnings("rawtypes") Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); String v = (String)entry.getValue(); if(!"sign".equals(k) && null != v && !"".equals(v)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + API_KEY); //算出摘要 String mysign = CommonUtils.MD5Encode(sb.toString(), characterEncoding).toLowerCase(); String tenpaySign = ((String)packageParams.get("sign")).toLowerCase(); return tenpaySign.equals(mysign); }
/** * @author chenp * @Description:sign签名 * @param characterEncoding * 编码格式 * @param parameters * 请求参数 * @return */ @SuppressWarnings("rawtypes") public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) { StringBuffer sb = new StringBuffer(); Set es = packageParams.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + API_KEY); String sign = CommonUtils.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; }
/** * @author chenp * @Description:将请求参数转换为xml格式的string * @param parameters * 请求参数 * @return */ @SuppressWarnings("rawtypes") public static String getRequestXml(SortedMap<Object, Object> parameters) { StringBuffer sb = new StringBuffer(); sb.append("<xml>"); Set es = parameters.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) { sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">"); } else { sb.append("<" + k + ">" + v + "</" + k + ">"); } } sb.append("</xml>"); return sb.toString(); } /** * 取出一个指定长度大小的随机正整数. * * @param length * int 设定所取出随机数的长度。length小于11 * @return int 返回生成的随机数。 */ public static int buildRandom(int length) { int num = 1; double random = Math.random(); if (random < 0.1) { random = random + 0.1; } for (int i = 0; i < length; i++) { num = num * 10; } return (int) ((random * num)); } /** * 获取当前时间 yyyyMMddHHmmss * @author chenp * @return String */ public static String getCurrTime() { Date now = new Date(); SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String s = outFormat.format(now); return s; } /** * 获取本机IP地址 * @author chenp * @return */ @SuppressWarnings("rawtypes") public static String localIp(){ String ip = null; Enumeration allNetInterfaces; try { allNetInterfaces = NetworkInterface.getNetworkInterfaces(); while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement(); List<InterfaceAddress> InterfaceAddress = netInterface.getInterfaceAddresses(); for (InterfaceAddress add : InterfaceAddress) { InetAddress Ip = add.getAddress(); if (Ip != null && Ip instanceof Inet4Address) { ip = Ip.getHostAddress(); } } } } catch (SocketException e) { lg.warn("获取本机Ip失败:异常信息:"+e.getMessage()); } return ip; }
** * 微信H5支付 * @return * @author chenp * @throws Exception */ public static Map<String, String> getH5CodeUrl(PayParams ps,HttpServletRequest request) throws Exception { String trade_type = "MWEB"; //类型【H5支付】 String scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://localhost:8080/cggl/f/purchase/supplier/setting/account/beforeRecharge\",\"wap_name\": \"帐户充值\"}}";//场景信息 /** * 参数封装 */ SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>(); packageParams.put("spbill_create_ip", getClientIp(request));//客户端主机 packageParams.put("trade_type", trade_type); packageParams.put("scene_info", scene_info); Map<String,String> map = commPay(ps,request,packageParams); return map; } /** * JSAPI支付 * @param ps * @param request * @return * @throws Exception */ public static Map<String, String> getJSPay(PayParams ps,HttpServletRequest request) throws Exception { String trade_type = "JSAPI"; //类型【JSAPI】 SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>(); packageParams.put("spbill_create_ip", getClientIp(request));//客户端主机 packageParams.put("trade_type", trade_type); packageParams.put("openid", ps.getOpenId()); Map<String, String> map = commPay(ps, request, packageParams); return map; } /** * 支付接口 * @param ps * @param request * @param paramMap * @return * @throws JDOMException * @throws IOException */ public static Map<String,String> commPay(PayParams ps,HttpServletRequest request,SortedMap<Object,Object> paramMap) throws JDOMException, IOException{ //公共参数 String appid = Constants.APP_ID;//微信服务号的appid String mch_id = Constants.MCHID; //微信支付商户号 String key = Constants.APIKEY; // 微信支付的API密钥 String notify_url =Constants.DOMAIN+request.getContextPath()+WECHAT_NOTIFY_URL_PC;//回调地址【注意,这里必需要使用外网的地址】 String ufdoder_url=UFDODER_URL;//微信下单API地址 //随机数 String nonce_str = createRadomNum(4); /** * 参数封装 */ SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>(); packageParams.put("appid", appid); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str);//随机字符串 packageParams.put("body", ps.body);//支付的商品名称 packageParams.put("out_trade_no", ps.out_trade_no+nonce_str);//商户订单号【备注:每次发起请求都须要随机的字符串,不然失败。】 packageParams.put("total_fee", ps.total_fee);//支付金额 packageParams.put("notify_url", notify_url); packageParams.put("attach", ps.attach);//额外的参数【业务类型+会员ID+支付类型】 packageParams.putAll(paramMap);//特定参数 @SuppressWarnings("static-access") String sign = new PayUtil().createSign("UTF-8", packageParams,key); packageParams.put("sign", sign); String requestXML = PayUtil.getRequestXml(packageParams);//将请求参数转换成String类型 String resXml = HttpUtil.postData(ufdoder_url,requestXML); //解析请求以后的xml参数而且转换成String类型 @SuppressWarnings("unchecked") Map<String,String> map = XMLUtil.doXMLParse(resXml); String result_code = (String) map.get("result_code"); lg.info("下单结果-result_code--》"+(String) map.get("result_code")); Map<String,String> nMap = new HashMap<String, String>(); String prepayId = (String) map.get("prepay_id"); String mweb_url = (String) map.get("mweb_url"); nMap.put("outTradeNo", ps.out_trade_no+nonce_str); nMap.put("prepayId", prepayId); nMap.put("outTradeNoZS", ps.out_trade_no); nMap.put("mweb_url", mweb_url); nMap.put("result_code", result_code); return nMap; } /** * 随机数生成 * @return */ public static String createRadomNum(int lenth){ String currTime = PayUtil.getCurrTime(); String strTime = currTime.substring(8, currTime.length()); String strRandom = PayUtil.buildRandom(lenth) + ""; String nonce_str = strTime + strRandom; return nonce_str; }
/** * 根据code获取用户的openid * @param httpClient * @param appid * @param ky * @param code * @return */ public static String getOpenId(String appId, String appSecret, String code) { String url = MicroMsgDomain + "/sns/oauth2/access_token?" + "appid="+appId + "&secret="+appSecret + "&code="+code + "&grant_type=authorization_code"; GetMethod method = new GetMethod(url); method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"UTF-8"); String openId=null; try { new HttpClient().executeMethod(method); String str = method.getResponseBodyAsString(); JSONObject json = JSONObject.fromObject(str); openId = json.getString("openid"); } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } finally { method.releaseConnection(); } return openId; }