PayUtils.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. package com.tendbird.payserver.pay.service;
  2. import com.fasterxml.jackson.databind.node.ObjectNode;
  3. import com.tendbird.payserver.pay.domain.PayConfig;
  4. import com.tendbird.payserver.pay.domain.PayOrder;
  5. import com.tendpay.sdk.Tendpay;
  6. import com.tendpay.sdk.TendpayClient;
  7. import com.tendpay.sdk.exception.PayException;
  8. import com.tendpay.sdk.model.PayOrderCreateReqModel;
  9. import com.tendpay.sdk.model.PayOrderQueryReqModel;
  10. import com.tendpay.sdk.model.RefundOrderCreateReqModel;
  11. import com.tendpay.sdk.model.RefundOrderQueryReqModel;
  12. import com.tendpay.sdk.request.PayOrderCreateRequest;
  13. import com.tendpay.sdk.request.PayOrderQueryRequest;
  14. import com.tendpay.sdk.request.RefundOrderCreateRequest;
  15. import com.tendpay.sdk.request.RefundOrderQueryRequest;
  16. import com.tendpay.sdk.response.PayOrderCreateResponse;
  17. import com.tendpay.sdk.response.PayOrderQueryResponse;
  18. import com.tendpay.sdk.response.RefundOrderCreateResponse;
  19. import com.tendpay.sdk.response.RefundOrderQueryResponse;
  20. import com.tendpay.sdk.util.JacksonUtil;
  21. import lombok.extern.slf4j.Slf4j;
  22. import org.springframework.util.ObjectUtils;
  23. @Slf4j
  24. public class PayUtils {
  25. private static final int maxQueryRetry = 20;
  26. //统一下单
  27. public static PayOrderCreateResponse doTradePay(PayConfig payConfig, PayOrder payOrder) throws Exception {
  28. Tendpay.setApiBase(payConfig.getApiUrl());
  29. Tendpay.apiKey = payConfig.getApiKey();
  30. Tendpay.mchNo = payConfig.getMchNo();
  31. Tendpay.appId = payConfig.getAppid();
  32. TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase());
  33. PayOrderCreateRequest request = new PayOrderCreateRequest();
  34. PayOrderCreateReqModel model = new PayOrderCreateReqModel();
  35. model.setMchNo(Tendpay.mchNo); // 商户号
  36. model.setAppId(tendpayClient.getAppId()); // 应用ID
  37. model.setMchOrderNo(payOrder.getMchOrderNo()); // 商户订单号
  38. model.setWayCode(payOrder.getWayCode()); // 支付方式
  39. model.setAmount(payOrder.getAmount()); // 金额,单位分
  40. model.setCurrency(payOrder.getCurrency()); // 币种,目前只支持cny
  41. model.setClientIp("127.0.0.1"); // 发起支付请求客户端的IP地址
  42. model.setSubject(payOrder.getSubject()); // 商品标题
  43. model.setBody(payOrder.getBody()); // 商品描述
  44. model.setNotifyUrl(payConfig.getNotifyUrl()); // 异步通知地址
  45. model.setReturnUrl(payConfig.getReturnUrl()); // 前端跳132457558789533910
  46. // 转地址
  47. model.setChannelExtra(channelExtra(payOrder.getWayCode(), payOrder.getAuthCode())); // 渠道扩展参数
  48. model.setExtParam(payOrder.getExtParam()); // 商户扩展参数,回调时原样返回
  49. request.setBizModel(model);
  50. try {
  51. PayOrderCreateResponse response = tendpayClient.execute(request);
  52. log.info("交易信息:{}", response);
  53. // 下单成功
  54. if (response.isSuccess(Tendpay.apiKey)) {
  55. return response;
  56. } else {
  57. throw new Exception(response.getMessage());
  58. }
  59. } catch (PayException e) {
  60. throw new Exception(e.getMessage());
  61. }
  62. }
  63. //轮循交易状态
  64. public static PayOrderQueryResponse doTradePayQuery(PayConfig payConfig, String orderNo, String orderId) throws Exception {
  65. for (int i = 0; i < maxQueryRetry; i++) {
  66. PayOrderQueryResponse orderQueryResponse = doTradePayQuerying(payConfig, orderNo, orderId);
  67. if (!ObjectUtils.isEmpty(orderQueryResponse)) {
  68. int state = orderQueryResponse.get().getState();
  69. switch (state) {
  70. case PayOrder.STATE_ORDER_SUCCESS:
  71. case PayOrder.STATE_ORDER_FAIL:
  72. case PayOrder.STATE_ORDER_REVERSE:
  73. case PayOrder.STATE_ORDER_CLOSED:
  74. case PayOrder.STATE_ORDER_REFUND:
  75. return orderQueryResponse;
  76. default:
  77. break;
  78. }
  79. }
  80. Thread.sleep(3000);
  81. }
  82. return null;
  83. }
  84. //交易状态查询
  85. public static PayOrderQueryResponse doTradePayQuerying(PayConfig payConfig, String orderNo, String orderId) throws Exception {
  86. Tendpay.setApiBase(payConfig.getApiUrl());
  87. Tendpay.apiKey = payConfig.getApiKey();
  88. Tendpay.mchNo = payConfig.getMchNo();
  89. Tendpay.appId = payConfig.getAppid();
  90. TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase());
  91. PayOrderQueryRequest request = new PayOrderQueryRequest();
  92. PayOrderQueryReqModel model = new PayOrderQueryReqModel();
  93. model.setMchNo(Tendpay.mchNo); // 商户号
  94. model.setAppId(tendpayClient.getAppId()); // 应用ID
  95. model.setMchOrderNo(orderNo); //商户订单号
  96. model.setPayOrderId(orderId); //支付订单号
  97. request.setBizModel(model);
  98. try {
  99. PayOrderQueryResponse response = tendpayClient.execute(request);
  100. if (response.isSuccess(Tendpay.apiKey)) {
  101. return response;
  102. } else {
  103. throw new Exception(response.getMessage());
  104. }
  105. } catch (PayException e) {
  106. throw new Exception(e.getMessage());
  107. }
  108. }
  109. //退款交易
  110. public static RefundOrderCreateResponse doTradePayRefund(PayConfig payConfig, PayOrder payOrder) throws Exception {
  111. Tendpay.setApiBase(payConfig.getApiUrl());
  112. Tendpay.apiKey = payConfig.getApiKey();
  113. Tendpay.mchNo = payConfig.getMchNo();
  114. Tendpay.appId = payConfig.getAppid();
  115. TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase());
  116. RefundOrderCreateRequest request = new RefundOrderCreateRequest();
  117. RefundOrderCreateReqModel model = new RefundOrderCreateReqModel();
  118. model.setMchNo(Tendpay.mchNo); // 商户号
  119. model.setAppId(tendpayClient.getAppId()); // 应用ID
  120. if (payOrder.getFlag() == 0) {
  121. model.setMchOrderNo(payOrder.getAuthCode()); // 商户支付单号(与支付订单号二者传一)
  122. } else {
  123. model.setPayOrderId(payOrder.getAuthCode()); //支付订单号(与商户支付单号二者传一)
  124. }
  125. model.setMchRefundNo(payOrder.getMchOrderNo()); // 商户退款单号
  126. model.setRefundAmount(payOrder.getAmount()); // 退款金额,单位分
  127. model.setCurrency(payOrder.getCurrency()); // 币种,目前只支持cny
  128. model.setClientIp("127.0.0.1"); // 发起支付请求客户端的IP地址
  129. model.setRefundReason(payOrder.getReason()); // 退款原因
  130. model.setNotifyUrl(payConfig.getNotifyUrl()); // 异步通知地址
  131. model.setChannelExtra(payOrder.getChannelExtra()); // 渠道扩展参数
  132. model.setExtParam(payOrder.getExtParam()); // 商户扩展参数,回调时原样返回
  133. request.setBizModel(model);
  134. try {
  135. RefundOrderCreateResponse response = tendpayClient.execute(request);
  136. log.info("退款交易:{}", response);
  137. // 判断退款发起是否成功(并不代表退款成功)
  138. if (response.isSuccess(Tendpay.apiKey)) {
  139. String refundOrderId = response.get().getRefundOrderId();
  140. String mchRefundNo = response.get().getMchRefundNo();
  141. return response;
  142. } else {
  143. throw new Exception(response.getMessage());
  144. }
  145. } catch (PayException e) {
  146. throw new Exception(e.getMessage());
  147. }
  148. }
  149. //轮循退款状态
  150. public static RefundOrderQueryResponse doRefundPayQuery(PayConfig payConfig, String orderNo, String orderId) throws Exception {
  151. Thread.sleep(1000);
  152. for (int i = 0; i < maxQueryRetry; i++) {
  153. RefundOrderQueryResponse response = doRefundPayQuerying(payConfig, orderNo, orderId);
  154. if (response != null) {
  155. int state = response.get().getState();
  156. switch (state) {
  157. case PayOrder.STATE_REFUND_SUCCESS:
  158. case PayOrder.STATE_REFUND_FAIL:
  159. case PayOrder.STATE_REFUND_CLOSED:
  160. return response;
  161. default:
  162. break;
  163. }
  164. }
  165. Thread.sleep(3000);
  166. }
  167. return null;
  168. }
  169. //查询退款状态
  170. public static RefundOrderQueryResponse doRefundPayQuerying(PayConfig payConfig, String orderNo, String orderId) throws Exception {
  171. TendpayClient tendpayClient = TendpayClient.getInstance(payConfig.getAppid(), payConfig.getApiKey(), payConfig.getApiUrl());
  172. RefundOrderQueryRequest request = new RefundOrderQueryRequest();
  173. RefundOrderQueryReqModel model = new RefundOrderQueryReqModel();
  174. model.setMchNo(payConfig.getMchNo()); // 商户号
  175. model.setAppId(tendpayClient.getAppId()); // 应用ID
  176. model.setMchRefundNo(orderNo); //商户退款单号
  177. model.setRefundOrderId(orderId); // 退款单号
  178. request.setBizModel(model);
  179. try {
  180. RefundOrderQueryResponse response = tendpayClient.execute(request);
  181. if (response.isSuccess(Tendpay.apiKey)) {
  182. return response;
  183. } else {
  184. throw new Exception(response.getMessage());
  185. }
  186. } catch (PayException e) {
  187. throw new Exception(e.getMessage());
  188. }
  189. }
  190. private static String channelExtra(String wayCode, String data) {
  191. if ("WX_LITE".equals(wayCode)) return wxJsapiExtra(data);
  192. if ("WX_JSAPI".equals(wayCode)) return wxJsapiExtra(data);
  193. if ("WX_BAR".equals(wayCode)) return wxBarExtra(data);
  194. if ("ALI_BAR".equals(wayCode)) return aliBarExtra(data);
  195. if ("YSF_BAR".equals(wayCode)) return ysfBarExtra(data);
  196. if ("UPACP_BAR".equals(wayCode)) return upacpBarExtra(data);
  197. if ("QR_CASHIER".equals(wayCode)) return qrCashierExtra(data);
  198. if ("AUTO_BAR".equals(wayCode)) return autoBarExtra(data);
  199. if ("PP_PC".equals(wayCode)) return ppExtra(data);
  200. //if("SAND_H5".equals(wayCode)) return sandH5Extra();
  201. return "";
  202. }
  203. private static String wxJsapiExtra(String data) {
  204. ObjectNode obj = JacksonUtil.newObjectNode();
  205. obj.put("openId", data);
  206. return obj.toString();
  207. }
  208. private static String wxBarExtra(String data) {
  209. ObjectNode obj = JacksonUtil.newObjectNode();
  210. obj.put("authCode", data);
  211. return obj.toString();
  212. }
  213. private static String aliBarExtra(String data) {
  214. ObjectNode obj = JacksonUtil.newObjectNode();
  215. obj.put("authCode", data);
  216. return obj.toString();
  217. }
  218. private static String ysfBarExtra(String data) {
  219. ObjectNode obj = JacksonUtil.newObjectNode();
  220. obj.put("authCode", data);
  221. return obj.toString();
  222. }
  223. private static String upacpBarExtra(String data) {
  224. ObjectNode obj = JacksonUtil.newObjectNode();
  225. obj.put("authCode", data);
  226. return obj.toString();
  227. }
  228. private static String qrCashierExtra(String data) {
  229. ObjectNode obj = JacksonUtil.newObjectNode();
  230. obj.put("payDataType", data);
  231. return obj.toString();
  232. }
  233. private static String autoBarExtra(String data) {
  234. ObjectNode obj = JacksonUtil.newObjectNode();
  235. obj.put("authCode", data);
  236. return obj.toString();
  237. }
  238. private static String ppExtra(String data) {
  239. ObjectNode obj = JacksonUtil.newObjectNode();
  240. obj.put("cancelUrl", data);
  241. return obj.toString();
  242. }
  243. }