智能仲裁后端服务

AlipayElegentTrade.java 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. package com.ruoyi.ali;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.alipay.api.AlipayApiException;
  5. import com.alipay.api.AlipayClient;
  6. import com.alipay.api.DefaultAlipayClient;
  7. import com.alipay.api.request.*;
  8. import com.alipay.api.response.*;
  9. import com.ruoyi.CallBackService;
  10. import com.ruoyi.annotation.TradePlatform;
  11. import com.ruoyi.config.CallbackConfig;
  12. import com.ruoyi.constant.PayConstant;
  13. import com.ruoyi.constant.Platform;
  14. import com.ruoyi.constant.TradeType;
  15. import com.ruoyi.core.ElegentTrade;
  16. import com.ruoyi.dto.*;
  17. import com.ruoyi.exceptions.TradeException;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Service;
  21. import java.math.BigDecimal;
  22. import java.util.Map;
  23. /**
  24. * 支付宝支付的策略类
  25. * @author wgl
  26. */
  27. @Service
  28. @TradePlatform(Platform.ALI)
  29. @Slf4j
  30. public class AlipayElegentTrade implements ElegentTrade {
  31. @Autowired
  32. private AlipayConfig alipayConfig;
  33. @Autowired
  34. private CallbackConfig callbackConfig;
  35. @Autowired
  36. private CallBackService callBackService;
  37. /**
  38. * 获取回调地址
  39. * @return
  40. */
  41. private String getPayNotifyUrl(){
  42. return callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH+ PayConstant.NOTIFY +"/"+ Platform.ALI;
  43. }
  44. /**
  45. * 获取退款回调
  46. * @return
  47. */
  48. private String getRefundNotifyUrl(){
  49. return callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH+ PayConstant.REFUND_NOTIFY +"/"+ Platform.ALI;
  50. }
  51. /**
  52. * 创建支付订单
  53. * @param payRequest
  54. * @return
  55. * @throws TradeException
  56. */
  57. @Override
  58. public PayResponse requestPay(PayRequest payRequest, String tradeType) throws TradeException {
  59. if(TradeType.NATIVE.equals( tradeType )){
  60. return createNativeOrder(payRequest);
  61. }
  62. if(TradeType.JSAPI.equals( tradeType )){
  63. return createJsApiOrder(payRequest);
  64. }
  65. if(TradeType.H5.equals( tradeType )){
  66. return createH5Order(payRequest);
  67. }
  68. if(TradeType.APP.equals( tradeType )){
  69. return createAPPOrder(payRequest);
  70. }
  71. return createNativeOrder(payRequest);
  72. }
  73. /**
  74. * 本地支付(扫码)
  75. * https://opendocs.alipay.com/open/194/106078?ref=api#预下单
  76. * @param payRequest
  77. * @return
  78. * @throws TradeException
  79. */
  80. private PayResponse createNativeOrder(PayRequest payRequest) throws TradeException {
  81. try {
  82. AlipayClient alipayClient = getAliHttpClient();
  83. AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
  84. request.setNotifyUrl(getPayNotifyUrl());
  85. JSONObject bizContent = new JSONObject();
  86. bizContent.put("out_trade_no", payRequest.getOrderSn());
  87. //转换
  88. //String totalFee= BigDecimal.valueOf(payRequest.getTotalFee()).divide(new BigDecimal(100) ).toString();
  89. bizContent.put("total_amount", fenToYuan(payRequest.getTotalFee()));
  90. bizContent.put("subject", payRequest.getBody());
  91. request.setBizContent(bizContent.toString());
  92. AlipayTradePrecreateResponse response = alipayClient.execute(request);
  93. if (response.isSuccess()) {
  94. PayResponse payResponse =new PayResponse();
  95. payResponse.setSuccess(true);
  96. payResponse.setCode_url(response.getQrCode()); //本地支付二维码
  97. payResponse.setOrder_sn(payRequest.getOrderSn());
  98. return payResponse;
  99. } else {
  100. log.error("调用失败");
  101. return null;
  102. }
  103. }catch (Exception e){
  104. e.printStackTrace();
  105. throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
  106. }
  107. }
  108. /**
  109. * 小程序
  110. * https://opendocs.alipay.com/mini/03l5wn
  111. * @param payRequest
  112. * @return
  113. * @throws TradeException
  114. */
  115. private PayResponse createJsApiOrder(PayRequest payRequest) throws TradeException {
  116. AlipayClient alipayClient = getAliHttpClient();
  117. try {
  118. AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
  119. request.setNotifyUrl(getPayNotifyUrl());
  120. JSONObject bizContent = new JSONObject();
  121. bizContent.put("out_trade_no", payRequest.getOrderSn());
  122. bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
  123. bizContent.put("subject", payRequest.getBody());
  124. bizContent.put("buyer_id", payRequest.getOpenid());
  125. bizContent.put("timeout_express", "10m");
  126. request.setBizContent(bizContent.toString());
  127. AlipayTradeCreateResponse response = alipayClient.sdkExecute(request);
  128. if (response.isSuccess()) {
  129. PayResponse payResponse =new PayResponse();
  130. payResponse.setSuccess(true);
  131. payResponse.setPrepay_id(response.getTradeNo());
  132. payResponse.setOrder_sn(response.getOutTradeNo());
  133. return payResponse;
  134. } else {
  135. log.error("调用失败");
  136. return null;
  137. }
  138. }catch (Exception e){
  139. throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
  140. }
  141. }
  142. /**
  143. * H5
  144. * https://opendocs.alipay.com/mini/03l5wn
  145. * @param payRequest
  146. * @return
  147. * @throws TradeException
  148. */
  149. private PayResponse createH5Order(PayRequest payRequest) throws TradeException {
  150. AlipayClient alipayClient = getAliHttpClient();
  151. try {
  152. AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
  153. request.setNotifyUrl(getPayNotifyUrl());
  154. request.setReturnUrl("");
  155. JSONObject bizContent = new JSONObject();
  156. bizContent.put("out_trade_no", payRequest.getOrderSn());
  157. bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
  158. bizContent.put("subject", payRequest.getBody());
  159. bizContent.put("product_code", "QUICK_WAP_WAY");
  160. request.setBizContent(bizContent.toString());
  161. AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
  162. if (response.isSuccess()) {
  163. PayResponse payResponse =new PayResponse();
  164. payResponse.setSuccess(true);
  165. payResponse.setPrepay_id(response.getTradeNo());
  166. payResponse.setOrder_sn(response.getOutTradeNo());
  167. return payResponse;
  168. } else {
  169. log.error("调用失败");
  170. return null;
  171. }
  172. }catch (Exception e){
  173. throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
  174. }
  175. }
  176. /**
  177. * APP
  178. * https://opendocs.alipay.com/open/02e7gq?ref=api&scene=20
  179. * @param payRequest
  180. * @return
  181. * @throws TradeException
  182. */
  183. private PayResponse createAPPOrder(PayRequest payRequest) throws TradeException {
  184. AlipayClient alipayClient = getAliHttpClient();
  185. try {
  186. AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
  187. request.setNotifyUrl(getPayNotifyUrl());
  188. JSONObject bizContent = new JSONObject();
  189. bizContent.put("out_trade_no", payRequest.getOrderSn());
  190. bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
  191. bizContent.put("subject", payRequest.getBody());
  192. bizContent.put("product_code", "QUICK_MSECURITY_PAY");
  193. request.setBizContent(bizContent.toString());
  194. AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
  195. if (response.isSuccess()) {
  196. PayResponse payResponse =new PayResponse();
  197. payResponse.setSuccess(true);
  198. payResponse.setPrepay_id(response.getTradeNo());
  199. payResponse.setOrder_sn(response.getOutTradeNo());
  200. return payResponse;
  201. } else {
  202. log.error("调用失败");
  203. return null;
  204. }
  205. }catch (Exception e){
  206. throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
  207. }
  208. }
  209. /**
  210. * 关闭订单
  211. * @param orderSn
  212. * @return
  213. * @throws TradeException
  214. */
  215. @Override
  216. public Boolean closePay(String orderSn) throws TradeException {
  217. try {
  218. AlipayClient alipayClient = getAliHttpClient();
  219. AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
  220. JSONObject bizContent = new JSONObject();
  221. bizContent.put("trade_no", orderSn);
  222. request.setBizContent(bizContent.toString());
  223. AlipayTradeCloseResponse response = alipayClient.execute(request);
  224. if (response.isSuccess()) {
  225. log.info("调用成功");
  226. return true;
  227. } else {
  228. log.error("调用失败");
  229. return false;
  230. }
  231. }catch (Exception e){
  232. throw new TradeException("订单关闭失败,订单号:"+orderSn);
  233. }
  234. }
  235. /**
  236. * 退款接口
  237. * alipay.trade.refund(统一收单交易退款接口)
  238. * https://opendocs.alipay.com/open/02ekfk
  239. * @param refundRequest
  240. * @return
  241. * @throws TradeException
  242. */
  243. @Override
  244. public Boolean refund(RefundRequest refundRequest) throws TradeException {
  245. try {
  246. AlipayClient alipayClient = getAliHttpClient();
  247. AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
  248. request.setNotifyUrl(getRefundNotifyUrl()); //退款回调
  249. JSONObject bizContent = new JSONObject();
  250. bizContent.put("refund_amount", fenToYuan(refundRequest.getRefundAmount() ));
  251. bizContent.put("out_trade_no", refundRequest.getOrderSn());
  252. //退款请求号,做幂等性校验
  253. if(refundRequest.getRequestNo()!=null){
  254. bizContent.put("out_request_no", refundRequest.getRequestNo());
  255. }else{
  256. bizContent.put("out_request_no", refundRequest.getOrderSn());
  257. }
  258. request.setBizContent(bizContent.toString());
  259. AlipayTradeRefundResponse response = alipayClient.execute(request);
  260. if (response.isSuccess()) {
  261. if("Y".equals(response.getFundChange())) {
  262. log.info("退款成功{}",refundRequest.getOrderSn());
  263. callBackService.successRefund(refundRequest.getOrderSn());
  264. return true;
  265. }else{
  266. //退款失败
  267. log.error("退款失败{}",refundRequest.getOrderSn());
  268. callBackService.failRefund(refundRequest.getOrderSn());
  269. return false;
  270. }
  271. } else {
  272. log.error("退款调用失败{}",refundRequest.getOrderSn());
  273. return false;
  274. }
  275. }catch (Exception e){
  276. e.printStackTrace();
  277. throw new TradeException("订单退款失败,订单号:"+ refundRequest.getOrderSn());
  278. }
  279. }
  280. /**
  281. * 查询单笔交易订单
  282. * 参考官网: https://opendocs.alipay.com/open/02e7gm?ref=api#请求示例
  283. *
  284. * @param orderSn
  285. * @return
  286. * @throws TradeException
  287. */
  288. @Override
  289. public QueryResponse queryTradingOrderNo(String orderSn) throws TradeException {
  290. AlipayClient alipayClient = getAliHttpClient();
  291. try {
  292. AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
  293. JSONObject bizContent = new JSONObject();
  294. bizContent.put("out_trade_no", orderSn);
  295. request.setBizContent(bizContent.toString());
  296. AlipayTradeQueryResponse response = alipayClient.execute(request);
  297. QueryResponse queryResponse=new QueryResponse();
  298. queryResponse.setOrder_sn(orderSn );
  299. if (response.isSuccess()) {
  300. queryResponse.setTransaction_id( response.getTradeNo() );
  301. queryResponse.setTrade_state(AlipayConstant.TRADE_STATE.get( response.getTradeStatus()) );//交易状态
  302. //int total = BigDecimal.valueOf(Double.valueOf(response.getTotalAmount())).multiply(new BigDecimal(100)).intValue();
  303. queryResponse.setTotal( yuanToFen(response.getTotalAmount()) ); //总金额
  304. //int buyer_pay_amount = BigDecimal.valueOf(Double.valueOf(response.getBuyerPayAmount())).multiply(new BigDecimal(100)).intValue();
  305. //queryResponse.setPayer_total( yuanToFen(response.getBuyerPayAmount()) );//支付金额
  306. queryResponse.setOpenid( response.getBuyerUserId());
  307. Map map = JSON.parseObject(response.getBody(), Map.class ) ;
  308. queryResponse.setExpand(map);//全部数据
  309. return queryResponse;
  310. } else {
  311. queryResponse.setTrade_state("NOTPAY");
  312. return queryResponse;
  313. }
  314. }catch (Exception e){
  315. e.printStackTrace();
  316. //throw new TradeException("订单查询失败,订单号:"+orderSn);
  317. return null;
  318. }
  319. }
  320. /**
  321. * 查询退款订单
  322. * @param orderSn
  323. * @return
  324. * @throws TradeException
  325. */
  326. @Override
  327. public QueryRefundResponse queryRefundTrading(String orderSn) throws TradeException {
  328. try {
  329. AlipayClient alipayClient = getAliHttpClient();
  330. AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
  331. JSONObject bizContent = new JSONObject();
  332. bizContent.put("out_request_no", orderSn);
  333. request.setBizContent(bizContent.toString());
  334. AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
  335. if (response.isSuccess()) {
  336. log.info("调用成功");
  337. Map map = JSON.parseObject(response.getBody(), Map.class );
  338. QueryRefundResponse queryRefundResponse=new QueryRefundResponse();
  339. queryRefundResponse.setOrder_sn( (String) map.get("out_trade_no") );
  340. queryRefundResponse.setTransaction_id( (String) map.get("trade_no") );
  341. queryRefundResponse.setTotal( (Integer) map.get("total_amount") ); //总金额
  342. //queryRefundResponse.setPayer_total( (Integer) map.get("total_amount") );//支付金额
  343. queryRefundResponse.setRefund((Integer) map.get("refund_amount") ); //退款金额
  344. queryRefundResponse.setRefund_id((String) map.get("trade_no") ); //退款单号
  345. queryRefundResponse.setOut_refund_no( (String) map.get("out_request_no") );//退款订单号
  346. //queryRefundResponse.setChannel( (String) map.get("channel") ); //通道
  347. //queryRefundResponse.setUser_received_account( (String) map.get("user_received_account") ); //账号
  348. queryRefundResponse.setStatus( (String) map.get("refund_status") ); //状态
  349. queryRefundResponse.setSuccess_time( (String) map.get("gmt_refund_pay") );
  350. //queryRefundResponse.setCreate_time( (String) map.get("gmt_refund_pay") );
  351. queryRefundResponse.setExpand(map);
  352. return queryRefundResponse;
  353. } else {
  354. log.error("调用失败");
  355. return null;
  356. }
  357. }catch (Exception e){
  358. e.printStackTrace();
  359. //throw new TradeException("退款订单查询失败,订单号:"+ orderSn);
  360. return null;
  361. }
  362. }
  363. @Override
  364. public String getOpenid(String code) {
  365. AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
  366. alipayConfig.getAppId(), alipayConfig.getPrivateKey(), "json", "utf-8", alipayConfig.getPublicKey(), alipayConfig.getSignType());
  367. AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
  368. request.setCode(code);
  369. request.setGrantType("authorization_code");
  370. try {
  371. AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
  372. return oauthTokenResponse.getUserId();
  373. } catch (AlipayApiException e) {
  374. //处理异常
  375. e.printStackTrace();
  376. return "";
  377. }
  378. }
  379. /**
  380. * 获取支付宝连接
  381. * 参考官网:https://opendocs.alipay.com/open/01csp3?ref=api#公钥模式加签
  382. * 公钥模式加签
  383. * @return
  384. */
  385. private AlipayClient getAliHttpClient(){
  386. try {
  387. com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig();
  388. alipayConfig.setServerUrl(AlipayConstant.domain);
  389. alipayConfig.setAppId(this.alipayConfig.getAppId());
  390. alipayConfig.setPrivateKey(this.alipayConfig.getPrivateKey());
  391. alipayConfig.setFormat("json");
  392. alipayConfig.setCharset("utf-8");
  393. alipayConfig.setAlipayPublicKey(this.alipayConfig.getPublicKey());
  394. alipayConfig.setSignType(this.alipayConfig.getSignType());
  395. //构造client
  396. AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
  397. return alipayClient;
  398. }catch (Exception e){
  399. e.printStackTrace();
  400. throw new TradeException("支付宝支付--初始化,校验系统参数失败");
  401. }
  402. }
  403. /**
  404. * 分转换为元
  405. * @param fen
  406. * @return
  407. */
  408. private String fenToYuan(int fen){
  409. //转换为元
  410. return BigDecimal.valueOf(fen).divide(new BigDecimal(100) ).toString();
  411. }
  412. private int yuanToFen(String yuan){
  413. return BigDecimal.valueOf(Double.valueOf(yuan)).multiply(new BigDecimal(100)).intValue();
  414. }
  415. }