国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Java微信退款開發(fā)

Java微信退款開發(fā)

2021-06-02 13:56thinkhui Java教程

這篇文章主要為大家詳細介紹了Java微信退款開發(fā)的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、下載證書并導入到系統(tǒng)

微信支付接口中,涉及資金回滾的接口會使用到商戶證書,包括退款、撤銷接口。商家在申請微信支付成功后,可以按照以下路徑下載:微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->api安全-->證書下載。

Java微信退款開發(fā)

Java微信退款開發(fā)

下載的時候需要手機驗證及登錄密碼。下載后找到apiclient_cert.p12這個證書,雙擊導入,導入的時候提示輸入密碼,這個密碼就是商戶id,且必須是在自己的商戶平臺下載的證書。否則會出現(xiàn)密碼錯誤的提示:

Java微信退款開發(fā)

導入正確的提示:

Java微信退款開發(fā)

二、編寫代碼

首先初始化退款接口中的請求參數(shù),如微信訂單號transaction_id(和商戶訂單號只需要知道一個)、訂單金額total_fee等;其次調(diào)用mobimessage中的refundresdata2xml方法解析成需要的類型;最后調(diào)用refundrequest類的httpsrequest方法觸發(fā)請求。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
 * 處理退款請求
 * @param request
 * @return
 * @throws exception
 */
 @requestmapping("/refund")
 @responsebody
 public jsonapi refund(httpservletrequest request) throws exception {
  //獲得當前目錄
  string path = request.getsession().getservletcontext().getrealpath("/");
  logutils.trace(path);
 
  date now = new date();
  simpledateformat dateformat = new simpledateformat("yyyymmddhhmmss");//可以方便地修改日期格式
  string outrefundno = "no" + dateformat.format( now );
 
  //獲得退款的傳入?yún)?shù)
  string transactionid = "4008202001201609012791655620";
  string outtradeno = "20160901141024";
  integer totalfee = 1;
  integer refundfee = totalfee;
 
  refundreqdata refundreqdata = new refundreqdata(transactionid,outtradeno,outrefundno,totalfee,refundfee);
 
  string info = mobimessage.refundreqdata2xml(refundreqdata).replaceall("__", "_");
  logutils.trace(info);
 
  try {
   refundrequest refundrequest = new refundrequest();
   string result = refundrequest.httpsrequest(wxconfigure.refund_api, info, path);
   logutils.trace(result);
 
   map<string, string> getmap = mobimessage.parsexml(new string(result.tostring().getbytes(), "utf-8"));
   if("success".equals(getmap.get("return_code")) && "success".equals(getmap.get("return_msg"))){
    return new jsonapi();
   }else{
    //返回錯誤描述
    return new jsonapi(getmap.get("err_code_des"));
   }
  }catch(exception e){
   e.printstacktrace();
   return new jsonapi();
  }
}

初始化退款接口需要的數(shù)據(jù),隱藏了get和set方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class refundreqdata {
 
 //每個字段具體的意思請查看api文檔
 private string appid = "";
 private string mch_id = "";
 private string nonce_str = "";
 private string sign = "";
 private string transaction_id = "";
 private string out_trade_no = "";
 private string out_refund_no = "";
 private int total_fee = 0;
 private int refund_fee = 0;
 private string op_user_id = "";
 
 /**
  * 請求退款服務
  * @param transactionid 是微信系統(tǒng)為每一筆支付交易分配的訂單號,通過這個訂單號可以標識這筆交易,它由支付訂單api支付成功時返回的數(shù)據(jù)里面獲取到。建議優(yōu)先使用
  * @param outtradeno 商戶系統(tǒng)內(nèi)部的訂單號,transaction_id 、out_trade_no 二選一,如果同時存在優(yōu)先級:transaction_id>out_trade_no
  * @param outrefundno 商戶系統(tǒng)內(nèi)部的退款單號,商戶系統(tǒng)內(nèi)部唯一,同一退款單號多次請求只退一筆
  * @param totalfee 訂單總金額,單位為分
  * @param refundfee 退款總金額,單位為分
  */
 public refundreqdata(string transactionid,string outtradeno,string outrefundno,int totalfee,int refundfee){
 
  //微信分配的公眾號id(開通公眾號之后可以獲取到)
  setappid(wxconfigure.appid);
 
  //微信支付分配的商戶號id(開通公眾號的微信支付功能之后可以獲取到)
  setmch_id(wxconfigure.mch_id);
 
  //transaction_id是微信系統(tǒng)為每一筆支付交易分配的訂單號,通過這個訂單號可以標識這筆交易,它由支付訂單api支付成功時返回的數(shù)據(jù)里面獲取到。
  settransaction_id(transactionid);
 
  //商戶系統(tǒng)自己生成的唯一的訂單號
  setout_trade_no(outtradeno);
 
  setout_refund_no(outrefundno);
 
  settotal_fee(totalfee);
 
  setrefund_fee(refundfee);
 
  setop_user_id(wxconfigure.mch_id);
 
  //隨機字符串,不長于32 位
  setnonce_str(stringutil.generaterandomstring(16));
 
 
  //根據(jù)api給的簽名規(guī)則進行簽名
  sortedmap<object, object> parameters = new treemap<object, object>();
  parameters.put("appid", appid);
  parameters.put("mch_id", mch_id);
  parameters.put("nonce_str", nonce_str);
  parameters.put("transaction_id", transaction_id);
  parameters.put("out_trade_no", out_trade_no);
  parameters.put("out_refund_no", out_refund_no);
  parameters.put("total_fee", total_fee);
  parameters.put("refund_fee", refund_fee);
  parameters.put("op_user_id", op_user_id);
 
 
  string sign = dictionarysort.createsign(parameters);
  setsign(sign); //把簽名數(shù)據(jù)設置到sign這個屬性中
 
 }

mobimessage實現(xiàn)json數(shù)據(jù)類型和xml數(shù)據(jù)之間的轉(zhuǎn)換。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class mobimessage {
 
 public static map<string,string> xml2map(httpservletrequest request) throws ioexception, documentexception {
  map<string,string> map = new hashmap<string, string>();
  saxreader reader = new saxreader();
  inputstream inputstream = request.getinputstream();
  document document = reader.read(inputstream);
  element root = document.getrootelement();
  list<element> list = root.elements();
  for(element e:list){
   map.put(e.getname(), e.gettext());
  }
  inputstream.close();
  return map;
 }
 
 
 //訂單轉(zhuǎn)換成xml
 public static string jsapireqdata2xml(jsapireqdata jsapireqdata){
  /*xstream xstream = new xstream();
  xstream.alias("xml",productinfo.getclass());
  return xstream.toxml(productinfo);*/
  mobimessage.xstream.alias("xml",jsapireqdata.getclass());
  return mobimessage.xstream.toxml(jsapireqdata);
 }
 
 public static string refundreqdata2xml(refundreqdata refundreqdata){
  /*xstream xstream = new xstream();
  xstream.alias("xml",productinfo.getclass());
  return xstream.toxml(productinfo);*/
  mobimessage.xstream.alias("xml",refundreqdata.getclass());
  return mobimessage.xstream.toxml(refundreqdata);
 }
 
 public static string class2xml(object object){
 
  return "";
 }
 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;
 }
 
 //擴展xstream,使其支持cdata塊
 private static xstream xstream = new xstream(new xppdriver() {
  public hierarchicalstreamwriter createwriter(writer out) {
   return new prettyprintwriter(out) {
    // 對所有xml節(jié)點的轉(zhuǎn)換都增加cdata標記
    boolean cdata = true;
 
    //@suppresswarnings("unchecked")
    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);
     }
    }
   };
  }
 });
 
 
}

refundrequest類中initcert方法加載證書到系統(tǒng)中,其中證書地址如下:

?
1
public static string certlocalpath = "/web-inf/cert/apiclient_cert.p12";

refundrequest類中httpsrequest方法調(diào)用微信接口,觸發(fā)請求。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * user: rizenguo
 * date: 2014/10/29
 * time: 14:36
 */
public class refundrequest {
 
 //連接超時時間,默認10秒
 private int sockettimeout = 10000;
 
 //傳輸超時時間,默認30秒
 private int connecttimeout = 30000;
 
 //請求器的配置
 private requestconfig requestconfig;
 
 //http請求器
 private closeablehttpclient httpclient;
 
 /**
  * 加載證書
  * @param path
  * @throws ioexception
  * @throws keystoreexception
  * @throws unrecoverablekeyexception
  * @throws nosuchalgorithmexception
  * @throws keymanagementexception
  */
 private void initcert(string path) throws ioexception, keystoreexception, unrecoverablekeyexception, nosuchalgorithmexception, keymanagementexception {
  //拼接證書的路徑
  path = path + wxconfigure.certlocalpath;
  keystore keystore = keystore.getinstance("pkcs12");
 
  //加載本地的證書進行https加密傳輸
  fileinputstream instream = new fileinputstream(new file(path));
  try {
   keystore.load(instream, wxconfigure.mch_id.tochararray()); //加載證書密碼,默認為商戶id
  } catch (certificateexception e) {
   e.printstacktrace();
  } catch (nosuchalgorithmexception e) {
   e.printstacktrace();
  } finally {
   instream.close();
  }
 
  // trust own ca and all self-signed certs
  sslcontext sslcontext = sslcontexts.custom()
    .loadkeymaterial(keystore, wxconfigure.mch_id.tochararray())  //加載證書密碼,默認為商戶id
    .build();
  // allow tlsv1 protocol only
  sslconnectionsocketfactory sslsf = new sslconnectionsocketfactory(
    sslcontext,
    new string[]{"tlsv1"},
    null,
    sslconnectionsocketfactory.browser_compatible_hostname_verifier);
 
  httpclient = httpclients.custom()
    .setsslsocketfactory(sslsf)
    .build();
 
  //根據(jù)默認超時限制初始化requestconfig
  requestconfig = requestconfig.custom().setsockettimeout(sockettimeout).setconnecttimeout(connecttimeout).build();
 
 }
 
 
 /**
  * 通過https往api post xml數(shù)據(jù)
  * @param url api地址
  * @param xmlobj 要提交的xml數(shù)據(jù)對象
  * @param path 當前目錄,用于加載證書
  * @return
  * @throws ioexception
  * @throws keystoreexception
  * @throws unrecoverablekeyexception
  * @throws nosuchalgorithmexception
  * @throws keymanagementexception
  */
 public string httpsrequest(string url, string xmlobj, string path) throws ioexception, keystoreexception, unrecoverablekeyexception, nosuchalgorithmexception, keymanagementexception {
  //加載證書
  initcert(path);
 
  string result = null;
 
  httppost httppost = new httppost(url);
 
  //得指明使用utf-8編碼,否則到api服務器xml的中文不能被成功識別
  stringentity postentity = new stringentity(xmlobj, "utf-8");
  httppost.addheader("content-type", "text/xml");
  httppost.setentity(postentity);
 
  //設置請求器的配置
  httppost.setconfig(requestconfig);
 
  try {
   httpresponse response = httpclient.execute(httppost);
 
   httpentity entity = response.getentity();
 
   result = entityutils.tostring(entity, "utf-8");
 
  } catch (connectionpooltimeoutexception e) {
   logutils.trace("http get throw connectionpooltimeoutexception(wait time out)");
 
  } catch (connecttimeoutexception e) {
   logutils.trace("http get throw connecttimeoutexception");
 
  } catch (sockettimeoutexception e) {
    logutils.trace("http get throw sockettimeoutexception");
 
  } catch (exception e) {
    logutils.trace("http get throw exception");
 
  } finally {
   httppost.abort();
  }
 
  return result;
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/fenghuibian/article/details/52459699

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91久久在线观看 | 精品免费久久久久久久苍 | 天天艹 | 日本一区二区视频在线播放 | 欧美在线1 | 在线国产一区二区 | 亚洲精品国产9999久久久久 | 一区在线播放 | 伊人五月| 天堂精品 | 午夜在线观看视频网站 | 亚洲免费精品 | 欧美在线观看一区 | 日本一区二区三区免费观看 | 国产在线观看免费 | 午夜爽爽爽 | 君岛美绪一区二区三区在线视频 | 日本不卡一区二区 | 国产中文视频 | 久久国内 | 国产精品三级视频 | 在线观看中文字幕 | 国产精品一区二区无线 | 欧美国产一区二区三区 | 欧美午夜精品久久久久免费视 | 亚洲午夜视频 | 国产一区日韩精品 | 亚洲一区在线日韩在线深爱 | 午夜男人天堂 | 亚洲天堂免费在线 | 91久久久久 | www中文字幕 | 午夜精品一区二区三区免费视频 | 国产一二三区在线观看 | 国产精品中文字幕在线 | 日本久久免费 | 国产久| 免费av观看| 精品成人久久久 | 日韩在线不卡 | 黄色一级在线观看 |