1 package com.foxinmy.weixin4j.api;
2
3 import java.io.BufferedReader;
4 import java.io.BufferedWriter;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.io.OutputStream;
8 import java.io.OutputStreamWriter;
9 import java.io.UnsupportedEncodingException;
10 import java.net.URLEncoder;
11 import java.util.Calendar;
12 import java.util.Date;
13 import java.util.HashMap;
14 import java.util.Map;
15
16 import com.alibaba.fastjson.JSON;
17 import com.alibaba.fastjson.TypeReference;
18 import com.foxinmy.weixin4j.exception.WeixinException;
19 import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
20 import com.foxinmy.weixin4j.http.weixin.XmlResult;
21 import com.foxinmy.weixin4j.model.WeixinPayAccount;
22 import com.foxinmy.weixin4j.payment.mch.APPPayRequest;
23 import com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest;
24 import com.foxinmy.weixin4j.payment.mch.MICROPayRequest;
25 import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
26 import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
27 import com.foxinmy.weixin4j.payment.mch.MerchantResult;
28 import com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest;
29 import com.foxinmy.weixin4j.payment.mch.NativePayResponse;
30 import com.foxinmy.weixin4j.payment.mch.OpenIdResult;
31 import com.foxinmy.weixin4j.payment.mch.Order;
32 import com.foxinmy.weixin4j.payment.mch.PrePay;
33 import com.foxinmy.weixin4j.payment.mch.RefundRecord;
34 import com.foxinmy.weixin4j.payment.mch.RefundResult;
35 import com.foxinmy.weixin4j.payment.mch.SceneInfoApp;
36 import com.foxinmy.weixin4j.payment.mch.SceneInfoStore;
37 import com.foxinmy.weixin4j.payment.mch.WAPPayRequest;
38 import com.foxinmy.weixin4j.type.CurrencyType;
39 import com.foxinmy.weixin4j.type.IdQuery;
40 import com.foxinmy.weixin4j.type.IdType;
41 import com.foxinmy.weixin4j.type.SignType;
42 import com.foxinmy.weixin4j.type.TarType;
43 import com.foxinmy.weixin4j.type.TradeType;
44 import com.foxinmy.weixin4j.type.mch.BillType;
45 import com.foxinmy.weixin4j.type.mch.RefundAccountType;
46 import com.foxinmy.weixin4j.util.Consts;
47 import com.foxinmy.weixin4j.util.DateUtil;
48 import com.foxinmy.weixin4j.util.DigestUtil;
49 import com.foxinmy.weixin4j.util.IOUtil;
50 import com.foxinmy.weixin4j.util.MapUtil;
51 import com.foxinmy.weixin4j.util.RandomUtil;
52 import com.foxinmy.weixin4j.util.StringUtil;
53 import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
54 import com.foxinmy.weixin4j.xml.XmlStream;
55
56
57
58
59
60
61
62
63
64
65 @Deprecated
66 public class PayApi extends MchApi {
67
68 public PayApi(WeixinPayAccount weixinAccount) {
69 super(weixinAccount);
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public PrePay createPrePay(MchPayPackage payPackage) throws WeixinException {
87 super.declareMerchant(payPackage);
88 payPackage.setSign(weixinSignature.sign(payPackage));
89 String payJsRequestXml = XmlStream.toXML(payPackage);
90 WeixinResponse response = weixinExecutor.post(
91 getRequestUri("order_create_uri"), payJsRequestXml);
92 return response.getAsObject(new TypeReference<PrePay>() {
93 });
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public MchPayRequest createPayRequest(MchPayPackage payPackage)
110 throws WeixinException {
111 if (StringUtil.isBlank(payPackage.getTradeType())) {
112 throw new WeixinException("tradeType not be empty");
113 }
114 String tradeType = payPackage.getTradeType().toUpperCase();
115 if (TradeType.MICROPAY.name().equals(tradeType)) {
116 MchPayPackage _payPackage = new MchPayPackage(payPackage.getBody(),
117 payPackage.getDetail(), payPackage.getOutTradeNo(),
118 DateUtil.formatFee2Yuan(payPackage.getTotalFee()), null,
119 null, payPackage.getCreateIp(), null, null,
120 payPackage.getAuthCode(), null, payPackage.getAttach(),
121 null, null, payPackage.getGoodsTag(),
122 payPackage.getLimitPay(), payPackage.getSubAppId());
123 super.declareMerchant(_payPackage);
124 _payPackage.setSign(weixinSignature.sign(_payPackage));
125 String para = XmlStream.toXML(_payPackage);
126 WeixinResponse response = weixinExecutor.post(
127 getRequestUri("micropay_uri"), para);
128 MICROPayRequest microPayRequest = response
129 .getAsObject(new TypeReference<MICROPayRequest>() {
130 });
131 microPayRequest.setPaymentAccount(weixinAccount);
132 return microPayRequest;
133 }
134 PrePay prePay = createPrePay(payPackage);
135 if (TradeType.APP.name().equals(tradeType)) {
136 return new APPPayRequest(prePay.getPrepayId(), weixinAccount);
137 } else if (TradeType.JSAPI.name().equals(tradeType)) {
138 return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
139 } else if (TradeType.NATIVE.name().equals(tradeType)) {
140 return new NATIVEPayRequest(prePay.getPrepayId(),
141 prePay.getPayUrl(), weixinAccount);
142 } else if (TradeType.MWEB.name().equals(tradeType)) {
143 return new WAPPayRequest(prePay.getPrepayId(), prePay.getPayUrl(),
144 weixinAccount);
145 } else {
146 throw new WeixinException("unknown tradeType:" + tradeType);
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 public MchPayRequest createJSPayRequest(String openId, String body,
172 String outTradeNo, double totalFee, String notifyUrl,
173 String createIp, String attach) throws WeixinException {
174 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
175 totalFee, notifyUrl, createIp, TradeType.JSAPI, openId, null,
176 null, attach);
177 return createPayRequest(payPackage);
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 public String createAddressRequestJSON(String url, String oauthToken) {
201 Map<String, String> map = new HashMap<String, String>();
202 map.put("appId", weixinAccount.getId());
203 map.put("timeStamp", DateUtil.timestamp2string());
204 map.put("nonceStr", RandomUtil.generateString(16));
205 map.put("url", url);
206 map.put("accessToken", oauthToken);
207 String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true));
208 map.remove("url");
209 map.remove("accessToken");
210 map.put("scope", "jsapi_address");
211 map.put("signType", SignType.SHA1.name().toLowerCase());
212 map.put("addrSign", sign);
213 return JSON.toJSONString(map);
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 public String createNativePayRequest(String productId) {
230 Map<String, String> map = new HashMap<String, String>();
231 String timestamp = DateUtil.timestamp2string();
232 String noncestr = RandomUtil.generateString(16);
233 map.put("appid", weixinAccount.getId());
234 map.put("mch_id", weixinAccount.getMchId());
235 map.put("time_stamp", timestamp);
236 map.put("nonce_str", noncestr);
237 map.put("product_id", productId);
238 String sign = weixinSignature.sign(map);
239 return String.format(getRequestUri("native_pay_uri"), sign,
240 weixinAccount.getId(), weixinAccount.getMchId(), productId,
241 timestamp, noncestr);
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 public NativePayResponse createNativePayResponse(String productId,
272 String body, String outTradeNo, double totalFee, String notifyUrl,
273 String createIp, String attach) throws WeixinException {
274 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
275 totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
276 productId, attach);
277 PrePay prePay = createPrePay(payPackage);
278 return new NativePayResponse(weixinAccount, prePay.getPrepayId());
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 public MchPayRequest createNativePayRequest(String productId, String body,
309 String outTradeNo, double totalFee, String notifyUrl,
310 String createIp, String attach) throws WeixinException {
311 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
312 totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
313 productId, attach);
314 return createPayRequest(payPackage);
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 public MchPayRequest createAppPayRequest(String body, String outTradeNo,
343 double totalFee, String notifyUrl, String createIp, String attach,
344 SceneInfoStore store) throws WeixinException {
345 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
346 totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
347 attach);
348 if (store != null) {
349 payPackage.setSceneInfo(String.format(
350 "{\"store_id\": \"%s\", \"store_name\":\"%s\"}",
351 store.getId(), store.getName()));
352 }
353 return createPayRequest(payPackage);
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 public MchPayRequest createWapPayRequest(String body, String outTradeNo,
383 double totalFee, String notifyUrl, String createIp, String attach,
384 SceneInfoApp app) throws WeixinException {
385 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
386 totalFee, notifyUrl, createIp, TradeType.MWEB, null, null,
387 null, attach);
388 if (app != null) {
389 payPackage.setSceneInfo(String.format("{\"h5_info\":\"%s\"}",
390 app.getSceneInfo()));
391 }
392 return createPayRequest(payPackage);
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 public MchPayRequest createMicroPayRequest(String authCode, String body,
422 String outTradeNo, double totalFee, String createIp, String attach,
423 SceneInfoStore store) throws WeixinException {
424 MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
425 totalFee, null, createIp, TradeType.MICROPAY, null, authCode,
426 null, attach);
427 if (store != null) {
428 payPackage.setSceneInfo(String.format("{\"store_info\":\"%s\"}",
429 JSON.toJSONString(store)));
430 }
431 return createPayRequest(payPackage);
432 }
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 public Order queryOrder(IdQuery idQuery) throws WeixinException {
453 Map<String, String> map = createBaseRequestMap(idQuery);
454 map.put("sign", weixinSignature.sign(map));
455 String param = XmlStream.map2xml(map);
456 WeixinResponse response = weixinExecutor.post(
457 getRequestUri("order_query_uri"), param);
458 return ListsuffixResultDeserializer.deserialize(response.getAsString(),
459 Order.class);
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 public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
510 double totalFee, double refundFee, CurrencyType refundFeeType,
511 String opUserId, String refundDesc,
512 RefundAccountType refundAccountType) throws WeixinException {
513 Map<String, String> map = createBaseRequestMap(idQuery);
514 map.put("out_refund_no", outRefundNo);
515 map.put("total_fee",
516 Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
517 map.put("refund_fee",
518 Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
519 if (StringUtil.isBlank(opUserId)) {
520 opUserId = weixinAccount.getMchId();
521 }
522 map.put("op_user_id", opUserId);
523 if (refundFeeType == null) {
524 refundFeeType = CurrencyType.CNY;
525 }
526 if (refundAccountType == null) {
527 refundAccountType = RefundAccountType.REFUND_SOURCE_UNSETTLED_FUNDS;
528 }
529 if (StringUtil.isNotBlank(refundDesc)) {
530 map.put("refund_desc", refundDesc);
531 }
532 map.put("refund_fee_type", refundFeeType.name());
533 map.put("refund_account", refundAccountType.name());
534 map.put("sign", weixinSignature.sign(map));
535 String param = XmlStream.map2xml(map);
536 WeixinResponse response = getWeixinSSLExecutor().post(
537 getRequestUri("refund_apply_uri"), param);
538 return response.getAsObject(new TypeReference<RefundResult>() {
539 });
540 }
541
542
543
544
545
546
547
548
549
550
551
552
553
554 public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
555 double totalFee) throws WeixinException {
556 return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null,
557 null, null, null);
558 }
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573 public MerchantResult reverseOrder(IdQuery idQuery) throws WeixinException {
574 Map<String, String> map = createBaseRequestMap(idQuery);
575 map.put("sign", weixinSignature.sign(map));
576 String param = XmlStream.map2xml(map);
577 WeixinResponse response = getWeixinSSLExecutor().post(
578 getRequestUri("order_reverse_uri"), param);
579 return response.getAsObject(new TypeReference<MerchantResult>() {
580 });
581 }
582
583
584
585
586
587
588
589
590
591
592
593
594
595 public String getShorturl(String url) throws WeixinException {
596 Map<String, String> map = createBaseRequestMap(null);
597 try {
598 map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name()));
599 } catch (UnsupportedEncodingException e) {
600 ;
601 }
602 map.put("sign", weixinSignature.sign(map));
603 String param = XmlStream.map2xml(map);
604 WeixinResponse response = weixinExecutor.post(
605 getRequestUri("longurl_convert_uri"), param);
606 map = XmlStream.xml2map(response.getAsString());
607 return map.get("short_url");
608 }
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626 public MerchantResult closeOrder(String outTradeNo) throws WeixinException {
627 Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo,
628 IdType.TRADENO));
629 map.put("sign", weixinSignature.sign(map));
630 String param = XmlStream.map2xml(map);
631 WeixinResponse response = weixinExecutor.post(
632 getRequestUri("order_close_uri"), param);
633 return response.getAsObject(new TypeReference<MerchantResult>() {
634 });
635 }
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659 public void downloadBill(Date billDate, BillType billType,
660 OutputStream outputStream, TarType tarType) throws WeixinException {
661 if (billDate == null) {
662 Calendar now = Calendar.getInstance();
663 now.add(Calendar.DAY_OF_MONTH, -1);
664 billDate = now.getTime();
665 }
666 if (billType == null) {
667 billType = BillType.ALL;
668 }
669 String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
670 Map<String, String> map = createBaseRequestMap(null);
671 map.put("bill_date", formatBillDate);
672 map.put("bill_type", billType.name());
673 if (tarType != null) {
674 map.put("tar_type", tarType.name());
675 }
676 map.put("sign", weixinSignature.sign(map));
677 String param = XmlStream.map2xml(map);
678 WeixinResponse response = weixinExecutor.post(
679 getRequestUri("downloadbill_uri"), param);
680
681 if (TarType.GZIP == tarType) {
682 try {
683 IOUtil.copy(response.getBody(), outputStream);
684 } catch (IOException e) {
685 ;
686 }
687 } else {
688 BufferedReader reader = null;
689 BufferedWriter writer = null;
690 try {
691 writer = new BufferedWriter(new OutputStreamWriter(
692 outputStream, Consts.UTF_8));
693 reader = new BufferedReader(new InputStreamReader(
694 response.getBody(), Consts.UTF_8));
695 String line = null;
696 while ((line = reader.readLine()) != null) {
697 writer.write(line);
698 writer.newLine();
699 }
700 } catch (IOException e) {
701 throw new WeixinException(e);
702 } finally {
703 try {
704 if (reader != null) {
705 reader.close();
706 }
707 if (writer != null) {
708 writer.close();
709 }
710 } catch (IOException ignore) {
711 ;
712 }
713 }
714 }
715 }
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737 public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException {
738 Map<String, String> map = createBaseRequestMap(idQuery);
739 map.put("sign", weixinSignature.sign(map));
740 String param = XmlStream.map2xml(map);
741 WeixinResponse response = weixinExecutor.post(
742 getRequestUri("refund_query_uri"), param);
743 return ListsuffixResultDeserializer.deserialize(response.getAsString(),
744 RefundRecord.class);
745 }
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769 @SuppressWarnings("unchecked")
770 public XmlResult reportInterface(String interfaceUrl, int executeTime,
771 String outTradeNo, String ip, Date time, XmlResult returnXml)
772 throws WeixinException {
773 Map<String, String> map = createBaseRequestMap(null);
774 map.put("interface_url", interfaceUrl);
775 map.put("execute_time_", Integer.toString(executeTime));
776 map.put("out_trade_no", outTradeNo);
777 map.put("user_ip", ip);
778 map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time));
779 map.putAll((Map<String, String>) JSON.toJSON(returnXml));
780 map.put("sign", weixinSignature.sign(map));
781 String param = XmlStream.map2xml(map);
782 WeixinResponse response = weixinExecutor.post(
783 getRequestUri("interface_report_uri"), param);
784 return response.getAsXml();
785 }
786
787
788
789
790
791
792
793
794
795
796
797
798
799 public OpenIdResult authCode2openId(String authCode) throws WeixinException {
800 Map<String, String> map = createBaseRequestMap(null);
801 map.put("auth_code", authCode);
802 map.put("sign", weixinSignature.sign(map));
803 String param = XmlStream.map2xml(map);
804 WeixinResponse response = weixinExecutor.post(
805 getRequestUri("authcode_openid_uri"), param);
806 return response.getAsObject(new TypeReference<OpenIdResult>() {
807 });
808 }
809 }