欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

微信公眾號(hào)支付(二)實(shí)現(xiàn)統(tǒng)一下單接口

 更新時(shí)間:2015年09月08日 22:52:48   投稿:mrr  
本篇文章主要給大家介紹調(diào)用微信公眾支付的統(tǒng)一下單API,通過參數(shù)封裝為xml格式并發(fā)送到微信給的接口地址就可以獲得返回內(nèi)容,需要的朋友可以參考下本文

上一篇已經(jīng)獲取到了用戶的OpenId

這篇主要是調(diào)用微信公眾支付的統(tǒng)一下單API

API地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

看文檔,主要流程就是把20個(gè)左右的參數(shù)封裝為XML格式發(fā)送到微信給的接口地址,然后就可以獲取到返回的內(nèi)容了,如果成功里面就有支付所需要的預(yù)支付ID

請(qǐng)求參數(shù)就不解釋了。

其中,隨機(jī)字符串:我用的是UUID去中劃線

 public static String create_nonce_str() {
 return UUID.randomUUID().toString().replace("-","");
 }

商戶訂單號(hào):每個(gè)訂單號(hào)只能使用一次,所以用的是系統(tǒng)的訂單號(hào)加的時(shí)間戳。

總金額:不能為

通知地址:微信支付成功或失敗回調(diào)給系統(tǒng)的地址

簽名:

import java.io.Serializable;
 public class PayInfo implements Serializable{
 private static final long serialVersionUID = L;
 private String appid;
 private String mch_id;
 private String device_info;
 private String nonce_str;
 private String sign;
 private String body;
 private String attach;
 private String out_trade_no;
 private int total_fee;
 private String spbill_create_ip;
 private String notify_url;
 private String trade_type;
 private String openid;
 //下面是get,set方法 
 }


 /**
 * 創(chuàng)建統(tǒng)一下單的xml的java對(duì)象
 * @param bizOrder 系統(tǒng)中的業(yè)務(wù)單號(hào)
 * @param ip 用戶的ip地址
 * @param openId 用戶的openId
 * @return
 */
 public PayInfo createPayInfo(BizOrder bizOrder,String ip,String openId) {
  PayInfo payInfo = new PayInfo();
  payInfo.setAppid(Constants.appid);
  payInfo.setDevice_info("WEB");
  payInfo.setMch_id(Constants.mch_id);
  payInfo.setNonce_str(CommonUtil.create_nonce_str().replace("-", ""));
  payInfo.setBody("這里是某某白米飯的body");
  payInfo.setAttach(bizOrder.getId());
  payInfo.setOut_trade_no(bizOrder.getOrderCode().concat("A").concat(DateFormatUtils.format(new Date(), "MMddHHmmss")));
  payInfo.setTotal_fee((int)bizOrder.getFeeAmount());
  payInfo.setSpbill_create_ip(ip);
  payInfo.setNotify_url(Constants.notify_url);
  payInfo.setTrade_type("JSAPI");
  payInfo.setOpenid(openId);
  return payInfo;
 }

獲取簽名:

/**
 * 獲取簽名
 * @param payInfo
 * @return
 * @throws Exception
 */
 public String getSign(PayInfo payInfo) throws Exception {
  String signTemp = "appid="+payInfo.getAppid()
   +"&attach="+payInfo.getAttach()
   +"&body="+payInfo.getBody()
   +"&device_info="+payInfo.getDevice_info()
   +"&mch_id="+payInfo.getMch_id()
   +"&nonce_str="+payInfo.getNonce_str()
   +"&notify_url="+payInfo.getNotify_url()
   +"&openid="+payInfo.getOpenid()
   +"&out_trade_no="+payInfo.getOut_trade_no()
   +"&spbill_create_ip="+payInfo.getSpbill_create_ip()
   +"&total_fee="+payInfo.getTotal_fee()
   +"&trade_type="+payInfo.getTrade_type()
   +"&key="+Constants.key; //這個(gè)key注意
 MessageDigest md = MessageDigest.getInstance("MD");
 md.reset();
 md.update(signTemp.getBytes("UTF-"));
 String sign = CommonUtil.byteToStr(md.digest()).toUpperCase();
 return sign;
 }

注意:上面的Constants.key取值在商戶號(hào)API安全的API密鑰中。

一些工具方法:獲取ip地址,將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串,將字節(jié)轉(zhuǎn)換為十六進(jìn)制字符串

 /**
 * 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串
 * 
 * @param byteArray
 * @return
 */
 public static String byteToStr(byte[] byteArray) {
  String strDigest = "";
  for (int i = ; i < byteArray.length; i++) {
  strDigest += byteToHexStr(byteArray[i]);
  }
  return strDigest;
 }
 /**
 * 將字節(jié)轉(zhuǎn)換為十六進(jìn)制字符串
 * 
 * @param btyes
 * @return
 */
 public static String byteToHexStr(byte bytes) {
  char[] Digit = { '', '', '', '', '', '', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'F' };
  char[] tempArr = new char[];
  tempArr[] = Digit[(bytes >>> ) & XF];
  tempArr[] = Digit[bytes & XF];
  String s = new String(tempArr);
  return s;
 }
 /**
 * 獲取ip地址
 * @param request
 * @return
 */
 public static String getIpAddr(HttpServletRequest request) { 
  InetAddress addr = null; 
  try { 
  addr = InetAddress.getLocalHost(); 
  } catch (UnknownHostException e) { 
  return request.getRemoteAddr(); 
  } 
  byte[] ipAddr = addr.getAddress(); 
  String ipAddrStr = ""; 
  for (int i = ; i < ipAddr.length; i++) { 
  if (i > ) { 
   ipAddrStr += "."; 
  } 
  ipAddrStr += ipAddr[i] & xFF; 
  } 
  return ipAddrStr; 
 } 

這樣就獲取了簽名,把簽名與PayInfo中的其他數(shù)據(jù)轉(zhuǎn)成XML格式,當(dāng)做參數(shù)傳遞給統(tǒng)一下單地址。

 PayInfo pi = pu.createPayInfo(bo,"...","");
 String sign = pu.getSign(pi);
 pi.setSign(sign);

對(duì)象轉(zhuǎn)XML

 /**
 * 擴(kuò)展xstream使其支持CDATA
 */
 private static XStream xstream = new XStream(new XppDriver() {
  public HierarchicalStreamWriter createWriter(Writer out) {
  return new PrettyPrintWriter(out) {
   //增加CDATA標(biāo)記
   boolean cdata = true;
   @SuppressWarnings("rawtypes")
   public void startNode(String name, Class clazz) {
   super.startNode(name, clazz);
   }
   protected void writeText(QuickWriter writer, String text) {
   if (cdata) {
    writer.write("<![CDATA[");
    writer.write(text);
    writer.write("]]>");
   } else {
    writer.write(text);
   }
   }
  };
  }
 });
 public static String payInfoToXML(PayInfo pi) {
  xstream.alias("xml", pi.getClass());
  return xstream.toXML(pi);
 }

xml轉(zhuǎn)Map

 @SuppressWarnings("unchecked")
 public static Map<String, String> parseXml(String xml) throws Exception {
  Map<String, String> map = new HashMap<String, String>();
  Document document = DocumentHelper.parseText(xml);
  Element root = document.getRootElement();
  List<Element> elementList = root.elements();
  for (Element e : elementList)
  map.put(e.getName(), e.getText());
  return map;
 }

下面就是調(diào)用統(tǒng)一下單的URL了

log.info(MessageUtil.payInfoToXML(pi).replace("__", "_"));
   Map<String, String> map = CommonUtil.httpsRequestToXML("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", MessageUtil.payInfoToXML(pi).replace("__", "_").replace("<![CDATA[", "").replace("]]>", ""));
 log.info(map);

 public static Map<String, String> httpsRequestToXML(String requestUrl, String requestMethod, String outputStr) {
  Map<String, String> result = new HashMap<>();
  try {
  StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr);
  result = MessageUtil.parseXml(buffer.toString());
  } catch (ConnectException ce) {
  log.error("連接超時(shí):"+ce.getMessage());
  } catch (Exception e) {
  log.error("https請(qǐng)求異常:"+ece.getMessage());
  }
  return result;
 }

httpsRequest()這個(gè)方法在第一篇中

上面獲取到的Map如果成功的話,里面就會(huì)有

String return_code = map.get("return_code");
 if(StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")){
   String return_msg = map.get("return_msg");
 if(StringUtils.isNotBlank(return_msg) && !return_msg.equals("OK")) {
   return "統(tǒng)一下單錯(cuò)誤!";
 }
 }else{
   return "統(tǒng)一下單錯(cuò)誤!";
 }
 String prepay_Id = map.get("prepay_id");

這個(gè)prepay_id就是預(yù)支付的ID。后面支付需要它。

相關(guān)文章

  • java 中Thread.join()的使用方法

    java 中Thread.join()的使用方法

    這篇文章主要介紹了java 中Thread.join()的使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 關(guān)于java入門與java開發(fā)環(huán)境配置詳細(xì)教程

    關(guān)于java入門與java開發(fā)環(huán)境配置詳細(xì)教程

    這篇文章主要介紹了關(guān)于java入門與java開發(fā)環(huán)境配置詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel)

    詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel)

    這篇文章主要介紹了詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • mybatis查詢匹配機(jī)制圖文詳解

    mybatis查詢匹配機(jī)制圖文詳解

    這篇文章主要給大家介紹了關(guān)于mybatis查詢匹配機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java中的transient關(guān)鍵字解讀

    java中的transient關(guān)鍵字解讀

    這篇文章主要介紹了java中的transient關(guān)鍵字解讀,transient關(guān)鍵字的主要作用就是讓某些被transient關(guān)鍵字修飾的成員屬性變量不被序列化,實(shí)際上也正是因此,在學(xué)習(xí)過程中很少用得上序列化操作,一般都是在實(shí)際開發(fā)中,需要的朋友可以參考下
    2023-09-09
  • Java構(gòu)造方法實(shí)例詳解(動(dòng)力節(jié)點(diǎn)java學(xué)院整理)

    Java構(gòu)造方法實(shí)例詳解(動(dòng)力節(jié)點(diǎn)java學(xué)院整理)

    其實(shí)java構(gòu)造方法很簡(jiǎn)單,下面通過示例給大家分享java構(gòu)造方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下
    2017-04-04
  • JVM方法調(diào)用invokevirtual詳解

    JVM方法調(diào)用invokevirtual詳解

    JVM調(diào)用方法有五條指令,分別是invokestatic,invokespecial,invokevirtual,invokeinterface,invokedynamic,這篇文章主要說明invokevirtual方法的調(diào)用問題,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-03-03
  • Java學(xué)習(xí)之Lambda表達(dá)式的使用詳解

    Java學(xué)習(xí)之Lambda表達(dá)式的使用詳解

    Lambda表達(dá)式是Java SE 8中一個(gè)重要的新特性,允許通過表達(dá)式來代替功能接口。本文將通過一些簡(jiǎn)單的示例和大家講講Lamda表達(dá)式的使用,感興趣的可以了解一下
    2022-12-12
  • Java字符串無(wú)意識(shí)的遞歸過程解析

    Java字符串無(wú)意識(shí)的遞歸過程解析

    這篇文章主要介紹了Java字符串無(wú)意識(shí)的遞歸過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java中上傳圖片壓縮處理的方法示例

    Java中上傳圖片壓縮處理的方法示例

    本篇文章主要介紹了Java中圖片壓縮處理的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02

最新評(píng)論