微信支付2.0版本,更换参数即可使用

微信支付2.0版本,更换参数即可使用

前段时间公司开发需要用到微信支付,查阅了微信官网,支付1.0的说后期不再维护了,就研究着2.0的json主流格式,现在当个经验交流,供大家借鉴,只需要替换成自己公司对应的各项参数即可使用。
废话不多说,直接上干货:

控制层和Dao层我就写出来了,大家自行写一下就ok.
首先是POM.xml文件的依赖:

UTF-8
1.2.17
4.2.3.RELEASE
1.8

junit junit 3.8.1 test log4j log4j ${log4j.version} com.alibaba fastjson 1.2.30
	
		 com.github.wechatpay-apiv3
		wechatpay-apache-httpclient
		0.2.2
   
   
   
	
		org.springframework
		spring-core
		${spring.version}
		

下面就是实现层的代码了:

package com.test.yishui.impl;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.test.yishui.util.ConfPathUtil;
import com.test.yishui.util.OpenPropertyUtil;
import com.test.yishui.util.RandomUtil;
import com.test.yishui.weixinPojo.KeyPairFactory;
import com.test.yishui.weixinPojo.WeiXinAmount;
import com.test.yishui.weixinPojo.WeiXinPojo;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;

public class PaymentServiceImpl {

/**
 * 商户号:we_chat_merchant_id 
 * API密钥 :we_chat_key
 * APIv3密钥:we_chat_apiv3key
 * 微信下订单地址:we_chat_order_url
 * we_chat_appid
 * 商户私钥:apiclient_key.pem
 * 私钥也可以通过工具从商户的p12证书中导出。请妥善保管好你的商户私钥文件。
 * 回调地址:wx_notify_url
 * 商户序列号:we_chat_serialNo
 * 商户appid:we_chat_appid
 * 微信查询订单地址:we_chat_query_url
 */

private static Logger logger = Logger.getLogger(PaymentServiceImpl.class);
private static Integer []  memberLevelList = {301, 302, 303, 304};

// private final String keyPath = “src\main\resources\apiclient_cert.p12”;
// private static String privateKeyPath = “src\main\resources\apiclient_key.pem”;
private static String keyPath = ConfPathUtil.getConfPath()+“apiclient_cert.p12”;
private static String privateKeyPath = ConfPathUtil.getConfPath()+“apiclient_key.pem”;
private final String keyAlias = “Tenpay Certificate”;

public JSONObject placeOrder(JSONObject requestParamMap) {
	logger.info("paymentService placeOrder method start..."+requestParamMap.toString());
	
	JSONObject result = new JSONObject();
	
	
	result = placeOrderByWechat(requestParamMap);
	
	result.put("errMsg", null);
	result.put("goodsNumber", 0);
	return result ;
}


/**
 * 微信下订单接口
 * @param requestParamMap
 * @return
 */

private JSONObject placeOrderByWechat(JSONObject requestParamMap) {
	JSONObject result = new JSONObject();
	result.put("success", Boolean.FALSE);
	
	try {
		// 获取产品价格
		int productId = requestParamMap.getInteger("productId");
        
		WeiXinAmount weiXinAmount = getWeiXinAmount("产品价格");
		// 获取微信的请求参数
		WeiXinPojo weiXinPojo = getWeiXinPojo(weiXinAmount, requestParamMap);
		// 向微信发起支付
		String prepayId = weChatPayPay(weiXinAmount, weiXinPojo);
        
		// 获取签名
		KeyPair keyPair = KeyPairFactory.createPKCS12(keyPath, keyAlias, OpenPropertyUtil.getConfig("we_chat_merchant_id", ""));
		String canonicalUrl = OpenPropertyUtil.getConfig("we_chat_order_url", "");
		long timestamp = System.currentTimeMillis();
		String nonceStr = RandomUtil.getRamdomDigits(28);
		JSONObject body = (JSONObject) JSONObject.toJSON(weiXinPojo);
		String sign = KeyPairFactory.getSign("POST", canonicalUrl, timestamp, nonceStr, body.toString(), keyPair) ;
		
		
        if(null != prepayId && !StringUtils.isEmpty(prepayId)) {
        	result.put("success", Boolean.TRUE);
        	result.put("outTradeNo", weiXinPojo.getOut_trade_no());
        }
        result.put("appId", OpenPropertyUtil.getConfig("we_chat_appid", ""));
    	result.put("partnerId", OpenPropertyUtil.getConfig("we_chat_merchant_id", ""));
    	result.put("prepayId", prepayId);
    	result.put("packageValue", "Sign=WXPay");
    	result.put("nonceStr", nonceStr);
    	result.put("timeStamp", timestamp);
    	result.put("sign", sign);
    	
    	// 生成订单 t_order 表
    	requestParamMap.put("payNo", prepayId);
        
    } catch (Exception e) {
    	logger.error("placeOrderByWechat method error..."+e.getMessage());
    }
	// 返回给前台支付信息
	return result;
}

	
private List changeToList(Integer [] memberLevelList){
	List memberLevels = new ArrayList();
	
	for(Integer memberLevel:memberLevelList) {
		memberLevels.add(memberLevel);
	}
	return memberLevels ;
}

public String weChatPayPay( WeiXinAmount amount, WeiXinPojo pojo) {
	JSONObject params = (JSONObject) JSONObject.toJSON(pojo);
    logger.info("request param {}"+ params.toJSONString());
	
    String prepayId = null ;
	CloseableHttpClient httpClient = null;

    try {
        // 初始化httpClient
        httpClient = getHttpClient();

        HttpPost httpPost = new HttpPost(OpenPropertyUtil.getConfig("we_chat_order_url",""));

        httpPost.setHeader("Accept","application/json");
        httpPost.setHeader("Content-Type","application/json; charset=utf-8");
        httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        
        // 中文乱码时需要转码
        httpPost.setEntity(new StringEntity(params.toJSONString(), "utf-8"));

        CloseableHttpResponse response = httpClient.execute(httpPost);
        if (response != null) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
            	String responseInfo = EntityUtils.toString(entity, StandardCharsets.UTF_8);
            	JSONObject parseObject = JSONObject.parseObject(responseInfo);
            	
            	prepayId = parseObject.getString("prepay_id");
            }
        }
    } catch (IOException e) {
    	logger.error("weChatPayPay method error..."+e.getMessage());
    } finally {
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException e) {
            	logger.error("weChatPayPay method error..."+e.getMessage());
            }
        }
    }
    return prepayId;
}

/**
 * 获取私钥。
 *
 * @param filename 私钥文件路径  (required)
 * @return 私钥对象
 */
public PrivateKey getPrivateKey(String filename) throws IOException {

    String content = new String(Files.readAllBytes(Paths.get(filename)), StandardCharsets.UTF_8);
    try {
        String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");

        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(
                new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("当前Java环境不支持RSA", e);
    } catch (InvalidKeySpecException e) {
        throw new RuntimeException("无效的密钥格式");
    }
}

private WeiXinAmount getWeiXinAmount(String productPrice) {
	WeiXinAmount amount = new WeiXinAmount();
    amount.setCurrency("CNY");
    
    Number num = Float.parseFloat(productPrice)*100;
    int oamount = num.intValue();
    Long total = Long.valueOf(oamount);
    amount.setTotal(total);
    
    return amount ;
}

private WeiXinPojo getWeiXinPojo(WeiXinAmount amount, JSONObject requestParamMap) {
	WeiXinPojo pojo = new WeiXinPojo();
	    
 	pojo.setMchid(OpenPropertyUtil.getConfig("we_chat_merchant_id", ""));
    pojo.setOut_trade_no(RandomUtil.getRamdomDigits(18));
    pojo.setAppid(OpenPropertyUtil.getConfig("we_chat_appid", ""));
    pojo.setNotify_url(OpenPropertyUtil.getConfig("wx_notify_url", ""));
    pojo.setAmount(amount);
    
    String proudctName = "深圳市新财富多媒体经营有限公司";
   
    pojo.setDescription(proudctName);
	return pojo ;    
}


public JSONObject weChatNotify(JSONObject resourceObj, JSONObject weChatInfo)  {
	logger.info("weChatNotify service start:");
	JSONObject result = new JSONObject();
	result.put("code",  "FAIL");
	result.put("message",  "失败");
	
	String tradeState = resourceObj.getString("trade_state");
	
	
	String mchId = OpenPropertyUtil.getConfig("we_chat_merchant_id", "");
	String appId = OpenPropertyUtil.getConfig("we_chat_appid", "");
	
	String mchid = resourceObj.getString("mchid");
	String appid = resourceObj.getString("appid");
	
	String outTradeNo = resourceObj.getString("out_trade_no");
	
	logger.info("weChatNotify service end:"+result);
	return result ;
}




// 初始化httpClient
private CloseableHttpClient getHttpClient() {
	CloseableHttpClient httpClient = null ;
	
	try {
		String mchId = OpenPropertyUtil.getConfig("we_chat_merchant_id", "");
		String mchSerialNo = OpenPropertyUtil.getConfig("we_chat_serialNo", "");
		String apiV3Key = OpenPropertyUtil.getConfig("we_chat_apiv3key", "");

		PrivateKey privateKey = getPrivateKey(privateKeyPath);

	    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
	                    new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, privateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
			 // 初始化httpClient
            httpClient = WechatPayHttpClientBuilder.create()
                    .withMerchant(mchId, mchSerialNo, privateKey)
                    .withValidator(new WechatPay2Validator(verifier)).build();
	} catch (Exception e) {
		logger.error("getHttpClient method error..."+e.getMessage());
	}
	
	return httpClient;
}

/**
 * 
 * @param outTradeNo 商户订单号
 * @param tradeState 微信返回的支付状态值
 * @param mchid		 商户id
 * @param appid		应用id
 * @param total		支付金额
 * @return 处理订单结果
 */
private JSONObject handleWeChatPayBusiness(String outTradeNo, String tradeState, String mchid,
		String appid, String total, JSONObject weChatInfo) {
	JSONObject result = new JSONObject();
	result.put("code",  "FAIL");
	result.put("message",  "失败");
	
	String mchId = OpenPropertyUtil.getConfig("we_chat_merchant_id", "");
	String appId = OpenPropertyUtil.getConfig("we_chat_appid", "");

return result ;
}





/**
 * 对微信返回的信息进行解码
 */
public JSONObject parseWechatNotifyStr(String wechatNotifyStr) {
	JSONObject resourceObj = new JSONObject();
	try {
		JSONObject resultInfo = JSONObject.parseObject(wechatNotifyStr);
		 JSONObject resourceInfo = resultInfo.getJSONObject("resource");
		 logger.info("parseWechatNotifyStr resource:"+wechatNotifyStr);
		 
		String associated_data = resourceInfo.getString("associated_data");
		byte[] associatedData = associated_data.getBytes();
		String nonce = resourceInfo.getString("nonce");
		byte[] nonCe = nonce.getBytes();
		String ciphertext = resourceInfo.getString("ciphertext");;
		String key = OpenPropertyUtil.getConfig("we_chat_apiv3key", "");
		byte[] bytes = key.getBytes();
		AesUtil aesUtil = new AesUtil(bytes);
		
		String decryptToString = aesUtil.decryptToString(associatedData, nonCe, ciphertext);
		resourceObj = JSONObject.parseObject(decryptToString);
	} catch (GeneralSecurityException e) {
		logger.error("parseWechatNotifyStr method error..." + e.getMessage());
	} catch (IOException e) {
		logger.error("parseWechatNotifyStr method error..." + e.getMessage());
	}
	logger.info("parseWechatNotifyStr decryptToString:"+resourceObj);
	return  resourceObj;
}

}

然后就是各种pojo:
package com.test.yishui.weixinPojo;

import java.io.Serializable;

public class WeiXinAmount implements Serializable {

private static final long serialVersionUID = 2143445999944574977L;
//支付金额
private Long total;
//货币种类
private String currency;

public Long getTotal() {
    return total;
}

public void setTotal(Long total) {
    this.total = total;
}

public String getCurrency() {
    return currency;
}

public void setCurrency(String currency) {
    this.currency = currency;
}

@Override
public String toString() {
    return "WeiXinAmount{" +
            "total=" + total +
            ", currency='" + currency + '\'' +
            '}';
}

}

package com.test.yishui.weixinPojo;

import java.io.Serializable;

public class WeiXinPojo implements Serializable {

private static final long serialVersionUID = -6686089474565653020L;
//mchid
private String mchid;
//直连商户号
private String out_trade_no;
//应用ID
private String appid;
//商品描述
private String description;
//通知地址
private String notify_url;
//订单金额
private WeiXinAmount amount;

public String getMchid() {
    return mchid;
}

public void setMchid(String mchid) {
    this.mchid = mchid;
}

public String getOut_trade_no() {
    return out_trade_no;
}

public void setOut_trade_no(String out_trade_no) {
    this.out_trade_no = out_trade_no;
}

public String getAppid() {
    return appid;
}

public void setAppid(String appid) {
    this.appid = appid;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getNotify_url() {
    return notify_url;
}

public void setNotify_url(String notify_url) {
    this.notify_url = notify_url;
}

public WeiXinAmount getAmount() {
    return amount;
}

public void setAmount(WeiXinAmount amount) {
    this.amount = amount;
}

@Override
public String toString() {
	return "WeiXinPojo [mchid=" + mchid + ", out_trade_no=" + out_trade_no + ", appid=" + appid + ", description="
			+ description + ", notify_url=" + notify_url + ", amount=" + amount 
			+ "]";
}

}

微信客户端类:
package com.test.yishui.weixinPojo;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import org.apache.http.client.HttpClient;

public class WeixinClient {

public static HttpClient createClient(String merchantId, String serialNo){
    // PrivateKey privateKey List certificates
    WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
            .withMerchant(merchantId, serialNo, null)
            .withWechatpay(null);

    HttpClient httpClient = builder.build();

    return httpClient;
}

}

获取私钥的工具类:
package com.test.yishui.weixinPojo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.log4j.Logger;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Base64Utils;

import com.alibaba.fastjson.JSONObject;
import com.test.yishui.util.OpenPropertyUtil;

/**

  • KeyPairFactory

  • @author dax

  • @since 13:41
    **/
    public class KeyPairFactory {

    private static Logger logger = Logger.getLogger(KeyPairFactory.class);

    private static KeyStore store;

    private final static Object lock = new Object();

    /**

    • 获取公私钥.

    • @param keyPath API证书apiclient_cert.p12的classpath路径

    • @param keyAlias 证书的别名 固定值 Tenpay Certificate

    • @param keyPass password 证书密码 这个默认就是商户号

    • @return the key pair
      */
      public static KeyPair createPKCS12(String keyPath, String keyAlias, String keyPass) {
      ClassPathResource resource = new ClassPathResource(keyPath);

      FileInputStream fis = null;
      URL url;

      char[] pem = keyPass.toCharArray();
      try {

       url = OpenPropertyUtil.class.getClassLoader().getResource("apiclient_cert.p12");
       fis = new FileInputStream(url.getPath());
       
       FileInputStream file = new FileInputStream(keyPath);
       synchronized (lock) {
           if (store == null) {
               synchronized (lock) {
                   store = KeyStore.getInstance("PKCS12");
                   store.load(file, pem);
               }
           }
       }
       X509Certificate certificate = (X509Certificate) store.getCertificate(keyAlias);
       certificate.checkValidity();
       // 证书的序列号 也有用
       String serialNumber = certificate.getSerialNumber().toString(16).toUpperCase();
       // 证书的 公钥
       PublicKey publicKey = certificate.getPublicKey();
       // 证书的私钥
       PrivateKey storeKey = (PrivateKey) store.getKey(keyAlias, pem);
      
       return new KeyPair(publicKey, storeKey);
      

      }catch (FileNotFoundException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
      } catch (Exception e) {
      throw new IllegalStateException("Cannot load keys from store: " + resource, e);
      }
      return null;
      }

    /**

    • V3 SHA256withRSA 签名.
    • @param method 请求方法 GET POST PUT DELETE 等
    • @param canonicalUrl 例如 https://api.mch.weixin.qq.com/v3/pay/transactions/app?version=1 ——> /v3/pay/transactions/app?version=1
    • @param timestamp 当前时间戳 因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
    • @param nonceStr 随机字符串 要和TOKEN中的保持一致
    • @param body 请求体 GET 为 “” POST 为JSON
    • @param keyPair 商户API 证书解析的密钥对 实际使用的是其中的私钥
    • @return the string
      */
      public static String getSign(String method, String canonicalUrl, long timestamp, String nonceStr, String body, KeyPair keyPair) throws SignatureException {
      String signatureStr = Stream.of(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body)
      .collect(Collectors.joining("\n", “”, “\n”));
      Signature sign = null;
      try {
      sign = Signature.getInstance(“SHA256withRSA”);
      sign.initSign(keyPair.getPrivate());
      sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
      } catch (NoSuchAlgorithmException e) {
      logger.error(“getSign method error…”+e.getMessage());
      }catch (InvalidKeyException e) {
      logger.error(“getSign method error…”+e.getMessage());
      }catch (SignatureException e) {
      logger.error(“getSign method error…”+e.getMessage());
      }
      return Base64Utils.encodeToString(sign.sign());
      }
      }

获取URL的工具类:
package com.test.yishui.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class UrlUtil {

/**
 * 将请求map中的转换成安装key排序的url
 * 
 * @author haojian [email protected] Feb 1, 2013 6:18:38 PM
 * @param parameterMap
 * @return
 */
public static String getSortedUrl(Map parameterMap) {
    // 排序
    Map map = new TreeMap(parameterMap);

    Set keySet = map.keySet();
    StringBuilder sb = new StringBuilder();
    for (String key : keySet) {
        sb.append(key).append("=").append(map.get(key)).append("&");
    }
    String str = sb.substring(0, sb.length() - 1);
    return str;
}

/**
 * 将url后面的参数放到 TreeMap 中
 * 
 * @author haojian [email protected] Feb 1, 2013 6:50:42 PM
 * @param params
 * @return
 */
public static Map getMapbyUrlParams(String params) {

    Map map = new TreeMap();
    String[] ss = params.split("&");
    for (String s : ss) {
        int index = s.indexOf("=");
        if (index > 0) {
            String key = s.substring(0, index);
            String value = s.substring(index + 1);
            map.put(key, value);

        }
    }

    return map;
}

/**
 * 对字符串进行url编码
 * 
 * @author haojian [email protected] Dec 25, 2013 5:26:08 PM
 * @param str
 * @return
 */
public static String urlEncode(String str) {
    String result = null;
    try {
        result = URLEncoder.encode(str, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return result;
}

/**
 * 对字符串进行url解码
 * 
 * @author haojian [email protected] Dec 25, 2013 5:26:08 PM
 * @param str
 * @return
 */
public static String urlDecode(String str) {
    String result = null;
    try {
        result = URLDecoder.decode(str, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return result;
}

/**
 * 根据 requestURL 获取域名
 * 如:从 http://nodo.bluemobi.com:8080/index  中截取的域名为:nodo.bluemobi.com
 * @author haojian
 * @date 2016-3-11 下午3:45:29 
 * @param requestURL
 * @return
 * @return String
 */
public static String getDemainByRequestURL(String requestURL) {
    //String requestURL = "http://localhost:8080/index";
    int begin = requestURL.indexOf("://") + 3;
    String requestURL2 = requestURL.substring(begin);
    int end = 0;
    if(requestURL2.contains(":")){
        end = requestURL2.indexOf(":");
    }else{
        end = requestURL2.indexOf("/");
    }
    
    String domain = requestURL2.substring(0, end);
    
    return domain;
    
}


public static void main(String[] args){
    //System.out.println( UrlUtil.getDemainByRequestURL("http://web_server_pool/test/") );
    
	String s = "ss_time%22%3A%2220161128163007%22%2C%22type%22%3A%22REFUND%22%7D%2C%22type%22%3A%22NOTIFY%22%7D%7B%22cre_time%22%3A%2220161128163007%22%2C%22event%22%3A%22REFUND_SUCCESS%22%2C%22id%22%3A%22NFC9uQQJzjQfUDPyyxdWXzTb%22%2C%22object%22%3A%7B%22app_id%22%3A%22APLcfrMn7oYae8TMKVqtgD12%22%2C%22attach%22%3A%22158%22%2C%22channel_code%22%3Anull%2C%22channel_msg%22%3Anull%2C%22channel_sno%22%3A%222016112801541859%22%2C%22create_time%22%3A%2220161128154209%22%2C%22extra%22%3Anull%2C%22id%22%3A%22RFLB1nPdCoqrYC4ifmmxjWPB%22%2C%22order_id%22%3A%22ODYX5Ho9KnEcre4xSv1Hbg3X%22%2C%22refund_amount%22%3A1%2C%22refund_no%22%3A%22RFLB1nPdCoqrYC4ifmmxjWPB%22%2C%22refund_status%22%3A%22SUCCESS%22%2C%22succe";
    System.out.println(UrlUtil.urlDecode(s));
}

}
获取随机数的工具类:
package com.test.yishui.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**

  • 处理随机概率的公共类

  • 应用中所有的随机数获取,概率验证都可调用该类方法实现

  • @author haojian [email protected]

  • Apr 1, 2013 9:53:52 AM
    */
    public class RandomUtil {

    // 小数精度,保留六位小数
    private static final double PRECISION = 1000000;

    /** 返回一个 大于等于0,小于n 的整数 */
    public static int getRandomInt(int n) {
    if (n == 0) {
    return 0;
    }
    Random random = new Random();
    return random.nextInt(n);
    }

    /** 返回一个 大于等于0,小于n 的整数 */
    public static int getRandomInt(int n , long seed) {
    if (n == 0) {
    return 0;
    }
    Random randomWithSeed = new Random();
    randomWithSeed.setSeed(seed);
    return randomWithSeed.nextInt(n);
    }

    /** 返回一个int数,该数 >=min <=max */
    public static int getRandomInt(int min, int max) {
    if (min == max) {
    return min;
    }
    if (min > max) {
    int temp = min;
    min = max;
    max = temp;
    }
    Random random = new Random();
    return random.nextInt(max - min + 1) + min;
    }

    /** 返回一个int数,该数 >=min <=max */
    public static int getRandomInt(int min, int max , long seed) {
    if (min == max) {
    return min;
    }
    if (min > max) {
    int temp = min;
    min = max;
    max = temp;
    }
    Random randomWithSeed = new Random();
    randomWithSeed.setSeed(seed);
    return randomWithSeed.nextInt(max - min + 1) + min;
    }

    /**

    • 注意:参数必须小于2147,结果保留6位小数 返回一个双double数,该数 >=min <=max
      */
      public static double getRandomDouble(double min, double max) {
      if (min > max) {
      double temp = min;
      min = max;
      max = temp;
      }
      if (max * PRECISION > Integer.MAX_VALUE) {
      throw new RuntimeException(“the number mast be less than 2147.”);
      }
      int intMin = (int) (min * PRECISION);
      int intMax = (int) (max * PRECISION);
      double result = getRandomInt(intMin, intMax) / PRECISION;
      return result;
      }

    /**

    • 注意:参数必须小于2147,结果保留6位小数 返回一个双double数,该数 >=min <=max
      */
      public static double getRandomDouble(double min, double max , long seed) {
      if (min > max) {
      double temp = min;
      min = max;
      max = temp;
      }
      if (max * PRECISION > Integer.MAX_VALUE) {
      throw new RuntimeException(“the number mast be less than 2147.”);
      }
      int intMin = (int) (min * PRECISION);
      int intMax = (int) (max * PRECISION);
      double result = getRandomInt(intMin, intMax, seed) / PRECISION;
      return result;
      }

    /**

    • 结果保留n位小数 返回一个双double数,该数 >=min <=max
      */
      public static double getRandomDouble(double min, double max, int n) {
      if (min > max) {
      throw new RuntimeException(
      “min number must be less than or equal than max number”);
      }

      double precision;
      if (n == 1)
      precision = 10;
      else if (n == 2)
      precision = 100;
      else if (n == 3)
      precision = 1000;
      else if (n == 4)
      precision = 1000;
      else if (n == 5)
      precision = 10000;
      else if (n == 6)
      precision = 100000;
      else if (n == 7)
      precision = 1000000;
      else if (n == 8)
      precision = 10000000;
      else if (n == 9)
      precision = 100000000;
      else if (n == 10)
      precision = 1000000000;
      else
      precision = 1;

      if (max * precision > Integer.MAX_VALUE) {
      throw new RuntimeException(“the number max and n is too large”);
      }
      int intMin = (int) (min * precision);
      int intMax = (int) (max * precision);
      double result = getRandomInt(intMin, intMax) / precision;
      return result;
      }

    /**

    • 验证该概率的事件是否发生 rate 发生的概率
      */
      public static boolean checkIsTrue(double rate) {
      if (rate >= 1) {
      return true;
      } else if (rate <= 0) {
      return false;
      }
      // 分母
      int denominator = (int) 1000000;
      // 分子
      int probability = (int) (rate * denominator);
      Random random = new Random();
      int n = random.nextInt(denominator) + 1;
      if (n <= probability) {
      return true;
      } else {
      return false;
      }
      }

    /**

    • 验证该概率的事件是否发生 rate 发生的概率
      */
      public static boolean checkIsTrue(double rate, long seed) {
      if (rate >= 1) {
      return true;
      } else if (rate <= 0) {
      return false;
      }
      Random randomWithSeed = new Random();
      randomWithSeed.setSeed(seed);
      // 分母
      int denominator = (int) PRECISION;
      // 分子
      int probability = (int) (rate * denominator);
      int n = randomWithSeed.nextInt(denominator) + 1;
      if (n <= probability) {
      return true;
      } else {
      return false;
      }
      }

    /**

    • @param num 数量
    • @param min 最小值
    • @param max 最大值
    • @return
      */
      public static List getUnlikeRandomInt(int num, int min, int max) {
      if (num > max - min + 1) {
      throw new RuntimeException(“the number num is too large”);
      }
      List list = new ArrayList();
      for (int i = 0; i < num; i++) {
      int randomPoint = RandomUtil.getRandomInt(min, max);
      if (!list.contains(randomPoint)) {
      list.add(randomPoint);
      } else {
      i–;
      }
      }
      return list;
      }

    /**

    • 概率验证
    • @author haojian [email protected] Nov 8, 2012 3:59:03 PM
    • @param list
    • @return
      */
      public static int getRandomResult(List weightList) {
      int index = 0;
      int all = 0;
      for (int i = 0; i < weightList.size(); i++) {
      int rate = weightList.get(i);
      all = all + rate;
      }
      int randomNum = RandomUtil.getRandomInt(1, all);
      int tempNum = 0;
      for (int i = 0; i < weightList.size(); i++) {
      int rate = weightList.get(i);
      tempNum = tempNum + rate;
      if (tempNum >= randomNum) {
      index = i;
      break;
      }
      }
      return index;
      }

    /**

    • 概率验证
    • @author haojian [email protected] Nov 8, 2012 3:59:03 PM
    • @param list
    • @return
      */
      public static int getRandomResult(List weightList, long seed) {
      int index = 0;
      int all = 0;
      for (int i = 0; i < weightList.size(); i++) {
      int rate = weightList.get(i);
      all = all + rate;
      }
      int randomNum = RandomUtil.getRandomInt(1, all, seed);
      int tempNum = 0;
      for (int i = 0; i < weightList.size(); i++) {
      int rate = weightList.get(i);
      tempNum = tempNum + rate;
      if (tempNum >= randomNum) {
      index = i;
      break;
      }
      }
      return index;
      }

    // 获取一定长度的随机数数字
    public static String getRamdomDigits(int n) {
    if (n == 0) {
    return “0”;
    }
    StringBuffer sb = new StringBuffer();
    Random random = new Random();
    for(int i=0 ;i int nextInt = random.nextInt(10);
    sb.append(nextInt);
    }
    return sb.toString();
    }

    /**

    • @param args
      */
      public static void main(String[] args) {

      for(int i=0;i<100;i++){

      int n = RandomUtil.getRandomInt(1, 10);

      boolean isTrue = false;

      for(int j=0;j

      System.out.println(isTrue); }

      for(int i=0;i<100;i++){

       System.out.println( (int)((Math.random()*Long.MAX_VALUE)%100L) );
      

      }

    }
    }
    获取Spring配置文件的工具类:
    package com.test.yishui.util;

import java.net.URL;

public class ConfPathUtil {

/**
 * spring 配置文件路径
 */
private static String confPath;
	
/**获取配置文件路径*/
public static String getConfPath() {
	return confPath;
}


static{
	
	URL url = ConfPathUtil.class.getResource("/");
	
	if(url!=null){
	    
		confPath = url.getPath();

		confPath = UrlUtil.urlDecode(confPath);
		
	}else{
		confPath = System.getProperty("file.separator") + System.getProperty("user.dir") + System.getProperty("file.separator") + "conf" + System.getProperty("file.separator");
	}
}

}

读取配置文件的工具类:
package com.test.yishui.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

public class OpenPropertyUtil {

private static Logger log = Logger.getLogger(OpenPropertyUtil.class);

/**
 * 根据key值获取对应配置文件的value值,若value值为null或者空,则取传入的默认值
 * 
 * @param key 配置表的key值
 * @param defaultValue 传入的默认值
 * @return 配置表的value值
 */
public static String getConfig(String key, String defaultValue) {
    Properties p;
    p = new Properties();
    FileInputStream fis = null;
    URL url;
    url = OpenPropertyUtil.class.getClassLoader().getResource("request.properties");
    try {
        fis = new FileInputStream(url.getPath());
        p.load(fis);
    } catch (FileNotFoundException e) {
        log.error("getConfig method error...{}"+e.getMessage());
    } catch (IOException e) {
    	log.error("getConfig method error...{}"+e.getMessage());
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    String value = p.getProperty(key);
    
    if(StringUtils.isEmpty(value)){
		return defaultValue ;
	}
	
	return value ;
}

}

好了,传入产品价格和写好签名后,就可以将参数传给前端,前端就可以发起支付了。
然后微信会根据配置好的回调函数,进行调用回调接口(https),验证号订单号,查询订单信息,再处理自己公司相应的逻辑处理就好

你可能感兴趣的:(工具类,微信,java)