java实现微信退款功能

时间:2022-11-09 16:01:37

微信退款之前需要在常量中配置退款地址,退款的地址必须是可以直接访问的。(之前的申请商户平台及在开放平台申请账号不在描述)在调起之前需要下载商户平台上的证书将其放在项目src下。 

java实现微信退款功能

微信退款回调url :微信官方建议在提交退款申请后进行退款回调url配置,便于通知退款的结果。配置在微信商户平台-》交易中心-》退款配置栏进行退款结果回调通知配置。配置的url必须为可以直接访问的类似付款成功回调url。

java实现微信退款功能

配置成功后在回调的url中处理退款后的结果。微信给返回的参数如下:

java实现微信退款功能

对于加密信息req_info的解密步骤如下。

java实现微信退款功能

解密过程中需要先到oracle官网下载对应java版本的sercity包,然后将下载后的包中两个jar复制到jdk/jre/lib/security/包下并覆盖原jar.另外需要在项目中引入一个bcprov-jdk15on-158.jar 

java实现微信退款功能

退款部分代码:

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// 构造向微信发送参数的实体类
  private unifiedorder unifiedorder = new unifiedorder();
  // 微信的参数
  private weixinconfigutils config = new weixinconfigutils();
  public static final string algorithm = "aes/ecb/pkcs7padding";
  private refundorder refundorder = new refundorder();
  @resource
  private aesdecodeutil aesdecodeutil;
@action("weixinrefund")
  public string weixinrefund() {
    try {
      string out_trade_no = getrequest().getparameter("out_trade_no");
      string refund_fee = getrequest().getparameter("refund_fee");
      alipay = alipayservice.searchalipaybyouttradeno(out_trade_no);
      if (alipay != null) {
        // 参数组
        string appid = alipay.getapp_id();
        string mch_id = config.mch_id;
        string nonce_str = randcharsutils.getrandomstring(16);
        string out_refund_no = uuidutils.getuuid();
        integer total_fee = alipay.gettotalfee();
        // 构造签名
        parameters.put("appid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("nonce_str", nonce_str);
        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", mch_id);
        string sign = wxsignutils.createsign("utf-8", parameters);
        // 向微信发送xml消息
        // unifiedorder unifiedorder = new unifiedorder();
        unifiedorder.setappid(appid);
        unifiedorder.setmch_id(mch_id);
        unifiedorder.setsign(sign);
        unifiedorder.setnonce_str(nonce_str);
        unifiedorder.setout_trade_no(out_trade_no);
        unifiedorder.setout_refund_no(out_refund_no);
        unifiedorder.settotal_fee(total_fee);
        unifiedorder.setrefund_fee(integer.valueof(refund_fee));
        unifiedorder.setop_user_id(mch_id);
        string xmlinfo = httpxmlutils.refundxml(unifiedorder);
        unifiedorder = null;
        try {
          closeablehttpresponse response = httputil.post(
              weixinconstant.refund_url, xmlinfo, true);
          // 输出退款后的信息
          string refundxml = entityutils.tostring(response.getentity(), "utf-8");
          map<string, string> refundordermap = httpxmlutils.parserefundxml(refundxml);
          if (refundordermap.size()>0) {
            if (refundordermap.get("result_code").equals("success") && refundordermap.get("return_code").equals("success")) {
              refundorder.setappid(refundordermap.get("appid"));
              refundorder.setmch_id(refundordermap.get("mch_id"));
              refundorder.settransaction_id(refundordermap.get("transaction_id"));
              refundorder.setout_trade_no(refundordermap.get("out_trade_no"));
              refundorder.setout_refund_no(refundordermap.get("out_refund_no"));
              refundorder.setrefund_id(refundordermap.get("refund_id"));
              refundorder.setrefund_fee(integer.valueof(refundordermap.get("refund_fee")));
              refundorder.settatol_fee(integer.valueof(refundordermap.get("total_fee")));
              refundorder.setrefund_status(weixinrefundstatusconstant.apply_success);
refundorderservice.saveorder(refundorder);
      msg.put("statecode", msgcode.success);
              msg.put("message ", "退款申请成功");
    refundorderservice.saveorder(refundorder);
            }else {
              msg.put("statecode", msgcode.error);
              msg.put("message ", "退款申请失败");
            }
          }else {
            msg.put("statecode", msgcode.error);
            msg.put("message ", "退款申请失败");
          }
          try {
            // 关闭流
            entityutils.consume(response.getentity());
          } finally {
            response.close();
          }
        } catch (exception e) {
          msg.put("statecode", msgcode.sys_error);
          msg.put("message ", "服务器异常");
        }
 
      } else {
        msg.put("statecode", msgcode.error);
        msg.put("message ", "退款申请失败");
      }
      struts2utils.renderjson(jsonobject.tojsonstring(msg,
          serializerfeature.disablecircularreferencedetect));
      return none;
    } catch (exception e) {
      log.error(e.getmessage());
      e.printstacktrace();
      return "500";
    }
  }
   /**
   * 微信退款回调url
   * */
 
  @action("refundnotifyurl")
  public string refundnotifyurl() throws ioexception {
    try {
      map<string, string> resultmap = jdomparsexmlutils.getweixinresult(
          struts2utils.getrequest(), struts2utils.getresponse());
      if (resultmap.get("return_code").equals("success")) {
        string reqinfo = resultmap.get("req_info");
        string result = aesdecodeutil.decode(reqinfo);
        map<string, string> resultmaps = httpxmlutils.parserefundnotifyxml(result);
        refundorder = refundorderservice.getorderbyoutrefundno(resultmaps.get("out_refund_no"));
        if (resultmaps.get("refund_status").equals("success")){
          refundorder.setrefund_status(weixinrefundstatusconstant.refund_success);
        }else if (resultmaps.get("refund_status").equals("change")) {
          refundorder.setrefund_status(weixinrefundstatusconstant.refund_fail);
      }else if (resultmaps.get("refund_status").equals("refundclose")) {
          refundorder.setrefund_status(weixinrefundstatusconstant.refund_closed);
      }
        refundorder.setrefund_rew_account(resultmaps.get("refund_recv_account"));
        system.out.println(resultmaps.get("refund_recv_account"));
        refundorderservice.updateorder(refundorder);
        refundorder = null;
        unifiedorder.setreturn_code("success");
      }
      unifiedorder.setreturn_code("success");
      string refundxml = httpxmlutils.refundxml(unifiedorder);
      struts2utils.getresponse().getwriter().write(refundxml);
      struts2utils.getresponse().getwriter().flush();
      } catch (exception e) {
      log.error(e.getmessage());
      e.printstacktrace();
      return "500";
    }
    return null;
}

 

?
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
package com.wellness.platfront.common.weixinutil;
 
import java.text.simpledateformat;
import java.util.calendar;
import java.util.date;
import java.util.random;
生成随机串
/**
 * nonce_str随即字符串
* @author
 * @date 2017/08/10
 */
public class randcharsutils {
  private static simpledateformat df = new simpledateformat("yyyymmddhhmmss");
 
  public static string getrandomstring(int length) { //length表示生成字符串的长度
    string base = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
    random random = new random(); 
    stringbuffer sb = new stringbuffer();
    int number = 0;
    for (int i = 0; i < length; i++) { 
      number = random.nextint(base.length()); 
      sb.append(base.charat(number)); 
    
    return sb.tostring(); 
  }
 
  /*
   * 订单开始交易的时间
   */
  public static string timestart(){
    return df.format(new date());
  }
 
  /*
   * 订单开始交易的时间
   */
  public static string timeexpire(){
    calendar now=calendar.getinstance();
    now.add(calendar.minute,30);
    return df.format(now.gettimeinmillis());
  }
 
}

生成签名的类

 

?
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
package com.wellness.platfront.common.weixinutil;
 
import java.util.iterator;
import java.util.map;
import java.util.set;
import java.util.sortedmap;
 
/**
 * 微信支付签名
 * @author
 * @date 2017/08/10
 */
public class wxsignutils {
  /**
   * 微信支付签名算法sign
   * @param characterencoding
   * @param parameters
   * @return
   */
  @suppresswarnings("rawtypes")
  public static string createsign(string characterencoding,sortedmap<object,object> parameters){
    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=" + weixinconstant.key);
    string sign = md5util.md5encode(sb.tostring(), characterencoding).touppercase();
    return sign;
  }
}

向微信发送消息的类

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
package com.wellness.platfront.common.weixinutil;
 
import java.io.bufferedreader;
import java.io.ioexception;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.io.outputstream;
import java.io.outputstreamwriter;
import java.io.stringreader;
import java.net.httpurlconnection;
import java.net.malformedurlexception;
import java.net.url;
import java.util.hashmap;
import java.util.list;
import java.util.map;
 
import javax.annotation.resource;
import javax.net.ssl.httpsurlconnection;
 
import org.jdom.jdomexception;
import org.jdom.input.saxbuilder;
import org.xml.sax.inputsource;
 
import com.thoughtworks.xstream.xstream;
import com.thoughtworks.xstream.io.xml.domdriver;
import com.thoughtworks.xstream.io.xml.xmlfriendlynamecoder;
import com.wellness.platfront.business.wechat.service.refundorderservice;
import com.wellness.platfront.entity.weixin.transfers;
import com.wellness.platfront.entity.weixin.unifiedorder;
/**
 * post提交xml格式的参数
 * @author
 * @date 2017/08/10
 */
public class httpxmlutils {
  @resource
  private refundorderservice refundorderservice;
  public static xstream xstream = new xstream(new domdriver("utf-8",
      new xmlfriendlynamecoder("-_", "_")));
  /**
   * 开始post提交参数到接口
   * 并接受返回
   * @param url
   * @param xml
   * @param method
   * @param contenttype
   * @return
   */
  public static string xmlhttpproxy(string url,string xml,string method,string contenttype){
    inputstream is = null;
    outputstreamwriter os = null;
    try {
      url _url = new url(url);
      httpurlconnection conn = (httpurlconnection) _url.openconnection();
      conn.setdoinput(true); 
      conn.setdooutput(true); 
      conn.setrequestproperty("content-type", "text/xml");
      conn.setrequestproperty("pragma:", "no-cache");
      conn.setrequestproperty("cache-control", "no-cache");
      conn.setrequestmethod("post");
      os = new outputstreamwriter(conn.getoutputstream());
      os.write(new string(xml.getbytes(contenttype)));
      os.flush();
      //返回值
      is = conn.getinputstream();
      return getcontent(is, "utf-8");
    } catch (malformedurlexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    } finally{
      try {
        if(os!=null){os.close();}
        if(is!=null){is.close();}
      } catch (ioexception e) {
        e.printstacktrace();
      }
    }
    return null;
  }
  /**
   * 解析返回的值
   * @param is
   * @param charset
   * @return
   */
  public static string getcontent(inputstream is, string charset) {
    string pagestring = null;
    inputstreamreader isr = null;
    bufferedreader br = null;
    stringbuffer sb = null;
    try {
      isr = new inputstreamreader(is, charset);
      br = new bufferedreader(isr);
      sb = new stringbuffer();
      string line = null;
      while ((line = br.readline()) != null) {
        sb.append(line + "\n");
      }
      pagestring = sb.tostring();
    } catch (exception e) {
      e.printstacktrace();
    } finally {
      try {
        if (is != null){
          is.close();
        }
        if(isr!=null){
          isr.close();
        }
        if(br!=null){
          br.close();
        }
      } catch (ioexception e) {
        e.printstacktrace();
      }
      sb = null;
    }
    return pagestring;
  }
  /**
   * 解析申请退款之后微信返回的值并进行存库操作
   * @throws ioexception
   * @throws jdomexception
   */
  public static map<string, string> parserefundxml(string refundxml) throws jdomexception, ioexception{
    parsexmlutils.jdomparsexml(refundxml);
    stringreader read = new stringreader(refundxml);
    // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
    inputsource source = new inputsource(read);
    // 创建一个新的saxbuilder
    saxbuilder sb = new saxbuilder();
    // 通过输入源构造一个document
    org.jdom.document doc;
    doc = (org.jdom.document) sb.build(source);
    org.jdom.element root = doc.getrootelement();// 指向根节点
    list<org.jdom.element> list = root.getchildren();
    map<string, string> refundordermap = new hashmap<string, string>();
    if(list!=null&&list.size()>0){
      for (org.jdom.element element : list) {
        refundordermap.put(element.getname(), element.gettext());
      }
      return refundordermap;
      }
    return null;
  }
  /**
   * 解析申请退款之后微信退款回调返回的字符串中内容
   * @throws ioexception
   * @throws jdomexception
   */
  public static map<string, string> parserefundnotifyxml(string refundxml) throws jdomexception, ioexception{
    parsexmlutils.jdomparsexml(refundxml);
    stringreader read = new stringreader(refundxml);
    // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
    inputsource source = new inputsource(read);
    // 创建一个新的saxbuilder
    saxbuilder sb = new saxbuilder();
    // 通过输入源构造一个document
    org.jdom.document doc;
    doc = (org.jdom.document) sb.build(source);
    org.jdom.element root = doc.getrootelement();// 指向根节点
    list<org.jdom.element> list = root.getchildren();
    map<string, string> resultmap = new hashmap<>();
    if(list!=null&&list.size()>0){
      for (org.jdom.element element : list){
        resultmap.put(element.getname(), element.gettext());
      }
    return resultmap;
    }
    return null;
  }
  /**
   * h5支付时 解析返回的值并返回prepareid
   * @throws ioexception
   * @throws jdomexception
   */
  public static map<string, string> geturl(unifiedorder unifiedorder) throws jdomexception, ioexception{
    string xmlinfo = httpxmlutils.xmlh5info(unifiedorder);
    string wxurl = weixinconstant.url;
    string method = "post";
    string weixinpost = httpxmlutils.httpsrequest(wxurl, method, xmlinfo).tostring();
    parsexmlutils.jdomparsexml(weixinpost);
    stringreader read = new stringreader(weixinpost);
    // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
    inputsource source = new inputsource(read);
    // 创建一个新的saxbuilder
    saxbuilder sb = new saxbuilder();
    // 通过输入源构造一个document
    org.jdom.document doc;
    doc = (org.jdom.document) sb.build(source);
    org.jdom.element root = doc.getrootelement();// 指向根节点
    list<org.jdom.element> list = root.getchildren();
    string prepayid =null;
    map<string, string> msg = new hashmap<string, string>();
    if(list!=null&&list.size()>0){
      for (org.jdom.element element : list) {
      msg.put(element.getname(), element.gettext());
      }
      }
    return msg;
  }
  /**
   * 解析返回的值并返回prepareid
   * @throws ioexception
   * @throws jdomexception
   */
  public static string getprepareid(unifiedorder unifiedorder) throws jdomexception, ioexception{
    string xmlinfo = httpxmlutils.xmlinfo(unifiedorder);
    string wxurl = weixinconstant.url;
    string method = "post";
    string weixinpost = httpxmlutils.httpsrequest(wxurl, method, xmlinfo).tostring();
    parsexmlutils.jdomparsexml(weixinpost);
    stringreader read = new stringreader(weixinpost);
    // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
    inputsource source = new inputsource(read);
    // 创建一个新的saxbuilder
    saxbuilder sb = new saxbuilder();
    // 通过输入源构造一个document
    org.jdom.document doc;
    doc = (org.jdom.document) sb.build(source);
    org.jdom.element root = doc.getrootelement();// 指向根节点
    list<org.jdom.element> list = root.getchildren();
    string prepayid =null;
    if(list!=null&&list.size()>0){
      for (org.jdom.element element : list) {
        if ( "prepay_id".equals(element.getname())) {
          prepayid= element.gettext();
          break;
        }
      }
      }
    return prepayid;
  }
  /**
   * 向微信发送企业付款请求并解析返回结果
   * @throws ioexception
   * @throws jdomexception
   */
  public static map<string, string> gettransfersmap(transfers transfers) throws jdomexception, ioexception{
    string xmlinfo = httpxmlutils.xmltransfer(transfers);
    string wxurl = weixinconstant.withdraw_url;
    string method = "post";
    string weixinpost = httpxmlutils.httpsrequest(wxurl, method, xmlinfo).tostring();
    parsexmlutils.jdomparsexml(weixinpost);
    stringreader read = new stringreader(weixinpost);
    // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
    inputsource source = new inputsource(read);
    // 创建一个新的saxbuilder
    saxbuilder sb = new saxbuilder();
    // 通过输入源构造一个document
    org.jdom.document doc;
    doc = (org.jdom.document) sb.build(source);
    org.jdom.element root = doc.getrootelement();// 指向根节点
    list<org.jdom.element> list = root.getchildren();
    map<string, string> transfermap=new hashmap<>();
    if(list!=null&&list.size()>0){
      for (org.jdom.element element : list) {
        transfermap.put(element.getname(), element.gettext());
      }
      }
    return transfermap;
  }
  /**
   * 构造退款xml参数
   * @param xml
   * @return
   */
  public static string refundxml(unifiedorder unifiedorder){
      xstream.autodetectannotations(true);
      xstream.alias("xml", unifiedorder.class);
      return xstream.toxml(unifiedorder);
  }
  /**
   * 构造企业付款xml参数
   * @param xml
   * @return
   */
  public static string transferxml(transfers transfers){
      xstream.autodetectannotations(true);
      xstream.alias("xml", transfers.class);
      return xstream.toxml(transfers);
  }
  /**
   * 构造xml参数
   * @param xml
   * @return
   */
  public static string xmlinfo(unifiedorder unifiedorder){
 
    if(unifiedorder!=null){
      stringbuffer bf = new stringbuffer();
      bf.append("<xml>");
 
      bf.append("<appid><![cdata[");
      bf.append(unifiedorder.getappid());
      bf.append("]]></appid>");
 
      bf.append("<mch_id><![cdata[");
      bf.append(unifiedorder.getmch_id());
      bf.append("]]></mch_id>");
 
      bf.append("<nonce_str><![cdata[");
      bf.append(unifiedorder.getnonce_str());
      bf.append("]]></nonce_str>");
 
      bf.append("<sign><![cdata[");
      bf.append(unifiedorder.getsign());
      bf.append("]]></sign>");
 
      bf.append("<body><![cdata[");
      bf.append(unifiedorder.getbody());
      bf.append("]]></body>");
 
      bf.append("<detail><![cdata[");
      bf.append(unifiedorder.getdetail());
      bf.append("]]></detail>");
 
      bf.append("<attach><![cdata[");
      bf.append(unifiedorder.getattach());
      bf.append("]]></attach>");
 
      bf.append("<out_trade_no><![cdata[");
      bf.append(unifiedorder.getout_trade_no());
      bf.append("]]></out_trade_no>");
 
      bf.append("<total_fee><![cdata[");
      bf.append(unifiedorder.gettotal_fee());
      bf.append("]]></total_fee>");
 
      bf.append("<spbill_create_ip><![cdata[");
      bf.append(unifiedorder.getspbill_create_ip());
      bf.append("]]></spbill_create_ip>");
 
      bf.append("<time_start><![cdata[");
      bf.append(unifiedorder.gettime_start());
      bf.append("]]></time_start>");
 
      bf.append("<time_expire><![cdata[");
      bf.append(unifiedorder.gettime_expire());
      bf.append("]]></time_expire>");
 
      bf.append("<notify_url><![cdata[");
      bf.append(unifiedorder.getnotify_url());
      bf.append("]]></notify_url>");
 
      bf.append("<trade_type><![cdata[");
      bf.append(unifiedorder.gettrade_type());
      bf.append("]]></trade_type>");
 
      bf.append("</xml>");
      return bf.tostring();
    }
    return "";
  }
  /**
   * 构造xml参数
   * @param xml
   * @return
   */
  public static string xmlh5info(unifiedorder unifiedorder){
    if(unifiedorder!=null){
      stringbuffer bf = new stringbuffer();
      bf.append("<xml>");
 
      bf.append("<appid><![cdata[");
      bf.append(unifiedorder.getappid());
      bf.append("]]></appid>");
 
      bf.append("<mch_id><![cdata[");
      bf.append(unifiedorder.getmch_id());
      bf.append("]]></mch_id>");
 
      bf.append("<nonce_str><![cdata[");
      bf.append(unifiedorder.getnonce_str());
      bf.append("]]></nonce_str>");
 
      bf.append("<sign><![cdata[");
      bf.append(unifiedorder.getsign());
      bf.append("]]></sign>");
 
      bf.append("<body><![cdata[");
      bf.append(unifiedorder.getbody());
      bf.append("]]></body>");
 
 
      bf.append("<attach><![cdata[");
      bf.append(unifiedorder.getattach());
      bf.append("]]></attach>");
 
      bf.append("<out_trade_no><![cdata[");
      bf.append(unifiedorder.getout_trade_no());
      bf.append("]]></out_trade_no>");
 
      bf.append("<total_fee><![cdata[");
      bf.append(unifiedorder.gettotal_fee());
      bf.append("]]></total_fee>");
 
      bf.append("<spbill_create_ip><![cdata[");
      bf.append(unifiedorder.getspbill_create_ip());
      bf.append("]]></spbill_create_ip>");
 
      bf.append("<notify_url><![cdata[");
      bf.append(unifiedorder.getnotify_url());
      bf.append("]]></notify_url>");
 
      bf.append("<trade_type><![cdata[");
      bf.append(unifiedorder.gettrade_type());
      bf.append("]]></trade_type>");
 
      bf.append("<scene_info><![cdata[");
      bf.append(unifiedorder.getscene_info());
      bf.append("]]></scene_info>");
 
      bf.append("</xml>");
      return bf.tostring();
    }
    return "";
  }
  /**
   * 构造退款xml参数
   * @param xml
   * @return
   */
  public static string xmltransfer(transfers transfers){
 
    if(transfers!=null){
      stringbuffer bf = new stringbuffer();
      bf.append("<xml>");
 
      bf.append("<mch_appid><![cdata[");
      bf.append(transfers.getmch_appid());
      bf.append("]]></mch_appid>");
 
      bf.append("<mchid><![cdata[");
      bf.append(transfers.getmchid());
      bf.append("]]></mchid>");
 
      bf.append("<nonce_str><![cdata[");
      bf.append(transfers.getnonce_str());
      bf.append("]]></nonce_str>");
 
      bf.append("<sign><![cdata[");
      bf.append(transfers.getsign());
      bf.append("]]></sign>");
 
      bf.append("<partner_trade_no><![cdata[");
      bf.append(transfers.getpartner_trade_no());
      bf.append("]]></partner_trade_no>");
 
 
      bf.append("<openid><![cdata[");
      bf.append(transfers.getopenid());
      bf.append("]]></openid>");
 
      bf.append("<check_name><![cdata[");
      bf.append(transfers.getcheck_name());
      bf.append("]]></check_name>");
 
      bf.append("<amount><![cdata[");
      bf.append(transfers.getamount());
      bf.append("]]></amount>");
 
      bf.append("<desc><![cdata[");
      bf.append(transfers.getdesc());
      bf.append("]]></desc>");
 
      bf.append("<spbill_create_ip><![cdata[");
      bf.append(transfers.getspbill_create_ip());
      bf.append("]]></spbill_create_ip>");
 
      bf.append("</xml>");
      return bf.tostring();
    }
    return "";
  }
  /**
   * post请求并得到返回结果
   * @param requesturl
   * @param requestmethod
   * @param output
   * @return
   */
  public static string httpsrequest(string requesturl, string requestmethod, string output) {
    try{
      url url = new url(requesturl);
      httpsurlconnection connection = (httpsurlconnection) url.openconnection();
      connection.setdooutput(true);
      connection.setdoinput(true);
      connection.setusecaches(false);
      connection.setrequestmethod(requestmethod);
      if (null != output) {
        outputstream outputstream = connection.getoutputstream();
        outputstream.write(output.getbytes("utf-8"));
        outputstream.close();
      }
      // 从输入流读取返回内容
      inputstream inputstream = connection.getinputstream();
      inputstreamreader inputstreamreader = new inputstreamreader(inputstream, "utf-8");
      bufferedreader bufferedreader = new bufferedreader(inputstreamreader);
      string str = null;
      stringbuffer buffer = new stringbuffer();
      while ((str = bufferedreader.readline()) != null) {
        buffer.append(str);
      }
      bufferedreader.close();
      inputstreamreader.close();
      inputstream.close();
      inputstream = null;
      connection.disconnect();
      return buffer.tostring();
    }catch(exception ex){
      ex.printstacktrace();
    }
    return "";
  }
}

加载证书

?
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
package com.wellness.platfront.common.weixinutil;
 
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.httpclients;
 
public class httputil {
  /**
   * 发送post请求
   *
   * @param url
   *      请求地址
   * @param outputentity
   *      发送内容
   * @param isloadcert
   *      是否加载证书
   */
  public static closeablehttpresponse post(string url, string outputentity, boolean isloadcert) throws exception {
    httppost httppost = new httppost(url);
    // 得指明使用utf-8编码,否则到api服务器xml的中文不能被成功识别
    httppost.addheader("content-type", "text/xml");
    httppost.setentity(new stringentity(outputentity, "utf-8"));
    if (isloadcert) {
      // 加载含有证书的http请求
      return httpclients.custom().setsslsocketfactory(certutil.initcert()).build().execute(httppost);
    } else {
      return httpclients.custom().build().execute(httppost);
    }
  }
}

加载证书的类

?
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
package com.wellness.platfront.common.weixinutil;
 
import java.io.file;
import java.io.fileinputstream;
import java.security.keystore;
 
import javax.net.ssl.sslcontext;
 
import org.apache.http.conn.ssl.sslconnectionsocketfactory;
import org.apache.http.ssl.sslcontexts;
 
/**
 * 加载证书的类
 * @author
 * @since 2017/08/16
 */
 
@suppresswarnings("deprecation")
public class certutil {
  private static weixinconfigutils config = new weixinconfigutils();
  /**
   * 加载证书
   */
  public static sslconnectionsocketfactory initcert() throws exception {
    fileinputstream instream = null;
    keystore keystore = keystore.getinstance("pkcs12");
    instream = new fileinputstream(new file(weixinconstant.path));
    keystore.load(instream, config.mch_id.tochararray());
 
    if (null != instream) {
      instream.close();
    }
 
    sslcontext sslcontext = sslcontexts.custom().loadkeymaterial(keystore,config.mch_id.tochararray()).build();
    sslconnectionsocketfactory sslsf = new sslconnectionsocketfactory(sslcontext, new string[]{"tlsv1"}, null, sslconnectionsocketfactory.browser_compatible_hostname_verifier);
 
    return sslsf;
  }
}

解密微信退款中返回相关信息的字符串

 

?
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
package com.wellness.platfront.common.weixinutil;
 
import java.security.security;
import javax.crypto.cipher;
import javax.crypto.secretkey;
import javax.crypto.spec.secretkeyspec;
import org.apache.commons.codec.binary.base64;
import org.bouncycastle.jce.provider.bouncycastleprovider;
import org.springframework.stereotype.service;
 
import com.wellness.platfront.common.wechat.utils.md5;
 
/**
 * 解密微信退款中返回相关信息的字符串
 * @author
 * @since 2017/09/05
 */
@service
public class aesdecodeutil {
 
   public static final string algorithm = "aes/ecb/pkcs7padding";
   public string decode(string reqinfo) throws exception{
    try {
      byte[] decodebase64 = base64.decodebase64(reqinfo);
      string md5key = md5.md5encode(weixinconstant.key);
      security.addprovider(new bouncycastleprovider());
      cipher cipher = cipher.getinstance(algorithm);
      secretkey keyspec = new secretkeyspec(md5key.getbytes(), "aes"); //生成加密解密需要的key
      cipher.init(cipher.decrypt_mode, keyspec);
      byte[] decoded = cipher.dofinal(decodebase64);
      string result = new string(decoded, "utf-8");
      return result;
    } catch (exception e) {
      e.printstacktrace();
    }
    return null;
   }
}

微信解析xml:带有cdata格式的

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
package com.wellness.platfront.common.weixinutil;
 
 
import java.io.bytearrayoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.printwriter;
import java.io.stringreader;
import java.util.hashmap;
import java.util.list;
import java.util.map;
 
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
 
import org.jdom.document;
import org.jdom.element;
import org.jdom.jdomexception;
import org.jdom.input.saxbuilder;
import org.xml.sax.inputsource;
 
import com.wellness.platfront.entity.weixin.unifiedorderresult;
import com.wellness.platfront.entity.weixin.wxpayresult;
 
 
/**
 * 微信解析xml:带有cdata格式的
* @author
 * @date 2017/08/10
 */
public class jdomparsexmlutils {
 
  /**
   * 1、统一下单获取微信返回
   * 解析的时候自动去掉cdma
   * @param xml
   */
  @suppresswarnings("unchecked")
  public static unifiedorderresult getunifiedorderresult(string xml){
    unifiedorderresult unifieorderresult = new unifiedorderresult();
    try {
      stringreader read = new stringreader(xml);
      // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
      inputsource source = new inputsource(read);
      // 创建一个新的saxbuilder
      saxbuilder sb = new saxbuilder();
      // 通过输入源构造一个document
      document doc;
      doc = (document) sb.build(source);
 
      element root = doc.getrootelement();// 指向根节点
      list<element> list = root.getchildren();
 
      if(list!=null&&list.size()>0){
        for (element element : list) {
          system.out.println("key是:"+element.getname()+",值是:"+element.gettext());
 
          if("return_code".equals(element.getname())){
            unifieorderresult.setreturn_code(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            unifieorderresult.setreturn_msg(element.gettext());
          }
 
          if("appid".equals(element.getname())){
            unifieorderresult.setappid(element.gettext());
          }
 
 
          if("mch_id".equals(element.getname())){
            unifieorderresult.setmch_id(element.gettext());
          }
 
          if("nonce_str".equals(element.getname())){
            unifieorderresult.setnonce_str(element.gettext());
          }
 
          if("sign".equals(element.getname())){
            unifieorderresult.setsign(element.gettext());
          }
 
          if("result_code".equals(element.getname())){
            unifieorderresult.setresult_code(element.gettext());
          }
 
          if("prepay_id".equals(element.getname())){
            unifieorderresult.setprepay_id(element.gettext());
          }
 
          if("trade_type".equals(element.getname())){
            unifieorderresult.settrade_type(element.gettext());
          }
        }
      }
 
    } catch (jdomexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    }catch (exception e) {
      e.printstacktrace();
    }
 
    return unifieorderresult;
  }
 
  /**
   * 获取微信回调的参数并将xml解析成map
   * 解析的时候自动去掉cdma
   * @param xml
   */
  @suppresswarnings("unchecked")
  public static map<string, string> getweixinresult(httpservletrequest request,httpservletresponse response){
    map<string, string> resultmap = new hashmap<>();
     try {
        printwriter writer = response.getwriter();
          inputstream instream = request.getinputstream();
          bytearrayoutputstream outsteam = new bytearrayoutputstream();
          byte[] buffer = new byte[1024];
          int len = 0;
          while ((len = instream.read(buffer)) != -1) {
            outsteam.write(buffer, 0, len);
          }
          outsteam.close();
          instream.close();
          string result = new string(outsteam.tobytearray(), "utf-8");
          stringreader read = new stringreader(result);
          inputsource source = new inputsource(read);
          // 创建一个新的saxbuilder
          saxbuilder sb = new saxbuilder();
          // 通过输入源构造一个document
          document doc;
          doc = (document) sb.build(source);
 
          element root = doc.getrootelement();// 指向根节点
          list<element> list = root.getchildren();
 
          if(list!=null&&list.size()>0){
            for (element element : list) {
              resultmap.put(element.getname(), element.gettext());
            }
          }
        return resultmap;
        } catch (exception e) {
          e.printstacktrace();
        }
     return null;
  }
 
 
  /**
   * 2、微信回调后参数解析
   * 解析的时候自动去掉cdma
   * @param xml
   */
  @suppresswarnings("unchecked")
  public static wxpayresult getwxpayresult(string xml){
    wxpayresult wxpayresult = new wxpayresult();
    try {
      stringreader read = new stringreader(xml);
      // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
      inputsource source = new inputsource(read);
      // 创建一个新的saxbuilder
      saxbuilder sb = new saxbuilder();
      // 通过输入源构造一个document
      document doc;
      doc = (document) sb.build(source);
 
      element root = doc.getrootelement();// 指向根节点
      list<element> list = root.getchildren();
 
      if(list!=null&&list.size()>0){
        for (element element : list) {
          if("return_code".equals(element.getname())){
            wxpayresult.setreturn_code(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
 
          if("appid".equals(element.getname())){
            wxpayresult.setappid(element.gettext());
          }
 
          if("mch_id".equals(element.getname())){
            wxpayresult.setmch_id(element.gettext());
          }
 
          if("nonce_str".equals(element.getname())){
            wxpayresult.setnonce_str(element.gettext());
          }
 
          if("sign".equals(element.getname())){
            wxpayresult.setsign(element.gettext());
          }
 
          if("result_code".equals(element.getname())){
            wxpayresult.setresult_code(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
          if("return_msg".equals(element.getname())){
            wxpayresult.setreturn_msg(element.gettext());
          }
 
        }
      }
 
    } catch (jdomexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    }catch (exception e) {
      e.printstacktrace();
    }
 
    return wxpayresult;
  }
 
}

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.wellness.platfront.common.weixinutil;
 
/**
 * dom解析
 * @author
 * @date 2017/08/10
 */
import java.io.ioexception;
import java.io.stringreader;
import java.util.iterator;
import java.util.list;
 
import org.apache.commons.lang.stringutils;
import org.dom4j.document;
import org.dom4j.documentexception;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.saxreader;
import org.jdom.jdomexception;
import org.jdom.input.saxbuilder;
import org.xml.sax.inputsource;
 
public class parsexmlutils {
 
  /**
   * 1、dom解析
   */
  @suppresswarnings("rawtypes")
  public static void beginxmlparse(string xml){
    document doc = null;
    try {
      doc = documenthelper.parsetext(xml); // 将字符串转为xml
 
      element rootelt = doc.getrootelement(); // 获取根节点smsreport
 
      system.out.println("根节点是:"+rootelt.getname());
 
      iterator iters = rootelt.elementiterator("sendresp"); // 获取根节点下的子节点sms
 
      while (iters.hasnext()) {
        element recordele1 = (element) iters.next();
        iterator iter = recordele1.elementiterator("sms");
 
        while (iter.hasnext()) {
          element recordele = (element) iter.next();
          string phone = recordele.elementtexttrim("phone"); // 拿到sms节点下的子节点stat值
 
          string smsid = recordele.elementtexttrim("smsid"); // 拿到sms节点下的子节点stat值
 
          system.out.println(phone+":"+smsid);
        }
      }
    } catch (documentexception e) {
      e.printstacktrace();
    } catch (exception e) {
      e.printstacktrace();
    }
  }
 
  /**
   * 2、dom4j解析xml(支持xpath)
   * 解析的时候自动去掉cdma
   * @param xml
   */
  public static void xpathparsexml(string xml){
    try {
      stringreader read = new stringreader(xml);
      saxreader saxreader = new saxreader();
      document doc = saxreader.read(read);
      string xpath ="/xml/appid";
      system.out.print(doc.selectsinglenode(xpath).gettext());
    } catch (documentexception e) {
      e.printstacktrace();
    }
  }
 
  /**
   * 3、jdom解析xml
   * 解析的时候自动去掉cdma
   * @param xml
   */
  @suppresswarnings("unchecked")
  public static void jdomparsexml(string xml){
    try {
      stringreader read = new stringreader(xml);
      // 创建新的输入源sax 解析器将使用 inputsource 对象来确定如何读取 xml 输入
      inputsource source = new inputsource(read);
      // 创建一个新的saxbuilder
      saxbuilder sb = new saxbuilder();
      // 通过输入源构造一个document
      org.jdom.document doc;
      doc = (org.jdom.document) sb.build(source);
 
      org.jdom.element root = doc.getrootelement();// 指向根节点
      list<org.jdom.element> list = root.getchildren();
 
      if(list!=null&&list.size()>0){
        for (org.jdom.element element : list) {
          /*try{
            methodname = element.getname();
            method m = v.getclass().getmethod("set" + methodname, new class[] { string.class });
            if(parseint(methodname)){
              m.invoke(v, new object[] { integer.parseint(element.gettext()) });
            }else{
              m.invoke(v, new object[] { element.gettext() });
            }
          }catch(exception ex){
            ex.printstacktrace();
          }*/
 
        }
      }
 
    } catch (jdomexception e) {
      e.printstacktrace();
    } catch (ioexception e) {
      e.printstacktrace();
    }catch (exception e) {
      e.printstacktrace();
    }
  }
 
  public static boolean parseint(string key){
    if(!stringutils.isempty(key)){
      if(key.equals("total_fee")||key.equals("cash_fee")||key.equals("coupon_fee")||key.equals("coupon_count")||key.equals("coupon_fee_0")){
        return true;
      }
    }
 
    return false;
  }
 
}

微信支付相关的常量

 

?
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
package com.wellness.platfront.common.weixinutil;
/**
 * 微信支付相关的常量
 * @author yangfuren
 * @since 2017/08/16
 */
public class weixinconstant {
  /**
   * 微信支付api秘钥
   */
  public static final string key = "eao9gdbk7njqkyevrfb82csputiniwnd";
 
  /**
   * url
   */
  public static final string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  /**
   * 退款url
   */
  public static final string refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  /**
   * 证书地址
   */
  public static final string path ="";
  /**
   * 付款url
   */
  public static final string withdraw_url="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
}

微信退款状态常量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.wellness.platfront.common.weixinutil;
/**
 * 微信退款状态常量
 * @author
 * @since 2017/09/04
 */
public class weixinrefundstatusconstant {
  //退款申请成功
  public static final string apply_success="退款申请成功";
  //退款申请失败
  public static final string apply_fail="退款申请失败";
  //退款成功
  public static final string refund_success="退款成功";
  //退款异常
  public static final string refund_fail="退款异常";
  //退款关闭
  public static final string refund_closed="退款关闭";
 
}

微信退款订单信息

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.wellness.platfront.entity.weixin;
 
import java.io.serializable;
import java.util.date;
 
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.generationtype;
import javax.persistence.id;
import javax.persistence.table;
 
/**
 * 微信退款订单信息
 * @author
 *
 */
@entity
@table(name = "weixin_refund_order")
public class refundorder implements serializable{
  private static final long serialversionuid = 1l;
  //退款订单id
  public integer refundorderid;
  //微信公众账号
  public string appid;
  //微信商户号
  public string mch_id;
  //微信订单号
  public string transaction_id;
  //商户订单号
  public string out_trade_no;
  //商户退款单号
  public string out_refund_no;
  //微信退款单号
  public string refund_id;
  //退款金额
  public integer refund_fee;
  //订单总价格
  public integer tatol_fee;
  //退款发起时间
  public date create_time;
  //退款状态  申请退款中 申请退款失败 退款成功 退款异常  退款关闭
  public string refund_status;
  //退款退还账户
  public string refund_rew_account;
  //退款完成时间
  public date end_time;
  //订单退还方式
    public string refundtype;
  @id
  @generatedvalue(strategy = generationtype.auto)
  @column(name = "refund_order_id", nullable = false)
  public integer getrefundorderid() {
    return refundorderid;
  }
  public void setrefundorderid(integer refundorderid) {
    this.refundorderid = refundorderid;
  }
  @column(name = "appid", nullable = false)
  public string getappid() {
    return appid;
  }
  public void setappid(string appid) {
    this.appid = appid;
  }
  @column(name = "mch_id", nullable = false)
  public string getmch_id() {
    return mch_id;
  }
  public void setmch_id(string mch_id) {
    this.mch_id = mch_id;
  }
  @column(name = "transaction_id", nullable = false)
  public string gettransaction_id() {
    return transaction_id;
  }
  public void settransaction_id(string transaction_id) {
    this.transaction_id = transaction_id;
  }
  @column(name = "out_trade_no", nullable = false)
  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;
  }
  @column(name = "out_refund_no", nullable = false)
  public string getout_refund_no() {
    return out_refund_no;
  }
  public void setout_refund_no(string out_refund_no) {
    this.out_refund_no = out_refund_no;
  }
  @column(name = "refund_id", nullable = false)
  public string getrefund_id() {
    return refund_id;
  }
  public void setrefund_id(string refund_id) {
    this.refund_id = refund_id;
  }
  @column(name = "refund_fee", nullable = false)
  public integer getrefund_fee() {
    return refund_fee;
  }
  public void setrefund_fee(integer refund_fee) {
    this.refund_fee = refund_fee;
  }
  @column(name = "tatol_fee", nullable = false)
  public integer gettatol_fee() {
    return tatol_fee;
  }
  public void settatol_fee(integer tatol_fee) {
    this.tatol_fee = tatol_fee;
  }
  @column(name = "create_time", nullable = false)
  public date getcreate_time() {
    return create_time;
  }
  public void setcreate_time(date create_time) {
    this.create_time = create_time;
  }
  @column(name = "refund_status", nullable = false)
  public string getrefund_status() {
    return refund_status;
  }
  public void setrefund_status(string refund_status) {
    this.refund_status = refund_status;
  }
  @column(name = "refund_rew_account")
  public string getrefund_rew_account() {
    return refund_rew_account;
  }
  public void setrefund_rew_account(string refund_rew_account) {
    this.refund_rew_account = refund_rew_account;
  }
  @column(name = "end_time")
  public date getend_time() {
    return end_time;
  }
  public void setend_time(date end_time) {
    this.end_time = end_time;
  }
 
  @column(name = "refund_type")
  public string getrefundtype() {
    return refundtype;
  }
  public void setrefundtype(string refundtype) {
    this.refundtype = refundtype;
  }
}

这个实体类中参数和微信官方需要的参数一致

 

?
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package com.wellness.platfront.entity.weixin;
 
import java.io.serializable;
import com.wellness.platfront.entity.member.member;
 
/**
 * 统一下单提交为微信的参数
 * @author
 * @date 2017年08月11日
 */
public class unifiedorder implements serializable{
  private static final long serialversionuid = 1l;
  //微信支付表id
  private integer weixinid;
  //微信分配的公众账号id(企业号corpid即为此appid)
  private string appid;
  //商户id
  private string mch_id;
  //终端设备号(门店号或收银设备id),注意:pc网页或公众号内支付请传"web"
  private string device_info;
  //随机字符串:数字+大写字母的组合,32位
  private string nonce_str;
  //签名
  private string sign;
  //商品或支付单简要描述
  private string body;
  //商品名称明细列表
  private string detail;
  //附加参数(例如:用于区别本商户不同的分店)
  private string attach;
  //商户系统内部的订单号
  private string out_trade_no;
  //货币类型:符合iso 4217标准的三位字母代码,默认人民币:cny
  private string fee_type;
  //总金额
  private int total_fee;
  //app和网页支付提交[用户端ip],native支付填调用微信支付api的机器ip。
  private string spbill_create_ip;
  //订单生成时间,格式为yyyymmddhhmmss,
  private string time_start;
  //订单失效时间,格式为yyyymmddhhmmss,最短失效时间间隔必须大于5分钟[支付宝是30分钟,同样30分钟]
  private string time_expire;
  //商品标记,代金券或立减优惠功能的参数
  private string goods_tag;
  //接收微信支付异步通知回调地址
  private string notify_url;
  //交易类型:jsapi,native,app h5为 mweb
  private string trade_type;
  //trade_type=native,此参数必传。此id为二维码中包含的商品id,商户自行定义。
  private string product_id;
  //no_credit--指定不能使用信用卡支付
  private string limit_pay;
  //trade_type=jsapi,此参数必传,用户在商户appid下的唯一标识
  private string openid;
  //商户内部自己的退款单号
  private string out_refund_no;
  //退款总金额单位为分
  private int refund_fee;
  //操作员的id默认为mch_id
  private string op_user_id;
  //微信官方提供的订单号
  private string prepayid;
  //记录所对应的member
  private member member;
  //返回给微信的状态码(用于支付回调时)
  public string return_code;
  //微信h5支付时候的场景信息官方的信息模板 {"h5_info"://h5支付固定传"h5_info"
  //{"type":"",//场景类型 "wap_url":"",//wap网站url地址"wap_name": ""//wap 网站名}}
  public string scene_info;
  public string getscene_info() {
    return scene_info;
  }
  public void setscene_info(string scene_info) {
    this.scene_info = scene_info;
  }
  public string getreturn_code() {
    return return_code;
  }
  public void setreturn_code(string return_code) {
    this.return_code = return_code;
  }
  public string getappid() {
    return appid;
  }
  public string getmch_id() {
    return mch_id;
  }
  public string getdevice_info() {
    return device_info;
  }
  public string getnonce_str() {
    return nonce_str;
  }
  public string getsign() {
    return sign;
  }
  public string getbody() {
    return body;
  }
  public string getdetail() {
    return detail;
  }
  public string getattach() {
    return attach;
  }
  public string getout_trade_no() {
    return out_trade_no;
  }
  public string getfee_type() {
    return fee_type;
  }
  public int gettotal_fee() {
    return total_fee;
  }
  public string getspbill_create_ip() {
    return spbill_create_ip;
  }
  public string gettime_start() {
    return time_start;
  }
  public string gettime_expire() {
    return time_expire;
  }
  public string getgoods_tag() {
    return goods_tag;
  }
  public string getnotify_url() {
    return notify_url;
  }
  public string gettrade_type() {
    return trade_type;
  }
  public string getproduct_id() {
    return product_id;
  }
  public string getlimit_pay() {
    return limit_pay;
  }
  public string getopenid() {
    return openid;
  }
  public void setappid(string appid) {
    this.appid = appid;
  }
  public void setmch_id(string mch_id) {
    this.mch_id = mch_id;
  }
  public void setdevice_info(string device_info) {
    this.device_info = device_info;
  }
  public void setnonce_str(string nonce_str) {
    this.nonce_str = nonce_str;
  }
  public void setsign(string sign) {
    this.sign = sign;
  }
  public void setbody(string body) {
    this.body = body;
  }
  public void setdetail(string detail) {
    this.detail = detail;
  }
  public void setattach(string attach) {
    this.attach = attach;
  }
  public void setout_trade_no(string out_trade_no) {
    this.out_trade_no = out_trade_no;
  }
  public void setfee_type(string fee_type) {
    this.fee_type = fee_type;
  }
  public void settotal_fee(int total_fee) {
    this.total_fee = total_fee;
  }
  public void setspbill_create_ip(string spbill_create_ip) {
    this.spbill_create_ip = spbill_create_ip;
  }
  public void settime_start(string time_start) {
    this.time_start = time_start;
  }
  public void settime_expire(string time_expire) {
    this.time_expire = time_expire;
  }
  public void setgoods_tag(string goods_tag) {
    this.goods_tag = goods_tag;
  }
  public void setnotify_url(string notify_url) {
    this.notify_url = notify_url;
  }
  public void settrade_type(string trade_type) {
    this.trade_type = trade_type;
  }
  public void setproduct_id(string product_id) {
    this.product_id = product_id;
  }
  public void setlimit_pay(string limit_pay) {
    this.limit_pay = limit_pay;
  }
  public void setopenid(string openid) {
    this.openid = openid;
  }
  public string getout_refund_no() {
    return out_refund_no;
  }
  public void setout_refund_no(string out_refund_no) {
    this.out_refund_no = out_refund_no;
  }
  public int getrefund_fee() {
    return refund_fee;
  }
  public void setrefund_fee(int refund_fee) {
    this.refund_fee = refund_fee;
  }
  public integer getweixinid() {
    return weixinid;
  }
  public void setweixinid(integer weixinid) {
    this.weixinid = weixinid;
  }
  public member getmember() {
    return member;
  }
  public void setmember(member member) {
    this.member = member;
  }
  public string getprepayid() {
    return prepayid;
  }
  public void setprepayid(string prepayid) {
    this.prepayid = prepayid;
  }
  public string getop_user_id() {
    return op_user_id;
  }
  public void setop_user_id(string op_user_id) {
    this.op_user_id = op_user_id;
  }
 
 
}

统一下单微信返回的参数组(xml)

?
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
package com.wellness.platfront.entity.weixin;
 
/**
 * 统一下单微信返回的参数组(xml)
 * @author
 * @date 2017年08月11日
 */
public class unifiedorderresult {
  private string appid;//appid
  private string mch_id;//商家id
  private string device_info;//设备号
  private string nonce_str;//随机字符串
  private string sign;//签名
  private string result_code;//错误码
  private string err_code;//错误代码
  private string err_code_des;//错误返回的信息描述
  private string trade_type;//调用接口提交的交易类型,取值如下:jsapi,native,app
  private string prepay_id;//微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
  private string code_url;//trade_type为native是有返回,可将该参数值生成二维码展示出来进行扫码支付
 
  private string return_code;//返回状态码success/fail此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
  private string return_msg;//返回信息
  public string getappid() {
    return appid;
  }
  public string getmch_id() {
    return mch_id;
  }
  public string getdevice_info() {
    return device_info;
  }
  public string getnonce_str() {
    return nonce_str;
  }
  public string getsign() {
    return sign;
  }
  public string getresult_code() {
    return result_code;
  }
  public string geterr_code() {
    return err_code;
  }
  public string geterr_code_des() {
    return err_code_des;
  }
  public string gettrade_type() {
    return trade_type;
  }
  public string getprepay_id() {
    return prepay_id;
  }
  public string getcode_url() {
    return code_url;
  }
  public void setappid(string appid) {
    this.appid = appid;
  }
  public void setmch_id(string mch_id) {
    this.mch_id = mch_id;
  }
  public void setdevice_info(string device_info) {
    this.device_info = device_info;
  }
  public void setnonce_str(string nonce_str) {
    this.nonce_str = nonce_str;
  }
  public void setsign(string sign) {
    this.sign = sign;
  }
  public void setresult_code(string result_code) {
    this.result_code = result_code;
  }
  public void seterr_code(string err_code) {
    this.err_code = err_code;
  }
  public void seterr_code_des(string err_code_des) {
    this.err_code_des = err_code_des;
  }
  public void settrade_type(string trade_type) {
    this.trade_type = trade_type;
  }
  public void setprepay_id(string prepay_id) {
    this.prepay_id = prepay_id;
  }
  public void setcode_url(string code_url) {
    this.code_url = code_url;
  }
  public string getreturn_code() {
    return return_code;
  }
  public string getreturn_msg() {
    return return_msg;
  }
  public void setreturn_code(string return_code) {
    this.return_code = return_code;
  }
  public void setreturn_msg(string return_msg) {
    this.return_msg = return_msg;
  }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/github_38924695/article/details/78725039