ApiPayServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. package com.ydd.app.service.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.github.binarywang.wxpay.exception.WxPayException;
  6. import com.ijpay.core.enums.TradeType;
  7. import com.ydd.api.DeliveryService;
  8. import com.ydd.app.dto.OrderReq;
  9. import com.ydd.app.dto.ValuationRes;
  10. import com.ydd.app.listener.DeliveryOrderEvent;
  11. import com.ydd.app.service.*;
  12. import com.ydd.app.task.TipsTask;
  13. import com.ydd.common.exception.CustomException;
  14. import com.ydd.common.utils.DateUtils;
  15. import com.ydd.common.utils.SnCodeUtils;
  16. import com.ydd.module.domain.*;
  17. import com.ydd.module.dto.CouponDto;
  18. import com.ydd.module.dto.PayTradeQueryDto;
  19. import com.ydd.module.enums.*;
  20. import com.ydd.module.expection.CustomAppException;
  21. import com.ydd.module.pay.alipay.AliPayService;
  22. import com.ydd.module.pay.wechat.service.WechatPayService;
  23. import com.ydd.module.service.*;
  24. import lombok.RequiredArgsConstructor;
  25. import lombok.extern.slf4j.Slf4j;
  26. import org.apache.commons.collections4.CollectionUtils;
  27. import org.apache.commons.lang3.StringUtils;
  28. import org.springframework.beans.factory.annotation.Autowired;
  29. import org.springframework.context.ApplicationContext;
  30. import org.springframework.scheduling.annotation.Async;
  31. import org.springframework.stereotype.Service;
  32. import org.springframework.transaction.annotation.Transactional;
  33. import org.springframework.transaction.support.TransactionSynchronizationAdapter;
  34. import org.springframework.transaction.support.TransactionSynchronizationManager;
  35. import java.math.BigDecimal;
  36. import java.util.Date;
  37. import java.util.List;
  38. import java.util.concurrent.Executors;
  39. import java.util.concurrent.ScheduledExecutorService;
  40. import java.util.concurrent.TimeUnit;
  41. /**
  42. * Project:lb-server
  43. * Class:PayServiceImpl
  44. * Description:TODO
  45. * Time:2021/2/24 15:57
  46. *
  47. * @author zoe
  48. */
  49. @Slf4j
  50. @Service
  51. @RequiredArgsConstructor(onConstructor_ = @Autowired)
  52. public class ApiPayServiceImpl implements ApiPayService {
  53. private final IOrderService iOrderService;
  54. private final IMemberService iMemberService;
  55. private final IMemberBalanceLogService iMemberBalanceLogService;
  56. private final AliPayService aliPayService;
  57. private final IRechargeOptionService iRechargeOptionService;
  58. private final IRechargeService iRechargeService;
  59. private final ICouponService iCouponService;
  60. private final IMemberCouponService iMemberCouponService;
  61. private final WechatPayService wechatPayService;
  62. private final IPaymentService paymentService;
  63. private final IOrderLogService iOrderLogService;
  64. private final ApiCouponService apiCouponService;
  65. private final ApiProductService apiProductService;
  66. private final ApplicationContext applicationContext;
  67. private final IOrderTipService iOrderTipService;
  68. private final IDspDeliveryService iDspDeliveryService;
  69. private final IOrderDeliveryService iOrderDeliveryService;
  70. private final DeliveryService client;
  71. private final IShopDeliveryService iShopDeliveryService;
  72. private final ApiOrderNewService apiOrderNewService;
  73. private final ApiOrderService apiOrderService;
  74. private final IShopDeliveryBindService iShopDeliveryBindService;
  75. public static ScheduledExecutorService tipScheduledExecutorService = Executors.newScheduledThreadPool(10);
  76. @Override
  77. @Transactional(rollbackFor = Exception.class)
  78. public void pay(Long loginId, Integer orderId, Integer paymentType) {
  79. Order order = iOrderService.getById(orderId);
  80. Member member = iMemberService.getById(loginId);
  81. if (order == null) {
  82. throw new CustomAppException("订单不存在!");
  83. }
  84. order.setPaymentType(paymentType);
  85. if (order.getStatus().equals(PayStatusEnum.NO_PAYED.status)) {
  86. //扣钱
  87. if (member.getAmount().compareTo(order.getPayAmount()) < 0) {
  88. throw new CustomAppException("余额不足!", 250);
  89. }
  90. iMemberService.updateAmount(loginId, order.getPayAmount().negate());
  91. //更新支付状态
  92. order.setStatus(PayStatusEnum.PAYED.status);
  93. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  94. //去三方平台发单
  95. //TODO
  96. //余额变动记录
  97. iMemberBalanceLogService.saveLog(loginId, LogTypeEnum.REDUCE.type, "余额支付", LogSourceEnum.CONSUMPTION.status, order.getPayAmount(), order.getMerchantId(),order.getId(), order.getPaymentType());
  98. }
  99. iOrderService.updateById(order);
  100. }
  101. @Override
  102. @Transactional(rollbackFor = Exception.class)
  103. public Object payWx(Long loginId, Integer id, BigDecimal money, Integer paymentType, Integer createType) {
  104. Recharge recharge = new Recharge();
  105. recharge.setAmount(money);
  106. recharge.setGiveAmount(BigDecimal.ZERO);
  107. if (id != null) {
  108. RechargeOption option = iRechargeOptionService.getById(id);
  109. if (option == null) {
  110. throw new CustomAppException("充值选项不存在!");
  111. }
  112. recharge.setGiveAmount(new BigDecimal(option.getGiveValue()));
  113. recharge.setAmount(new BigDecimal(option.getValue()));
  114. recharge.setCouponIds(option.getCouponIds());
  115. }
  116. String orderSn = "R" + SnCodeUtils.createSn();
  117. recharge.setMemberId(loginId);
  118. recharge.setRechargeSn(orderSn);
  119. recharge.setTransactionDesc("账户充值");
  120. recharge.setPaymentType(PaymentTypeEnum.WEI_XIN.type);
  121. recharge.setPayStatus(PayStatusEnum.NO_PAYED.status);
  122. iRechargeService.save(recharge);
  123. paymentService.savePayment(loginId, orderSn, money, PaymentTypeEnum.WEI_XIN.type, TradeTypeEnum.RECHARGE.type, "", orderSn);
  124. try {
  125. Object resp;
  126. if (createType != null && createType == 1) {
  127. // PC充值
  128. resp = apiOrderService.getPaymentQRCode(money, orderSn, PaymentTypeEnum.WEI_XIN.type);
  129. } else {
  130. // APP充值
  131. resp = wechatPayService.pay(recharge.getAmount(), recharge.getTransactionDesc(), recharge.getRechargeSn(), TradeType.APP);
  132. }
  133. return resp;
  134. } catch (WxPayException e) {
  135. // e.printStackTrace();
  136. throw new CustomException("支付失败, 请重试");
  137. }
  138. }
  139. @Override
  140. @Transactional(rollbackFor = Exception.class)
  141. public Object payZfb(Long loginId, Integer id, BigDecimal money, Integer paymentType, Integer createType) {
  142. Recharge recharge = new Recharge();
  143. recharge.setAmount(money);
  144. recharge.setGiveAmount(BigDecimal.ZERO);
  145. if (id != null) {
  146. RechargeOption option = iRechargeOptionService.getById(id);
  147. if (option == null) {
  148. throw new CustomAppException("充值选项不存在!");
  149. }
  150. recharge.setGiveAmount(new BigDecimal(option.getGiveValue()));
  151. recharge.setAmount(new BigDecimal(option.getValue()));
  152. recharge.setCouponIds(option.getCouponIds());
  153. }
  154. String orderSn = "R" + SnCodeUtils.createSn();
  155. recharge.setMemberId(loginId);
  156. recharge.setRechargeSn(orderSn);
  157. recharge.setTransactionDesc("账户充值");
  158. recharge.setPaymentType(PaymentTypeEnum.ZHI_FU_BAO.type);
  159. recharge.setPayStatus(PayStatusEnum.NO_PAYED.status);
  160. iRechargeService.save(recharge);
  161. paymentService.savePayment(loginId, orderSn, money, PaymentTypeEnum.ZHI_FU_BAO.type, TradeTypeEnum.RECHARGE.type, "", orderSn);
  162. Object resp;
  163. if (createType != null && createType == 1) {
  164. // PC充值
  165. resp = apiOrderService.getPaymentQRCode(money, orderSn, PaymentTypeEnum.ZHI_FU_BAO.type);
  166. } else {
  167. // APP充值
  168. resp = aliPayService.pay(recharge.getRechargeSn(), recharge.getAmount().toString(), "账户充值");
  169. }
  170. return resp;
  171. }
  172. @Async
  173. @Override
  174. @Transactional(rollbackFor = Exception.class)
  175. public void paySuccess(String orderSn, String tradeSn, Integer payMement) {
  176. // OrderTip orderTip =null;
  177. // if(orderSn.startsWith("T")){
  178. // orderTip = iOrderTipService.getOne(new QueryWrapper<OrderTip>().eq("child_order_no",orderSn));
  179. // orderSn = orderTip.getOrderNo();
  180. // }
  181. Payment payment = paymentService.getOne(new QueryWrapper<Payment>().eq("child_order_sn", orderSn).eq("payment_type", payMement));
  182. if (payment != null && TradeTypeEnum.RECHARGE.type.equals(payment.getTradeType())) {
  183. recharge(orderSn, tradeSn);
  184. } else if (payment != null && TradeTypeEnum.ORDER.type.equals(payment.getTradeType())) {
  185. Order order = iOrderService.getOne(new QueryWrapper<Order>().eq("order_sn", orderSn).eq("deleted", IsDeleteEnum.NORMAL.status));
  186. if (!PaymentTypeEnum.BALANCE.type.equals(payment.getPaymentType()) && PayStatusEnum.NO_PAYED.status.equals(order.getStatus())) {
  187. payment.setPayStatus(PayStatusEnum.PAYED.status);
  188. payment.setTransactionSn(tradeSn);
  189. payment.setPayTime(new Date());
  190. paymentService.updatePayment(payment);
  191. order.setStatus(PayStatusEnum.PAYED.status);
  192. order.setDeliveryStatus(DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  193. iOrderService.updateById(order);
  194. iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.PAYED.status);
  195. iOrderLogService.addOrderLog(order.getId(), OrderStatusEnum.ORDERS_TO_BE_RECEIVED.status);
  196. CouponDto couponDto = null;
  197. if (order.getCouponId() != null && order.getCouponAmount().compareTo(BigDecimal.ZERO) > 0) {
  198. couponDto = apiCouponService.findDetail(order.getCouponId().intValue());
  199. couponDto.setStatus(MemberCouponStatusEnum.USED.getStatus());
  200. apiCouponService.updateCoupon(couponDto);
  201. }
  202. iMemberBalanceLogService.saveLog(order.getMemberId(), LogTypeEnum.REDUCE.type, "下单支付", LogSourceEnum.CONSUMPTION.status, order.getPayAmount(), order.getMerchantId(),order.getId(), order.getPaymentType());
  203. List<ValuationRes> resList = JSONArray.parseArray(payment.getValuation(), ValuationRes.class);
  204. if (CollectionUtils.isNotEmpty(resList)) {
  205. if (order.getWaimaiOrderId() != null) {
  206. apiOrderNewService.getWaiMaiInfo(order, new OrderReq());
  207. } else {
  208. this.setOrderSource(order);
  209. }
  210. // else {
  211. // Product product = apiProductService.findById(order.getProductId().intValue());
  212. // order.setProduct(product);
  213. // }
  214. CouponDto finalCouponDto = couponDto;
  215. TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
  216. @Override
  217. public void afterCommit() {
  218. applicationContext.publishEvent(new DeliveryOrderEvent(order, resList, finalCouponDto));
  219. }
  220. });
  221. }
  222. }
  223. } else if (payment != null && TradeTypeEnum.ADDTIP.type.equals(payment.getTradeType())) {
  224. OrderTip orderTip = iOrderTipService.getOne(new QueryWrapper<OrderTip>().eq("child_order_no", orderSn));
  225. orderTip.setStatus(PayStatusEnum.PAYED.status);
  226. iOrderTipService.updateById(orderTip);
  227. iOrderDeliveryService.updateDelivery(orderTip.getAmount(), orderTip.getOrderNo());
  228. Order order = iOrderService.getOne(new QueryWrapper<Order>().eq("order_sn", orderTip.getOrderNo()).eq("deleted", IsDeleteEnum.NORMAL.status));
  229. Order updateOrder = new Order();
  230. updateOrder.setId(order.getId());
  231. if (order.getTipAmount() != null) {
  232. updateOrder.setTipAmount(order.getTipAmount().add(orderTip.getAmount()));
  233. } else {
  234. updateOrder.setTipAmount(orderTip.getAmount());
  235. }
  236. // order.setUseTip(StatusEnum.SHOW.status);
  237. updateOrder.setTotalAmount(order.getTotalAmount().add(orderTip.getAmount()));
  238. updateOrder.setPayAmount(order.getPayAmount().add(orderTip.getAmount()));
  239. iOrderService.updateById(updateOrder);
  240. payment.setPayStatus(PayStatusEnum.PAYED.status);
  241. payment.setTransactionSn(tradeSn);
  242. payment.setPayTime(new Date());
  243. paymentService.updatePayment(payment);
  244. iMemberBalanceLogService.saveLog(order.getMemberId(), LogTypeEnum.REDUCE.type, "加小费", LogSourceEnum.CONSUMPTION.status, orderTip.getAmount(), order.getMerchantId(),order.getId(), orderTip.getPayType());
  245. tipScheduledExecutorService.schedule(new TipsTask(order, null, iOrderService, iDspDeliveryService, client, orderTip.getAmount(), iOrderDeliveryService, iShopDeliveryService,iShopDeliveryBindService), 1, TimeUnit.SECONDS);
  246. }
  247. }
  248. private void setOrderSource(Order order) {
  249. Integer platformType = order.getPlatformType();
  250. if (platformType != null && platformType > 0) {
  251. order.setPoiSeq(order.getLbDaySeq());
  252. // 美团、美团闪购
  253. if (platformType == 1 || platformType == 5) {
  254. order.setOrderSource("101");
  255. } else if (platformType == 2) {
  256. // 饿了么
  257. order.setOrderSource("102");
  258. } else if (platformType == 3) {
  259. // 饿百零售
  260. order.setOrderSource("103");
  261. }
  262. }
  263. }
  264. private void recharge(String orderSn, String tradeSn) {
  265. Recharge recharge = iRechargeService.getOne(new QueryWrapper<Recharge>().eq("recharge_sn", orderSn));
  266. if (recharge.getPayStatus().equals(PayStatusEnum.NO_PAYED.status)) {
  267. recharge.setPayStatus(PayStatusEnum.PAYED.status);
  268. recharge.setTransactionSn(tradeSn);
  269. recharge.setPayTime(new Date());
  270. iRechargeService.updateById(recharge);
  271. Member member = iMemberService.getById(recharge.getMemberId());
  272. //加钱
  273. iMemberBalanceLogService.updateMemberBalanceLog(recharge.getMemberId(), recharge.getAmount(), LogSourceEnum.RECHARGE.status, LogTypeEnum.INCREASE.type, "余额充值", member.getMerchantId(), recharge.getPaymentType());
  274. if (recharge.getGiveAmount() != null && recharge.getGiveAmount().compareTo(BigDecimal.ZERO) > 0) {
  275. iMemberBalanceLogService.updateMemberBalanceLog(recharge.getMemberId(), recharge.getGiveAmount(), LogSourceEnum.SEND.status, LogTypeEnum.INCREASE.type, "充值赠送金额", member.getMerchantId(), null);
  276. }
  277. //处理优惠券
  278. if (StringUtils.isNotBlank(recharge.getCouponIds())) {
  279. String[] ids = recharge.getCouponIds().split(",");
  280. for (String id : ids) {
  281. Coupon coupon = iCouponService.getById(id);
  282. log.info("优惠券类型---" + JSONObject.toJSONString(coupon));
  283. for (int i = 0; i < coupon.getMemberReciveNum(); i++) {
  284. MemberCoupon memberCoupon = new MemberCoupon();
  285. memberCoupon.setCouponId(Long.valueOf(id));
  286. memberCoupon.setMemberId(recharge.getMemberId());
  287. memberCoupon.setName(coupon.getCouponName());
  288. memberCoupon.setType(coupon.getCouponType());
  289. // 0->时间段 1->固定时间(天)
  290. if (coupon.getTimeType().equals(0)) {
  291. memberCoupon.setValidStartTime(coupon.getValidStartTime());
  292. memberCoupon.setValidEndTime(coupon.getValidEndTime());
  293. } else {
  294. Integer days = coupon.getDays();
  295. memberCoupon.setValidStartTime(new Date());
  296. Date endTime = DateUtils.addDays(new Date(), days);
  297. memberCoupon.setValidEndTime(DateUtils.getAutoTime(endTime, 23, 59, 59));
  298. }
  299. // 充值获取
  300. memberCoupon.setScope(5);
  301. iMemberCouponService.save(memberCoupon);
  302. }
  303. coupon.setReciveNum(coupon.getReciveNum() + coupon.getMemberReciveNum());
  304. iCouponService.updateById(coupon);
  305. }
  306. }
  307. }
  308. }
  309. @Override
  310. public PayTradeQueryDto tradeQuery(String orderSn, Integer payType) {
  311. // payType (1-支付宝 2-微信)
  312. if (PaymentTypeEnum.ZHI_FU_BAO.type.equals(payType)) {
  313. return aliPayService.aliTradeQuery(orderSn);
  314. } else if (PaymentTypeEnum.WEI_XIN.type.equals(payType)) {
  315. return wechatPayService.wechatTradeQuery(orderSn);
  316. } else {
  317. log.warn("无效的付款类型! orderSn: {}, payType: {}", orderSn, payType);
  318. throw new CustomException("payType参数错误!");
  319. }
  320. }
  321. }