后台服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 line
10 KiB

  1. package com.iformall.controller;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.github.binarywang.wxpay.v3.util.AesUtils;
  4. import com.iformall.annotation.AuthIgnore;
  5. import com.iformall.common.ErrorCode;
  6. import com.iformall.domain.po.ProductOrder;
  7. import com.iformall.domain.po.ProductOrderPay;
  8. import com.iformall.domain.po.WxAppinfo;
  9. import com.iformall.domain.po.WxPayAccount;
  10. import com.iformall.enums.EnumAppPlat;
  11. import com.iformall.enums.EnumProductOrderPayVendor;
  12. import com.iformall.interceptor.BodyReaderHttpServletRequestWrapper;
  13. import com.iformall.service.ProductOrderPayService;
  14. import com.iformall.service.ProductOrderService;
  15. import com.iformall.service.WxAppinfoService;
  16. import com.iformall.service.WxPayAccountService;
  17. import com.iformall.service.pay.PayServiceFactory;
  18. import com.iformall.service.pay.service.pay.PayAdapterService;
  19. import io.swagger.annotations.Api;
  20. import io.swagger.annotations.ApiOperation;
  21. import org.apache.commons.lang3.StringUtils;
  22. import org.jdom2.JDOMException;
  23. import org.slf4j.Logger;
  24. import org.slf4j.LoggerFactory;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.web.bind.annotation.*;
  27. import javax.servlet.http.HttpServletRequest;
  28. import javax.servlet.http.HttpServletResponse;
  29. import java.io.BufferedReader;
  30. import java.io.IOException;
  31. import java.io.InputStream;
  32. import java.io.InputStreamReader;
  33. import java.util.HashMap;
  34. import java.util.Iterator;
  35. import java.util.Map;
  36. @RestController
  37. @RequestMapping("/payCallBack")
  38. @Api(description = "支付回调")
  39. public class CallbackPayController extends BaseController {
  40. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  41. @Autowired
  42. private WxAppinfoService wxAppinfoService;
  43. @Autowired
  44. private WxPayAccountService wxPayAccountService;
  45. @Autowired
  46. private ProductOrderPayService productOrderPayService;
  47. @Autowired
  48. private PayServiceFactory payServiceFactory;
  49. @AuthIgnore
  50. @ApiOperation("支付回调")
  51. @PostMapping(value = "{projectType}/pay/v3")
  52. public void _payV3Notify(@PathVariable Integer projectType, @RequestBody Map<String, Object> paranMap,
  53. HttpServletRequest request, HttpServletResponse response) {
  54. logger.debug("[" + getIpAddr() + "] CallbackPayController::_payV3Notify");
  55. logger.info("微信支付回调结果通知{}"+JSONObject.toJSONString(paranMap));
  56. /**
  57. * {"id":"4330b030-788f-5067-8c8a-69ee373d43ad","create_time":"2023-08-28T18:44:56+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"PneNTwSVDoirBNQsJstB/yX1dNMupj7uKQVEVfLOoyMSCqKh+KMwIdanidbcs6OnSy1Xmx4MploMaQ5rSg66sFDQ9nDuSVc4S/I3OVflu1l7z9vR+FJiztpTqhr/ekeNz9VivtqPPtn6N3dCyZb6iCEwnXT+TEB8SBZe4bPSPFGhB/MB9w1ZpqP14OvMDUnzKM15mdex6wmAJH6qIbd1aH3jrW/Lv7KeyfXEYrRDljq2Za6476UQxeAcsR3JA6QpWwrhYxpKFQEHuGMdiVC1KvQsP3+JUWOKSiQQ1r5upTACPI8n5B/kOeXJA8MnTgY/7lZiA6ys2dt8jqxzL8IlDracnlwvsiRAuXjRjcX6pYCz4q0HwIYb1nHXE+iRcSGm8h+xFFsnhGgxrhEVz6ARhK6ZtKtibCv7Ll/a/d090FBKtVXzCWB6cLMMmfrIwLQFqiFUtb6zsV/zusAJdwHZt3LmtgGahoV3+UPTnbztEAp5IJGz2imGPTsk7QpvKWQknf5FM/Z1fhr/vb+pZV5NGBZ+6l/mI8isA4HtljzNHU/PuKCGO8uWu6QFevgAftGGww==","associated_data":"transaction","nonce":"Hrcahgdp1eO6"}}
  58. */
  59. try{
  60. WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.WX.getCode());
  61. WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId());
  62. Map<String, String> resource = (Map<String, String>) paranMap.get("resource");
  63. String associatedData = resource.get("associated_data");
  64. String nonce = resource.get("nonce");
  65. String ciphertext = resource.get("ciphertext");
  66. String decryptString = AesUtils.decryptToString(associatedData, nonce, ciphertext, payAccount.getMerchantApiv3Key());
  67. logger.info("微信支付回调解密数据{}"+decryptString);
  68. JSONObject jsonObject = JSONObject.parseObject(decryptString);
  69. String out_order_no = jsonObject.getString("out_trade_no");
  70. /**
  71. * 交易类型,枚举值:
  72. * JSAPI:公众号支付
  73. * NATIVE:扫码支付
  74. * App:App支付
  75. * MICROPAY:付款码支付
  76. * MWEB:H5支付
  77. * FACEPAY:刷脸支付
  78. */
  79. String trade_type = jsonObject.getString("trade_type");
  80. EnumProductOrderPayVendor payVendorEnum = null;
  81. if("JSAPI".equals(trade_type)){
  82. payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_WECHAT;
  83. }else if("NATIVE".equals(trade_type)){
  84. payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_WECHAT_NATIVE;
  85. }
  86. if(payVendorEnum == null){
  87. logger.error("微信支付回调处理支付方式异常{}"+trade_type);
  88. response.setStatus(ErrorCode.SYS_SERVER_ERROR.getCode());
  89. }
  90. ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_order_no), payVendorEnum);
  91. PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode());
  92. productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService);
  93. response.setStatus(200);
  94. }catch(Exception e){
  95. logger.error("微信支付回调处理异常{}"+e);
  96. response.setStatus(ErrorCode.SYS_SERVER_ERROR.getCode());
  97. }
  98. }
  99. @AuthIgnore
  100. @ApiOperation("支付回调")
  101. @PostMapping(value = "{projectType}/ttNotify")
  102. public Map<String,Object> _ttNotify(@PathVariable Integer projectType, @RequestBody Map<String, Object> paranMap,
  103. HttpServletRequest request, HttpServletResponse response) {
  104. logger.debug("[" + getIpAddr() + "] CallbackPayController::_ttNotify");
  105. Map<String,Object> resultMap = new HashMap<>();
  106. logger.info("抖音支付回调结果通知{}"+JSONObject.toJSONString(paranMap));
  107. /**
  108. * ----效验数据来源合法
  109. */
  110. try{
  111. String msg = (String) paranMap.get("msg");
  112. String type = (String) paranMap.get("type");
  113. Map<String, Object> pMap = JSONObject.parseObject(msg, Map.class);
  114. // String appid = (String) pMap.get("appid");
  115. // WxAppinfo appInfo = wxAppinfoService.getOnlyByAppIdFromRedis(appid);
  116. WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.TOUTIAO.getCode());
  117. WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId());
  118. if("payment".equals(type)){
  119. String out_order_no = (String)pMap.get("cp_orderno");
  120. EnumProductOrderPayVendor payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_TT;
  121. ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_order_no), payVendorEnum);
  122. PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode());
  123. productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService);
  124. resultMap.put("err_no",0);
  125. resultMap.put("err_tips","success");
  126. }
  127. }catch(Exception e){
  128. logger.error("抖音支付回调处理异常"+e);
  129. resultMap.put("err_no",ErrorCode.SYS_SERVER_ERROR.getCode());
  130. resultMap.put("err_tips","抖音支付回调处理异常");
  131. }
  132. return resultMap;
  133. }
  134. @AuthIgnore
  135. @ApiOperation("支付回调")
  136. @PostMapping(value = "{projectType}/aliNotify")
  137. public String _aliNotify(@PathVariable Integer projectType,
  138. HttpServletRequest request, HttpServletResponse response) {
  139. logger.debug("[" + getIpAddr() + "] CallbackPayController::_aliNotify");
  140. String body = ((BodyReaderHttpServletRequestWrapper) request).getBody();
  141. logger.info("ali支付回调结果通知 body{}"+body);
  142. Map<String,Object> resultMap = new HashMap<>();
  143. /**
  144. * ----效验数据来源合法
  145. */
  146. try{
  147. Map<String, String> paranMap = handBody(body);
  148. logger.info("ali支付回调结果通知 paranMap{}"+JSONObject.toJSONString(paranMap));
  149. // String app_id = paranMap.get("app_id");
  150. // WxAppinfo appInfo = wxAppinfoService.getOnlyByAppIdFromRedis(app_id);
  151. WxAppinfo appInfo = wxAppinfoService.getProjectCAppInfoFromRedis(projectType, EnumAppPlat.ALI.getCode());
  152. WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appInfo.getPayId());
  153. String out_trade_no = paranMap.get("out_trade_no");
  154. String trade_status = paranMap.get("trade_status");
  155. if("TRADE_SUCCESS".equals(trade_status)){
  156. EnumProductOrderPayVendor payVendorEnum = EnumProductOrderPayVendor.PAY_WAY_ALIPAY_WAP;
  157. ProductOrderPay orderPay = productOrderPayService.getByOrder(Long.parseLong(out_trade_no), payVendorEnum);
  158. PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payVendorEnum.getCode());
  159. productOrderPayService.handleProductOrderByQuery(appInfo,payAccount,orderPay,payAdapterService);
  160. }
  161. return "success";
  162. }catch(Exception e){
  163. logger.error("ali支付回调处理异常"+e);
  164. }
  165. return "fail";
  166. }
  167. private Map<String,String> handBody(String body){
  168. Map<String,String> map = new HashMap<>();
  169. if(StringUtils.isNotBlank(body)){
  170. String[] key_value = body.split("&");
  171. if(key_value.length > 0){
  172. for (String kv: key_value) {
  173. String[] split = kv.split("=");
  174. map.put(split[0],split[1]);
  175. }
  176. }
  177. }
  178. return map;
  179. }
  180. }