TOrderServiceImpl.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package com.szwl.service.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6. import com.google.gson.Gson;
  7. import com.szwl.constant.JoinpayConstant;
  8. import com.szwl.feign.bean.OrderFeign;
  9. import com.szwl.model.entity.TOrder;
  10. import com.szwl.mapper.TOrderMapper;
  11. import com.szwl.model.entity.TOrderDetails;
  12. import com.szwl.model.entity.TWechatPayConfig;
  13. import com.szwl.model.utils.HttpClientUtils;
  14. import com.szwl.service.*;
  15. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  16. import com.szwl.weixin.util.HttpUtils;
  17. import com.wechat.pay.java.core.Config;
  18. import com.wechat.pay.java.service.payments.nativepay.model.Amount;
  19. import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
  20. import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
  21. import com.wechat.pay.java.service.payments.nativepay.model.SceneInfo;
  22. import com.wechat.pay.java.service.refund.model.CreateRequest;
  23. import com.wechat.pay.java.service.refund.model.Refund;
  24. import org.apache.commons.lang.StringUtils;
  25. import org.apache.http.HttpStatus;
  26. import org.apache.http.message.BasicNameValuePair;
  27. import org.springframework.beans.factory.annotation.Autowired;
  28. import org.springframework.stereotype.Service;
  29. import javax.servlet.http.HttpServletRequest;
  30. import javax.servlet.http.HttpServletResponse;
  31. import java.io.UnsupportedEncodingException;
  32. import java.math.BigDecimal;
  33. import java.math.RoundingMode;
  34. import java.text.SimpleDateFormat;
  35. import java.util.*;
  36. import static com.szwl.service.impl.TJoinpayMchServiceImpl.createHmacSign;
  37. /**
  38. * <p>
  39. * 服务实现类
  40. * </p>
  41. *
  42. * @author wuhs
  43. * @since 2022-06-17
  44. */
  45. @Service
  46. public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements TOrderService {
  47. @Autowired
  48. private TWeixinPayConfigService weixinPayConfigService;
  49. @Autowired
  50. OrderFeign orderFeign;
  51. @Autowired
  52. private TWechatPayConfigService wechatPayConfigService;
  53. @Autowired
  54. private TOrderDetailsService orderDetailsService;
  55. @Override
  56. public synchronized String initSn(Long equipmentId) {
  57. StringBuilder number = new StringBuilder();
  58. if (equipmentId != null) {
  59. Random random = new Random();
  60. /**
  61. * 6位随机
  62. */
  63. for (int i = 0; i < 6; i++) {
  64. number.append(String.valueOf(random.nextInt(10)));
  65. }
  66. /**
  67. * 设备id
  68. */
  69. number.append(equipmentId.toString());
  70. /**
  71. * 日期
  72. */
  73. number.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
  74. }
  75. return number.toString();
  76. }
  77. @Override
  78. public String wechatPay(String sn, BigDecimal amount, String productName, Long id, String notifyUrl, String clientId, HttpServletRequest request) {
  79. TWechatPayConfig wechatPayConfig = wechatPayConfigService.getById(id);
  80. Config config = wechatPayConfigService.getWechatConfig(id);
  81. if(config==null){
  82. wechatPayConfigService.initConfig(id);
  83. config = wechatPayConfigService.getWechatConfig(id);
  84. }
  85. // 构建service
  86. NativePayService service = new NativePayService.Builder().config(config).build();
  87. PrepayRequest payRequest = new PrepayRequest();
  88. Amount amount1 = new Amount();
  89. amount1.setTotal(amount.intValue());
  90. payRequest.setAmount(amount1);
  91. payRequest.setAppid(wechatPayConfig.getAppId());
  92. payRequest.setMchid(wechatPayConfig.getMerchantId());
  93. payRequest.setDescription(productName);
  94. // 添加设备编号
  95. String ipAddress = HttpClientUtils.getIpAddress(request);
  96. SceneInfo sceneInfo = new SceneInfo();
  97. sceneInfo.setPayerClientIp(ipAddress);
  98. sceneInfo.setDeviceId(clientId);
  99. payRequest.setSceneInfo(sceneInfo);
  100. payRequest.setNotifyUrl(notifyUrl);
  101. // payRequest.setNotifyUrl("http://evxz5m.natappfree.cc/wechatPay/notify");;
  102. payRequest.setOutTradeNo(sn);
  103. // 调用下单方法,得到应答
  104. PrepayResponse response = service.prepay(payRequest);
  105. return response.getCodeUrl();
  106. }
  107. /**
  108. * 处理退款回调通知
  109. * @param request
  110. * @param response
  111. * @return
  112. */
  113. @Override
  114. public String wechatRefund(HttpServletRequest request, HttpServletResponse response) {
  115. Gson gson = new Gson();
  116. Map<String, Object> hashMap = new HashMap<>(3);
  117. try {
  118. // 处理退款通知参数
  119. String body = HttpUtils.readData(request);
  120. Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
  121. String eventType = (String)bodyMap.get("event_type");
  122. if (eventType.equals("REFUND.SUCCESS")) {
  123. // 处理退款单
  124. processRefund(bodyMap);
  125. //成功应答
  126. response.setStatus(HttpStatus.SC_OK);
  127. hashMap.put("code", "SUCCESS");
  128. } else {
  129. response.setStatus(HttpStatus.SC_OK);
  130. hashMap.put("code", "FAIL");
  131. hashMap.put("message", "系统错误");
  132. }
  133. return gson.toJson(hashMap);
  134. } catch (Exception e) {
  135. e.printStackTrace();
  136. }
  137. return null;
  138. }
  139. @Override
  140. public Refund weixinRefundApi(CreateRequest createRequest, Long id) {
  141. Config config = wechatPayConfigService.getWechatConfig(id);
  142. if(config==null){
  143. wechatPayConfigService.initConfig(id);
  144. config = wechatPayConfigService.getWechatConfig(id);
  145. }
  146. // 构建service
  147. NativePayService service = new NativePayService.Builder().config(config).build();
  148. Refund refund = service.refund(createRequest);
  149. return refund;
  150. }
  151. /**
  152. * 汇聚查询退款状态
  153. * @param refundTrxNo
  154. * @return
  155. */
  156. @Override
  157. public JSONObject queryRefund(String refundTrxNo) {
  158. String url = "https://www.joinpay.com/trade/queryRefund.action";
  159. List<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>();
  160. data.add(new BasicNameValuePair("p1_MerchantNo", JoinpayConstant.mch_no));
  161. data.add(new BasicNameValuePair("p2_RefundOrderNo", refundTrxNo));
  162. data.add(new BasicNameValuePair("p3_Version", "2.1"));
  163. String hmac = null;
  164. try {
  165. hmac = createHmacSign(data, JoinpayConstant.key);
  166. } catch (UnsupportedEncodingException e) {
  167. e.printStackTrace();
  168. }
  169. data.add(new BasicNameValuePair("hmac", hmac));
  170. String result = HttpClientUtils.postKeyValue(url, data);
  171. JSONObject resultJson = JSONObject.parseObject(result);
  172. return resultJson;
  173. }
  174. public void processRefund(Map<String, Object> bodyMap) {
  175. String decrypt = weixinPayConfigService.decryptFromResource(bodyMap);
  176. Gson gson = new Gson();
  177. Map<String,Object> map = gson.fromJson(decrypt, HashMap.class);
  178. String sn = map.get("out_trade_no").toString();
  179. String refundNo = map.get("out_refund_no").toString();
  180. String amount =map.get("amount").toString();
  181. Map<String,Object> amountMap = gson.fromJson(amount, HashMap.class);
  182. String refundPrice = amountMap.get("refund").toString();
  183. if(StringUtils.isNotEmpty(sn)){
  184. LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
  185. query.eq(TOrder::getSn,sn);
  186. TOrder order = getOne(query);
  187. // 已退款
  188. if(order.getRefundQuantity() < order.getProductNumber()) {
  189. order.setStatus(1);
  190. } else {
  191. order.setStatus(3);
  192. }
  193. // 更改订单明细表
  194. LambdaQueryWrapper<TOrderDetails> queryWrapper = new LambdaQueryWrapper<>();
  195. queryWrapper.eq(TOrderDetails::getOrderSn, sn);
  196. // 处理退款中状态的明细
  197. queryWrapper.eq(TOrderDetails::getRefundStatus, "4");
  198. List<TOrderDetails> tOrderDetails = orderDetailsService.list(queryWrapper);
  199. for (TOrderDetails tOrderDetail : tOrderDetails) {
  200. Integer refundQuantity = tOrderDetail.getRefundQuantity();
  201. Integer productNumber = tOrderDetail.getProductNumber();
  202. if(refundQuantity < productNumber) {
  203. // 部分退款
  204. tOrderDetail.setRefundStatus("2");
  205. orderDetailsService.updateById(tOrderDetail);
  206. } else {
  207. // 全部退款
  208. tOrderDetail.setRefundStatus("3");
  209. orderDetailsService.updateById(tOrderDetail);
  210. }
  211. }
  212. //退款金额要除以100
  213. BigDecimal r4_refundAmount = new BigDecimal(refundPrice).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP).setScale(2, RoundingMode.HALF_DOWN);
  214. // if(order.getRefundMarketingAmount()!=null){
  215. // r4_refundAmount =r4_refundAmount.add(order.getRefundMarketingAmount());
  216. // }
  217. BigDecimal refundAmount = order.getRefundAmount();
  218. if(refundAmount != null) {
  219. order.setRefundAmount(refundAmount.add(r4_refundAmount));
  220. } else {
  221. order.setRefundAmount(r4_refundAmount);
  222. }
  223. order.setRefundDate(new Date());
  224. order.setModifyDate(new Date());
  225. order.setRefundTrxNo(refundNo);
  226. try {
  227. orderFeign.saveToEs(order);
  228. }catch (Exception e) {
  229. e.printStackTrace();
  230. }finally {
  231. updateById(order);
  232. }
  233. }
  234. }
  235. }