Java 微信支付之APP支付服务端 (一)

Java 微信支付之APP支付服务端 (一)

如图所示,这是服务端要集成的所有微信接口。至于在开放平台申请就不做赘述了。主要流程,1.下单,2.异步通知,3.查询。

Java 微信支付之APP支付服务端 (一)_第1张图片



一、微信统一下单请求交易
/**
       * 微信统一下单请求交易
       *
       * @param userId
       * @param amount
       * @return
       */
      @RequestMapping(value=Route.Payment.WEIXIN_PAY,method=RequestMethod.POST)
      @ResponseBody
      public Response pay(@PathVariable("userId") int userId,@PathVariable("amount") String amount) {
            log.info("InfoMsg:--- 微信统一下单请求交易开始");
            Response resp = this.getReponse();
            String message = "";
            try {
                  ThirdPayBean bean = thirdPayService.findByPayId(19);
                  String mch_id = bean.getMer_no();   //商户号
                  String notify_url = bean.getReturn_url(); //通知地址
                  PlatformMutualityManagent pmm = platformMutualityManagentService.findOne(5);
                  String appid = pmm.getClient_id();        //应用ID
                  String App_Secret = pmm.getClient_secret();
                  String nonce_str = WXPayUtil.generateNonceStr();            //随机字符串
                  String sign = "";                   //签名
                  String sign_type = "MD5";                       //签名类型
                  String body = "循心";                     //商品描述 ps:腾讯充值中心-QQ会员充值
                  String out_trade_no = OrderGeneratedUtils.getOrderNo();         //商户订单号
                  int total_fee = WXRandomNumberUtil.wx_format_PayAmount(amount); //交易金额
                  String spbill_create_ip = InetAddress.getLocalHost().getHostAddress(); //终端IP
                  String trade_type = "APP";          //交易类型
                  String attach = userId + "|" + bean.getBank_id();      //附加数据 ps:用户|支付方式
                  
                  StringBuffer sb = new StringBuffer();
                  sb.append("appid=").append(appid).append("&");
                  sb.append("attach=").append(attach).append("&");
                  sb.append("body=").append(body).append("&");
                  sb.append("mch_id=").append(mch_id).append("&");
                  sb.append("notify_url=").append(notify_url).append("&");
                  sb.append("nonce_str=").append(nonce_str).append("&");
                  sb.append("out_trade_no=").append(out_trade_no).append("&");
                  sb.append("sign_type=").append(sign_type).append("&");
                  sb.append("spbill_create_ip=").append(spbill_create_ip).append("&");
                  sb.append("total_fee=").append(total_fee).append("&");
                  sb.append("trade_type=").append(trade_type).append("&");
                  String params = sb.toString();
                  //需要签名的数据
                  String stringSignTemp = params + "&key=" + App_Secret;
                  //MD5签名方式
                  sign = WXPayUtil.MD5(stringSignTemp).toUpperCase();
                  Map map = new HashMap<>();
                  map.put("appid", appid);
                  map.put("attach", attach);
                  map.put("body", body);
                  map.put("mch_id", mch_id);
                  map.put("notify_url", notify_url);
                  map.put("nonce_str", nonce_str);
                  map.put("out_trade_no", out_trade_no);
                  map.put("sign", sign);
                  map.put("sign_type", sign_type);
                  map.put("spbill_create_ip", spbill_create_ip);
                  map.put("total_fee", total_fee);
                  map.put("trade_type", trade_type);
                  
                  List theaderList = new ArrayList<>();
                  theaderList.add(new UHeader("Content-Type", "application/x-www-form-urlencoded"));
                  //Httpclient发送请求
                  String postResponse = MaryunHttpUtils.getPostResponse(weixin_pay_Url, map, theaderList);
                  //解析返回的XML数据
                  Map response = WXPayUtil.xmlToMap(postResponse);
                  if(!response.isEmpty() && response.get("return_code").equals("SUCCESS")){
                        if(response.get("result_code").equals("SUCCESS")) {
                              boolean result = rechargeRecordService.generatedBills(response,attach);
                              if(result) {
                                    log.info("InfoMsg:--- 微信统一下单请求交易成功");
                              }
                        }else {
                              message = response.get("err_code_des");
                              log.error("errorMsg:--- 微信统一下单请求交易解析失败" + message);
                        }
                  }else {
                        log.error("errorMsg:--- 微信统一下单请求交易解析失败" + message);
                  }
                  log.info("InfoMsg:--- 微信统一下单请求交易结束");
                  return resp.success();
            } catch (Exception e) {
                  log.error("errorMsg:--- 微信统一下单请求交易失败" + e.getMessage());
                  return resp.failure(e.getMessage());
            }
            
      }



二、微信异步通知
/**
       * 微信支付通知地址
       *
       * @param request
       * @return
       */
      @RequestMapping(value=Route.Payment.WEIXIN_PAY_NOTIFY,method=RequestMethod.POST)
      @ResponseBody
      public Response weixin_pay_notify(HttpServletRequest request) {
            log.info("infoMsg:--- 微信异步通知开始");
            Response resp = this.getReponse();
            BufferedReader reader = null;
            String wx_map = "";
            try {
                  PlatformMutualityManagent pmm = platformMutualityManagentService.findOne(5);
                  Assert.notNull(pmm);
                  String app_key = pmm.getClient_id();
              reader = request.getReader();
              String line = "";
              String xmlString = null;
              StringBuffer inputString = new StringBuffer();
              while ((line = reader.readLine()) != null) {
                  inputString.append(line);
              }
              xmlString = inputString.toString();
              request.getReader().close();
              if(!StringUtils.isBlank(xmlString)) {
                  Map return_map = WXPayUtil.xmlToMap(xmlString);
                  //验签
                  if(WXPayUtil.isSignatureValid(xmlString, app_key)) {
                        if(return_map.get("return_map").equals("SUCCESS")) {
                              //TODO 账变,修改状态,到账提醒
                              Double amount = Double.parseDouble(return_map.get("total_fee"));
                              String passbackParams = return_map.get("total_fee");
                              String order_no = return_map.get("out_trade_no");
                              boolean result = rechargeRecordService.updateBill(amount,passbackParams,order_no);
                              if(result) {
                                    Map map = new HashMap<>();
                                    map.put("return_map", "SUCCESS");
                                    map.put("return_msg", "OK");
                                    wx_map = WXPayUtil.mapToXml(map);
                              }
                        }
                  }
              }
                  log.info("infoMsg:--- 微信异步通知失败");
                  return resp.success(wx_map);
            } catch (Exception e) {
                  log.error("errorMsg:--- 微信通知失败" + e.getMessage());
                  return resp.failure(e.getMessage());
            }
      }




三、微信支付订单查询
/**
       * 微信支付订单查询
       *
       * @param transaction_id 微信订单号
       * @param out_trade_no  平台订单号
       * @return
       */
      @RequestMapping(value=Route.Payment.WEIXIN_PAY_QUERY,method=RequestMethod.POST)
      @ResponseBody
      public Response weixin_pay_query(@PathVariable("transaction_id") String transaction_id,@PathVariable("out_trade_no") String out_trade_no) {
            log.info("infoMsg:--- 微信支付订单查询开始");     
            Response resp = this.getReponse();
            String sign = "";
            String message = "";
            Map return_map = null;
            try {
                  ThirdPayBean bean = thirdPayService.findByPayId(19);
                  Assert.notNull(bean);
                  String mch_id = bean.getMer_no();   //商户号
                  PlatformMutualityManagent pmm = platformMutualityManagentService.findOne(5);
                  Assert.notNull(pmm);
                  String appid = pmm.getClient_id();        //应用ID
                  String App_Secret = pmm.getClient_secret();     
                  String nonce_str = WXPayUtil.generateNonceStr();            //随机字符串
                  
                  StringBuffer sb = new StringBuffer();
                  sb.append("appid=").append(appid).append("&");
                  sb.append("nonce_str=").append(nonce_str).append("&");
                  sb.append("out_trade_no=").append(out_trade_no).append("&");
                  String params = sb.toString();
                  //需要签名的数据
                  String stringSignTemp = params + "&key=" + App_Secret;
                  //MD5签名方式
                  sign = WXPayUtil.MD5(stringSignTemp).toUpperCase();
                  Map req_map = new HashMap<>();
                  req_map.put("appid", appid);
                  req_map.put("mch_id", mch_id);
                  req_map.put("transaction_id", transaction_id);
                  req_map.put("out_trade_no", out_trade_no);
                  req_map.put("nonce_str", nonce_str);
                  req_map.put("sign", sign);
                  List headerList = new ArrayList<>();
                  headerList.add(new UHeader("Content-Type", "application/x-www-form-urlencoded"));
                  String postResponse = MaryunHttpUtils.getPostResponse(weixin_query_Url, req_map, headerList);
                  if(StringUtils.trim(postResponse).equals("")) {
                        return_map = WXPayUtil.xmlToMap(postResponse);
                        if(!return_map.isEmpty()) {
                              String return_code = return_map.get("return_code");
                              if(return_code.equals("SUCCESS")) {
                                    String result_code = return_map.get("return_code");
                                    if(result_code.equals("SUCCESS")) {
                                          message = (String) req_map.get("trade_state_desc");
                                    }
                              }else {
                                    message = (String) req_map.get("err_code_des");
                              }
                        }
                  }
                  log.info("infoMsg:--- 微信支付订单查询结束");     
                  return resp.success(return_map);
            } catch (Exception e) {
                  log.error("erroroMsg:--- 微信支付订单查询失败" + e.getMessage() + message);      
                  return resp.failure(e.getMessage() + message);
            }
      }




三、微信支付中设计的工具类
1.httpclient
package com.xunxin.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import com.alibaba.fastjson.JSON;
/**
 * Copyright © 2017 noseparte(Libra) © Like the wind, like rain
 * @Author Noseparte
 * @Compile 2017年10月24日 -- 下午6:03:20
 * @Version 1.0
 * @Description   Apache HttpClient Util
 */
public class MaryunHttpUtils {
      
          public static class UHeader{
            /**
             * the title of header.
             */
            private String headerTitle;
            private String headerValue;
                  public  UHeader(String headerTitle, String headerValue) {
                        super();
                        this.headerTitle = headerTitle;
                        this.headerValue = headerValue;
                  }
                  public String getHeaderTitle() {
                        return headerTitle;
                  }
                  public void setHeaderTitle(String headerKey) {
                        this.headerTitle = headerKey;
                  }
                  public String getHeaderValue() {
                        return headerValue;
                  }
                  public void setHeaderValue(String headerValue) {
                        this.headerValue = headerValue;
                  }
          }
          public static String getResponse(String url,HashMap args,List headerList){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
//                client = setProxy(client);
//                    client.getHostConfiguration().setProxy("10.170.187.42", 3128);
                  client.setConnectionTimeout(60000);
                  client.setTimeout(60000);
                        GetMethod method = new GetMethod(url);
                        client.getParams().setContentCharset("UTF-8");
                        if(headerList.size()>0){
                              for(int i = 0;i args,List headerList){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
                  //client = setProxy(client);
//                    client.getHostConfiguration().setProxy("10.170.187.42", 3128);
                  Iterator it = args.entrySet().iterator();
                  String sargs = "";
                        while(it.hasNext()){
                              Entry entry = (Entry)it.next();
                              sargs += "&"+entry.getKey().toString()+"="+entry.getValue();
                        }
                        if(!"".equals(sargs)){
                              sargs = "?"+sargs.substring(1, sargs.length());
                        }
                        System.out.println(url+sargs);
                        GetMethod method = new GetMethod(url+sargs);
//                      client.getParams().setContentCharset("UTF-8");
                        if(headerList!=null&&headerList.size()>0){
                              for(int i = 0;i map,List headerList){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
                  //client = setProxy(client);
                  
//                    client.getHostConfiguration().setProxy("10.170.187.42", 3128);
                        PostMethod method = new PostMethod(url);
                        client.getParams().setContentCharset("UTF-8");
                        if(headerList.size()>0){
                              for(int i = 0;i args,List headerList,String headerName){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
                        PostMethod method = new PostMethod(url);
                        client.getParams().setContentCharset("UTF-8");
                        if(headerList.size()>0){
                              for(int i = 0;i headerList){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
                        PostMethod method = new PostMethod(url);
                        client.getParams().setContentCharset("UTF-8");
                        if(headerList.size()>0){
                              for(int i = 0;i headerList,String headerName){
            String info = "";
            try {
                  HttpClient client = new HttpClient();
                        PostMethod method = new PostMethod(url);
                        client.getParams().setContentCharset("UTF-8");
                        if(headerList.size()>0){
                              for(int i = 0;i= maxPerMSECSize) { 
                    orderNumCount = 0L; 
                } 
                //组装订单号 
                String countStr=maxPerMSECSize +orderNumCount+""; 
                finOrderNum=nowLong+countStr.substring(1); 
                orderNumCount++; 
                System.out.println(finOrderNum); 
                // Thread.sleep(1000); 
            } 
            return finOrderNum; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        }
      return null; 
    }   

2.商户订单号工具类 OrderGeneratedUtils
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 *
 * Copyright © 2017 noseparte(Libra) © Like the wind, like rain
 * @Author Noseparte
 * @Compile 2017年11月2日 -- 下午5:18:35
 * @Version 1.0
 * @Description   订单生成工具类
 */
public class OrderGeneratedUtils {
       /**
     * 锁对象,可以为任意对象
     */ 
    private static Object lockObj = "lockerOrder"; 
    /**
     * 订单号生成计数器
     */ 
    private static long orderNumCount = 0L; 
    /**
     * 每毫秒生成订单号数量最大值
     */ 
    private static int maxPerMSECSize=1000;
   
    /** 
     * 生成订单编号 
     * @return 
     */   
    public static synchronized String getOrderNo() {   
      try { 
            // 最终生成的订单号 
            String finOrderNum = ""; 
            synchronized (lockObj) { 
                // 取系统当前时间作为订单号变量前半部分,精确到毫秒 
                long nowLong = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())); 
                // 计数器到最大值归零,可扩展更大,目前1毫秒处理峰值1000个,1秒100万 
                if (orderNumCount >= maxPerMSECSize) { 
                    orderNumCount = 0L; 
                } 
                //组装订单号 
                String countStr=maxPerMSECSize +orderNumCount+""; 
                finOrderNum=nowLong+countStr.substring(1); 
                orderNumCount++; 
                System.out.println(finOrderNum); 
                // Thread.sleep(1000); 
            } 
            return finOrderNum; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        }
      return null; 
    }   
 
3.微信支付随机算法生成 WXRandomNumberUtil
import java.util.Random;
/**
 *
 * Copyright © 2017 noseparte(Libra) © Like the wind, like rain
 * @Author Noseparte
 * @Compile 2017年11月6日 -- 上午11:20:41
 * @Version 1.0
 * @Description   微信支付生成随机数算法
 */
public class WXRandomNumberUtil {
      /**
       * 生成随机数算法
       *
       * @param length
       * @return
       */
    public static String getRandomStringByLength(int length) { 
        String base = "abcdefghijklmnopqrstuvwxyz0123456789"; 
        Random random = new Random(); 
        StringBuffer sb = new StringBuffer(); 
        for (int i = 0; i < length; i++) { 
            int number = random.nextInt(base.length()); 
            sb.append(base.charAt(number)); 
        } 
        return sb.toString(); 
    } 
   
   
   
    /**
     * 微信支付交易金额格式化
     *
     * @param amount
     * @return
     */
    public static int wx_format_PayAmount(String amount) {
      int pay_amount = 0;
      pay_amount = Integer.parseInt((amount.split(".")[0])) * 100;
      return pay_amount;
    }

4..微信支付工具类(官方) WXPayUtil
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.xunxin.util.constants.WXPayConstants;
import com.xunxin.util.constants.WXPayConstants.SignType;
/**
 *
 * Copyright © 2017 noseparte(Libra) © Like the wind, like rain
 * @Author Noseparte
 * @Compile 2017年11月6日 -- 下午6:10:22
 * @Version 1.0
 * @Description 微信支付通用工具类
 */
public class WXPayUtil {
    /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map xmlToMap(String strXML) throws Exception {
        try {
            Map data = new HashMap();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }
    }
    /**
     * 将Map转换为XML格式的字符串
     *
     * @param data Map类型数据
     * @return XML格式的字符串
     * @throws Exception
     */
    public static String mapToXml(Map data) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = documentBuilder.newDocument();
        org.w3c.dom.Element root = document.createElement("xml");
        document.appendChild(root);
        for (String key: data.keySet()) {
            String value = data.get(key);
            if (value == null) {
                value = "";
            }
            value = value.trim();
            org.w3c.dom.Element filed = document.createElement(key);
            filed.appendChild(document.createTextNode(value));
            root.appendChild(filed);
        }
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);
        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
        try {
            writer.close();
        }
        catch (Exception ex) {
        }
        return output;
    }
    /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @return 含有sign字段的XML
     */
    public static String generateSignedXml(final Map data, String key) throws Exception {
        return generateSignedXml(data, key, SignType.MD5);
    }
    /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名类型
     * @return 含有sign字段的XML
     */
    public static String generateSignedXml(final Map data, String key, SignType signType) throws Exception {
        String sign = generateSignature(data, key, signType);
        data.put(WXPayConstants.FIELD_SIGN, sign);
        return mapToXml(data);
    }
    /**
     * 判断签名是否正确
     *
     * @param xmlStr XML格式数据
     * @param key API密钥
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
        Map data = xmlToMap(xmlStr);
        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
            return false;
        }
        String sign = data.get(WXPayConstants.FIELD_SIGN);
        return generateSignature(data, key).equals(sign);
    }
    /**
     * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
     *
     * @param data Map类型数据
     * @param key API密钥
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(Map data, String key) throws Exception {
        return isSignatureValid(data, key, SignType.MD5);
    }
    /**
     * 判断签名是否正确,必须包含sign字段,否则返回false。
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(Map data, String key, SignType signType) throws Exception {
        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
            return false;
        }
        String sign = data.get(WXPayConstants.FIELD_SIGN);
        return generateSignature(data, key, signType).equals(sign);
    }
    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @param key API密钥
     * @return 签名
     */
    public static String generateSignature(final Map data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }
    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data 待签名数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map data, String key, SignType signType) throws Exception {
        Set keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }
    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
    /**
     * 生成 HMACSHA256
     * @param data 待处理数据
     * @param key 密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
    /**
     * 日志
     * @return
     */
    public static Logger getLogger() {
        Logger logger = LoggerFactory.getLogger("wxpay java sdk");
        return logger;
    }
    /**
     * 获取当前时间戳,单位秒
     * @return
     */
    public static long getCurrentTimestamp() {
        return System.currentTimeMillis()/1000;
    }
    /**
     * 获取当前时间戳,单位毫秒
     * @return
     */
    public static long getCurrentTimestampMs() {
        return System.currentTimeMillis();
    }
    /**
     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
     * @return
     */
    public static String generateUUID() {

        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
}



About Me:

  • Github地址:https://github.com/noseparte 
  • Email:  [email protected]     有java与hadoop相关的技术问题,可以发私信与我交流。
  • NPM地址:  https://www.npmjs.com/~noseparte
  • WebSite: http://www.noseparte.com/   Copyright © 2017 noseparte

你可能感兴趣的:(Java,支付,APP)