1. 程式人生 > >java開發微信公眾號支付

java開發微信公眾號支付

 String strAttach = "微信支付";
        //strAttach = new String(strAttach.getBytes("gbk"),"utf-8");
        String strBody = "微信公眾號支付";
        //strBody = new String(strBody.getBytes("gbk"),"utf-8");
        Order order= orderService.findBySn(sn);
        String ip = request.getRemoteAddr();
        WxPaySendData data = new WxPaySendData();
        data.setAppid(Configure.getAppid());
        data.setAttach(URLEncoder.encode(strAttach, "UTF-8"));
        data.setBody(URLEncoder.encode(strBody, "UTF-8"));
        data.setMch_id(Configure.getMchid());
        data.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));
        data.setNotify_url(Configure.getNotify_url());
        data.setOut_trade_no(UtilDate.getOrderNum());
        data.setTotal_fee((order.getAmount().multiply(new BigDecimal(100)).intValue()));//單位:分
        data.setTrade_type("JSAPI");
        data.setSpbill_create_ip(ip);
        data.setOpenid(at.getOpenid());
        String returnXml = UnifiedorderService.unifiedOrder(data,Configure.getKey());
        WxPayReturnData reData = new WxPayReturnData();
        XStream xs1 = new XStream(new DomDriver());
        xs1.alias("xml", WxPayReturnData.class);
        reData = (WxPayReturnData) xs1.fromXML(returnXml);
注意:這裡騰訊用的是xml格式的引數因此需要把引數轉成xml格式。這裡用的是XStream,並且需要把sendData 和 returnData 封裝成class

//工具類
UnifiedorderService.java
public class UnifiedorderService {
    
  private final static Logger logger = LoggerFactory.getLogger(UnifiedorderService.class);
    
  public static String unifiedOrder(WxPaySendData data,String key){
    //統一下單支付
    String returnXml = null;
    try {
      //生成sign簽名
      SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
      parameters.put("appid", data.getAppid()); 
      parameters.put("attach", data.getAttach());
      parameters.put("body", data.getBody());
      parameters.put("mch_id", data.getMch_id());
      parameters.put("nonce_str", data.getNonce_str());
      parameters.put("notify_url", data.getNotify_url());
      parameters.put("out_trade_no", data.getOut_trade_no());
      parameters.put("total_fee", data.getTotal_fee());
      parameters.put("trade_type", data.getTrade_type());
      parameters.put("spbill_create_ip", data.getSpbill_create_ip());
      parameters.put("openid", data.getOpenid());
      parameters.put("device_info", data.getDevice_info());
      logger.info("SIGN:"+WxSign.createSign(parameters,key));
      data.setSign(WxSign.createSign(parameters,key));
      XStream xs = new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_", "_")));
      xs.alias("xml", WxPaySendData.class);
      String xml = xs.toXML(data);
      logger.info("統一下單xml為:\n" + xml);
      HttpClientUtil util = HttpClientUtil.getInstance();
      returnXml = util.doPostForString("https://api.mch.weixin.qq.com/pay/unifiedorder", null, xml);
      logger.info("返回結果:" + returnXml);
    } catch (Exception e) {
      e.printStackTrace();
    } 
    return returnXml;
  }
    
}

//工具類
WxSign.java
public class WxSign {
    
    
  private static String characterEncoding = "UTF-8";
  
  @SuppressWarnings("rawtypes")
  public static String createSign(SortedMap<Object,Object> parameters,String key){ 
    StringBuffer sb = new StringBuffer(); 
    Set es = parameters.entrySet();//所有參與傳參的引數按照accsii排序(升序) 
    Iterator it = es.iterator(); 
    while(it.hasNext()) { 
      Map.Entry entry = (Map.Entry)it.next(); 
      String k = (String)entry.getKey(); 
      Object v = entry.getValue(); 
      if(null != v && !"".equals(v)  
          && !"sign".equals(k) && !"key".equals(k)) { 
        sb.append(k + "=" + v + "&"); 
      } 
    } 
    sb.append("key=" + key);
    String sign = MD5.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); 
    return sign; 
  }
    
  public static String getNonceStr() {
    Random random = new Random();
    return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
  }
  
  public static String getTimeStamp() {
    return String.valueOf(System.currentTimeMillis() / 1000);
  }
  
}

//md5.java
package com.pawpaw.plugin.tencentpay;


import java.security.MessageDigest;


/**
* User: rizenguo
* Date: 2014/10/23
* Time: 15:43
*/
public class MD5 {
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f"};


    /**
     * 轉換位元組陣列為16進位制字串
     * @param b 位元組陣列
     * @return 16進位制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }


    /**
     * 轉換byte到16進位制
     * @param b 要轉換的byte
     * @return 16進位制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }


    /**
     * MD5編碼
     * @param origin 原始字串
     * @return 經過MD5加密之後的結果
     */
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }


}

//WxPaySendData.java
package com.pawpaw.entity;


public class WxPaySendData {
        //公眾號ID
        private String appid;
        //附加引數
        private String attach;
        //商品名稱
        private String body;
        //商戶ID
        private String mch_id;
        //隨機支付串
        private String nonce_str;
        //通知地址,不能攜帶引數,直接就能訪問
        private String notify_url;
        //使用者訂單號
        private String out_trade_no;
        //總金額 以分為單位
        private int total_fee;
        //交易型別
        private String trade_type;
        //終端IP
        private String spbill_create_ip;
        //openID
        private String openid;
        //簽名
        private String sign;
        public String getAppid() {
                return appid;
        }
        public void setAppid(String appid) {
                this.appid = appid;
        }
        public String getAttach() {
                return attach;
        }
        public void setAttach(String attach) {
                this.attach = attach;
        }
        public String getBody() {
                return body;
        }
        public void setBody(String body) {
                this.body = body;
        }
        public String getMch_id() {
                return mch_id;
        }
        public void setMch_id(String mch_id) {
                this.mch_id = mch_id;
        }
        public String getNonce_str() {
                return nonce_str;
        }
        public void setNonce_str(String nonce_str) {
                this.nonce_str = nonce_str;
        }
        public String getNotify_url() {
                return notify_url;
        }
        public void setNotify_url(String notify_url) {
                this.notify_url = notify_url;
        }
        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 int getTotal_fee() {
                return total_fee;
        }
        public void setTotal_fee(int total_fee) {
                this.total_fee = total_fee;
        }
        public String getTrade_type() {
                return trade_type;
        }
        public void setTrade_type(String trade_type) {
                this.trade_type = trade_type;
        }
        public String getSpbill_create_ip() {
                return spbill_create_ip;
        }
        public void setSpbill_create_ip(String spbill_create_ip) {
                this.spbill_create_ip = spbill_create_ip;
        }
        public String getOpenid() {
                return openid;
        }
        public void setOpenid(String openid) {
                this.openid = openid;
        }
        public String getSign() {
                return sign;
        }
        public void setSign(String sign) {
                this.sign = sign;
        }
        
        
}

//WxPayReturnData.java
package com.pawpaw.entity;


public class WxPayReturnData {
        //業務結果
        private String return_code;
        //訊息
        private String return_msg;
                //公眾號ID
                private String appid;
                //商戶ID
                private String mch_id;
                //隨機支付串
                private String nonce_str;
                //簽名
                private String sign;
                //業務結果
                private String result_code;
                //預支付ID
                private String prepay_id;
                //交易型別
                private String trade_type;
        
                public String getReturn_code() {
                        return return_code;
                }
                public void setReturn_code(String return_code) {
                        this.return_code = return_code;
                }
                public String getReturn_msg() {
                        return return_msg;
                }
                public void setReturn_msg(String return_msg) {
                        this.return_msg = return_msg;
                }
                public String getAppid() {
                        return appid;
                }
                public void setAppid(String appid) {
                        this.appid = appid;
                }
                public String getMch_id() {
                        return mch_id;
                }
                public void setMch_id(String mch_id) {
                        this.mch_id = mch_id;
                }
                public String getNonce_str() {
                        return nonce_str;
                }
                public void setNonce_str(String nonce_str) {
                        this.nonce_str = nonce_str;
                }
                public String getSign() {
                        return sign;
                }
                public void setSign(String sign) {
                        this.sign = sign;
                }
                public String getResult_code() {
                        return result_code;
                }
                public void setResult_code(String result_code) {
                        this.result_code = result_code;
                }
                public String getPrepay_id() {
                        return prepay_id;
                }
                public void setPrepay_id(String prepay_id) {
                        this.prepay_id = prepay_id;
                }
                public String getTrade_type() {
                        return trade_type;
                }
                public void setTrade_type(String trade_type) {
                        this.trade_type = trade_type;
                }


                
                        
}

最後要提一下的是NOTIFY_URL回撥地址,接收微信支付非同步通知回撥地址。


三    通過上面的操作我們獲得了預支付交易會話標識prepay_id,這樣我們就可以進行最後一步的操作了。使用H5調起支付api。