/**
* 是否签名正确,规则是:按参数名称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;
}