UnifiedOrderBusiness.java 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package com.tencent.business;
  2. import com.tencent.common.Configure;
  3. import com.tencent.common.Log;
  4. import com.tencent.common.Signature;
  5. import com.tencent.common.Util;
  6. import com.tencent.common.report.ReporterFactory;
  7. import com.tencent.common.report.protocol.ReportReqData;
  8. import com.tencent.common.report.service.ReportService;
  9. import com.tencent.protocol.pay_protocol.UnifiedOrderReqData;
  10. import com.tencent.protocol.pay_protocol.UnifiedOrderResData;
  11. import com.tencent.service.UnifiedOrderService;
  12. import org.slf4j.LoggerFactory;
  13. /**
  14. * User: gaojie
  15. * Date: 2017/05/10
  16. * Time: 16:42
  17. */
  18. public class UnifiedOrderBusiness {
  19. public UnifiedOrderBusiness() throws IllegalAccessException, ClassNotFoundException, InstantiationException {
  20. unifiedOrderService = new UnifiedOrderService();
  21. }
  22. public interface ResultListener {
  23. //API返回ReturnCode不合法,支付请求逻辑错误,请仔细检测传过去的每一个参数是否合法,或是看API能否被正常访问
  24. void onFailByReturnCodeError(UnifiedOrderResData unifiedOrderResData);
  25. //API返回ReturnCode为FAIL,支付API系统返回失败,请检测Post给API的数据是否规范合法
  26. void onFailByReturnCodeFail(UnifiedOrderResData unifiedOrderResData);
  27. //支付请求API返回的数据签名验证失败,有可能数据被篡改了
  28. void onFailBySignInvalid(UnifiedOrderResData unifiedOrderResData);
  29. //用户用来支付的二维码已经过期,提示收银员重新扫一下用户微信“刷卡”里面的二维码
  30. void onFailByAuthCodeExpire(UnifiedOrderResData unifiedOrderResData);
  31. //授权码无效,提示用户刷新一维码/二维码,之后重新扫码支付"
  32. void onFailByAuthCodeInvalid(UnifiedOrderResData unifiedOrderResData);
  33. //用户余额不足,换其他卡支付或是用现金支付
  34. void onFailByMoneyNotEnough(UnifiedOrderResData unifiedOrderResData);
  35. //支付失败
  36. void onFail(UnifiedOrderResData unifiedOrderResData);
  37. //支付成功
  38. void onSuccess(UnifiedOrderResData unifiedOrderResData);
  39. }
  40. //打log用
  41. private static Log log = new Log(LoggerFactory.getLogger(UnifiedOrderBusiness.class));
  42. private UnifiedOrderService unifiedOrderService;
  43. /**
  44. * 直接执行被扫支付业务逻辑(包含最佳实践流程)
  45. *
  46. * @param unifiedOrderReqData 这个数据对象里面包含了API要求提交的各种数据字段
  47. * @param resultListener 商户需要自己监听被扫支付业务逻辑可能触发的各种分支事件,并做好合理的响应处理
  48. * @throws Exception
  49. */
  50. public void run(UnifiedOrderReqData unifiedOrderReqData, ResultListener resultListener) throws Exception {
  51. //--------------------------------------------------------------------
  52. //构造请求“被扫支付API”所需要提交的数据
  53. //--------------------------------------------------------------------
  54. String outTradeNo = unifiedOrderReqData.getOut_trade_no();
  55. //接受API返回
  56. String payServiceResponseString;
  57. long costTimeStart = System.currentTimeMillis();
  58. log.i("支付API返回的数据如下:");
  59. payServiceResponseString = unifiedOrderService.request(unifiedOrderReqData);
  60. long costTimeEnd = System.currentTimeMillis();
  61. long totalTimeCost = costTimeEnd - costTimeStart;
  62. log.i("api请求总耗时:" + totalTimeCost + "ms");
  63. //打印回包数据
  64. log.i(payServiceResponseString);
  65. //将从API返回的XML数据映射到Java对象
  66. UnifiedOrderResData unifiedOrderResData = (UnifiedOrderResData) Util.getObjectFromXML(payServiceResponseString, UnifiedOrderResData.class);
  67. //异步发送统计请求
  68. //*
  69. ReportReqData reportReqData = new ReportReqData(
  70. unifiedOrderResData.getDevice_info(),
  71. Configure.UNIFIED_ORDER_API,
  72. (int) (totalTimeCost),//本次请求耗时
  73. unifiedOrderResData.getReturn_code(),
  74. unifiedOrderResData.getReturn_msg(),
  75. unifiedOrderResData.getResult_code(),
  76. unifiedOrderResData.getErr_code(),
  77. unifiedOrderResData.getErr_code_des(),
  78. "",
  79. unifiedOrderReqData.getSpbill_create_ip()
  80. );
  81. long timeAfterReport;
  82. if (Configure.isUseThreadToDoReport()) {
  83. ReporterFactory.getReporter(reportReqData).run();
  84. timeAfterReport = System.currentTimeMillis();
  85. log.i("pay+report总耗时(异步方式上报):" + (timeAfterReport - costTimeStart) + "ms");
  86. } else {
  87. ReportService.request(reportReqData);
  88. timeAfterReport = System.currentTimeMillis();
  89. log.i("pay+report总耗时(同步方式上报):" + (timeAfterReport - costTimeStart) + "ms");
  90. }
  91. if (unifiedOrderResData == null || unifiedOrderResData.getReturn_code() == null) {
  92. log.e("【支付失败】支付请求逻辑错误,请仔细检测传过去的每一个参数是否合法,或是看API能否被正常访问");
  93. resultListener.onFailByReturnCodeError(unifiedOrderResData);
  94. return;
  95. }
  96. if (unifiedOrderResData.getReturn_code().equals("FAIL")) {
  97. //注意:一般这里返回FAIL是出现系统级参数错误,请检测Post给API的数据是否规范合法
  98. log.e("【支付失败】支付API系统返回失败,请检测Post给API的数据是否规范合法");
  99. resultListener.onFailByReturnCodeFail(unifiedOrderResData);
  100. return;
  101. } else {
  102. log.i("支付API系统成功返回数据");
  103. //--------------------------------------------------------------------
  104. //收到API的返回数据的时候得先验证一下数据有没有被第三方篡改,确保安全
  105. //--------------------------------------------------------------------
  106. if (!Signature.checkIsSignValidFromResponseString(payServiceResponseString)) {
  107. log.e("【支付失败】支付请求API返回的数据签名验证失败,有可能数据被篡改了");
  108. resultListener.onFailBySignInvalid(unifiedOrderResData);
  109. return;
  110. }
  111. //获取错误码
  112. String errorCode = unifiedOrderResData.getErr_code();
  113. //获取错误描述
  114. String errorCodeDes = unifiedOrderResData.getErr_code_des();
  115. if (unifiedOrderResData.getResult_code().equals("SUCCESS")) {
  116. //--------------------------------------------------------------------
  117. //1)直接扣款成功
  118. //--------------------------------------------------------------------
  119. log.i("【提交成功】");
  120. resultListener.onSuccess(unifiedOrderResData);
  121. }else{
  122. //出现业务错误
  123. log.i("业务返回失败");
  124. log.i("err_code:" + errorCode);
  125. log.i("err_code_des:" + errorCodeDes);
  126. }
  127. }
  128. }
  129. public void setScanPayService(UnifiedOrderService service) {
  130. unifiedOrderService = service;
  131. }
  132. }