OrderPayService.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package com.izouma.nineth.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.izouma.nineth.config.GeneralProperties;
  4. import com.izouma.nineth.domain.*;
  5. import com.izouma.nineth.dto.UserBankCard;
  6. import com.izouma.nineth.enums.MintOrderStatus;
  7. import com.izouma.nineth.enums.OrderStatus;
  8. import com.izouma.nineth.enums.PayMethod;
  9. import com.izouma.nineth.event.OrderNotifyEvent;
  10. import com.izouma.nineth.exception.BusinessException;
  11. import com.izouma.nineth.repo.*;
  12. import com.izouma.nineth.utils.DateTimeUtils;
  13. import com.izouma.nineth.utils.SnowflakeIdWorker;
  14. import lombok.AllArgsConstructor;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.apache.rocketmq.spring.core.RocketMQTemplate;
  18. import org.springframework.cache.annotation.Cacheable;
  19. import org.springframework.security.crypto.password.PasswordEncoder;
  20. import org.springframework.stereotype.Service;
  21. import java.math.BigDecimal;
  22. import java.time.LocalDateTime;
  23. import java.util.Map;
  24. import java.util.Objects;
  25. import java.util.Optional;
  26. @Service
  27. @Slf4j
  28. @AllArgsConstructor
  29. public class OrderPayService {
  30. private static String PAY_CHANNEL = "sandPay";
  31. private final OrderService orderService;
  32. private final OrderRepo orderRepo;
  33. private final MintOrderRepo mintOrderRepo;
  34. private final GiftOrderRepo giftOrderRepo;
  35. private final SandPayService sandPayService;
  36. private final HMPayService hmPayService;
  37. private final GeneralProperties generalProperties;
  38. private final UserBalanceService userBalanceService;
  39. private final RocketMQTemplate rocketMQTemplate;
  40. private final GiftOrderService giftOrderService;
  41. private final MintOrderService mintOrderService;
  42. private final UserRepo userRepo;
  43. private final SnowflakeIdWorker snowflakeIdWorker;
  44. private final RechargeOrderRepo rechargeOrderRepo;
  45. private final SysConfigService sysConfigService;
  46. private final PasswordEncoder passwordEncoder;
  47. private final PayEaseService payEaseService;
  48. private final UserBankCardRepo userBankCardRepo;
  49. public static void setPayChannel(String payChannel) {
  50. if ("hmPay".equals(payChannel) || "sandPay".equals(payChannel)) {
  51. PAY_CHANNEL = payChannel;
  52. }
  53. }
  54. public String paddingOrderId(String orderId) {
  55. if (orderId != null && orderId.length() < 12) {
  56. StringBuilder orderIdBuilder = new StringBuilder(orderId);
  57. for (int i = orderIdBuilder.length(); i < 12; i++) {
  58. orderIdBuilder.insert(0, "0");
  59. }
  60. orderId = orderIdBuilder.toString();
  61. }
  62. return orderId;
  63. }
  64. @Cacheable(value = "payOrder", key = "'order#'+#orderId")
  65. public String payOrder(Long orderId) {
  66. Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  67. if (order.getStatus() != OrderStatus.NOT_PAID) {
  68. throw new BusinessException("订单状态错误");
  69. }
  70. switch (PAY_CHANNEL) {
  71. case "sandPay":
  72. return sandPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(),
  73. order.getName(), SandPayService.getTimeout(order.getCreatedAt(), 180),
  74. "{\"type\":\"order\",\"id\":\"" + orderId + "\"}");
  75. case "hmPay":
  76. return hmPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(),
  77. HMPayService.getTimeout(order.getCreatedAt(), 180),
  78. "order", generalProperties.getHost() + "/9th/orderDetail?id=" + orderId);
  79. }
  80. throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
  81. }
  82. public void payOrderBalance(Long orderId, Long userId, String tradeCode) {
  83. Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  84. if (order.getStatus() != OrderStatus.NOT_PAID) {
  85. throw new BusinessException("订单状态错误");
  86. }
  87. if (!Objects.equals(order.getUserId(), userId)) {
  88. throw new BusinessException("订单不属于该用户");
  89. }
  90. String encodedPwd = userRepo.findTradeCode(userId);
  91. if (StringUtils.isEmpty(encodedPwd)) {
  92. throw new BusinessException("请先设置交易密码");
  93. }
  94. if (!passwordEncoder.matches(tradeCode, encodedPwd)) {
  95. throw new BusinessException("交易码错误");
  96. }
  97. BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getTotalPrice(), orderId, order.getName());
  98. rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
  99. new OrderNotifyEvent(orderId, PayMethod.BALANCE, record.getId().toString(),
  100. System.currentTimeMillis()));
  101. }
  102. @Cacheable(value = "payOrder", key = "'order#'+#orderId")
  103. public Map<String, Object> payOrderAgreement(Long orderId, String bindCardId) {
  104. Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  105. if (order.getStatus() != OrderStatus.NOT_PAID) {
  106. throw new BusinessException("订单状态错误");
  107. }
  108. if (StringUtils.isEmpty(bindCardId)) {
  109. bindCardId = userBankCardRepo.findByUserId(order.getUserId())
  110. .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null);
  111. }
  112. if (StringUtils.isEmpty(bindCardId)) {
  113. throw new BusinessException("请先绑定银行卡");
  114. }
  115. return payEaseService.pay(order.getName(), orderId.toString(), order.getTotalPrice(),
  116. order.getUserId().toString(), bindCardId, "order");
  117. }
  118. public void confirmOrderAgreement(String requestId, String paymentOrderId, String code) {
  119. try {
  120. payEaseService.payConfirm(requestId, paymentOrderId, code);
  121. } catch (BusinessException e) {
  122. try {
  123. new Thread(() -> {
  124. orderService.cancel(Long.parseLong(requestId));
  125. }).start();
  126. } catch (Exception ee) {
  127. }
  128. throw e;
  129. }
  130. }
  131. @Cacheable(value = "payOrder", key = "'gift#'+#orderId")
  132. public String payGiftOrder(Long orderId) {
  133. GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  134. if (order.getStatus() != OrderStatus.NOT_PAID) {
  135. throw new BusinessException("订单状态错误");
  136. }
  137. switch (PAY_CHANNEL) {
  138. case "sandPay":
  139. return sandPayService.requestAlipay(orderId + "", order.getGasPrice(),
  140. "转赠" + order.getAssetId(), "转赠" + order.getAssetId(),
  141. SandPayService.getTimeout(order.getCreatedAt(), 180),
  142. "{\"type\":\"gift\",\"id\":\"" + orderId + "\"}");
  143. case "hmPay":
  144. return hmPayService.requestAlipay(orderId + "", order.getGasPrice(),
  145. "转赠" + order.getAssetId(),
  146. HMPayService.getTimeout(order.getCreatedAt(), 180),
  147. "gift", generalProperties.getHost() + "/9th/home");
  148. }
  149. throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
  150. }
  151. public void payGiftBalance(Long orderId, Long userId, String tradeCode) {
  152. GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  153. if (order.getStatus() != OrderStatus.NOT_PAID) {
  154. throw new BusinessException("订单状态错误");
  155. }
  156. if (!Objects.equals(order.getUserId(), userId)) {
  157. throw new BusinessException("订单不属于该用户");
  158. }
  159. if (!Objects.equals(userRepo.findTradeCode(userId), tradeCode)) {
  160. throw new BusinessException("交易码错误");
  161. }
  162. BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getGasPrice(), orderId, "转赠");
  163. giftOrderService.giftNotify(orderId, PayMethod.BALANCE, record.getId().toString());
  164. }
  165. @Cacheable(value = "payOrder", key = "'gift#'+#orderId")
  166. public Map<String, Object> payGiftOrderAgreement(Long orderId, String bindCardId) {
  167. GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  168. if (order.getStatus() != OrderStatus.NOT_PAID) {
  169. throw new BusinessException("订单状态错误");
  170. }
  171. if (StringUtils.isEmpty(bindCardId)) {
  172. bindCardId = userBankCardRepo.findByUserId(order.getUserId())
  173. .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null);
  174. }
  175. if (StringUtils.isEmpty(bindCardId)) {
  176. throw new BusinessException("请先绑定银行卡");
  177. }
  178. return payEaseService.pay("转赠" + order.getAssetId(), orderId.toString(), order.getGasPrice(),
  179. order.getUserId().toString(), bindCardId, "gift");
  180. }
  181. @Cacheable(value = "payOrder", key = "'mintOrder#'+#orderId")
  182. public String payMintOrder(Long orderId) {
  183. MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  184. if (order.getStatus() != MintOrderStatus.NOT_PAID) {
  185. throw new BusinessException("订单状态错误");
  186. }
  187. switch (PAY_CHANNEL) {
  188. case "sandPay":
  189. return sandPayService.requestAlipay(orderId + "", order.getGasPrice(),
  190. "铸造活动:" + order.getMintActivityId(), "铸造活动:" + order.getMintActivityId(),
  191. SandPayService.getTimeout(order.getCreatedAt(), 180),
  192. "{\"type\":\"mintOrder\",\"id\":\"" + orderId + "\"}");
  193. case "hmPay":
  194. return hmPayService.requestAlipay(orderId + "", order.getGasPrice(),
  195. "铸造活动:" + order.getMintActivityId(),
  196. HMPayService.getTimeout(order.getCreatedAt(), 180),
  197. "mintOrder", generalProperties.getHost() + "/9th/home");
  198. }
  199. throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
  200. }
  201. public void payMintOrderBalance(Long orderId, Long userId, String tradeCode) {
  202. MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  203. if (order.getStatus() != MintOrderStatus.NOT_PAID) {
  204. throw new BusinessException("订单状态错误");
  205. }
  206. if (!Objects.equals(order.getUserId(), userId)) {
  207. throw new BusinessException("订单不属于该用户");
  208. }
  209. if (!Objects.equals(userRepo.findTradeCode(userId), tradeCode)) {
  210. throw new BusinessException("交易码错误");
  211. }
  212. BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getGasPrice(), orderId, "铸造活动");
  213. giftOrderService.giftNotify(orderId, PayMethod.BALANCE, record.getId().toString());
  214. }
  215. @Cacheable(value = "payOrder", key = "'mint#'+#orderId")
  216. public Map<String, Object> payMintOrderAgreement(Long orderId, String bindCardId) {
  217. MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
  218. if (order.getStatus() != MintOrderStatus.NOT_PAID) {
  219. throw new BusinessException("订单状态错误");
  220. }
  221. if (StringUtils.isEmpty(bindCardId)) {
  222. bindCardId = userBankCardRepo.findByUserId(order.getUserId())
  223. .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null);
  224. }
  225. if (StringUtils.isEmpty(bindCardId)) {
  226. throw new BusinessException("请先绑定银行卡");
  227. }
  228. return payEaseService.pay("铸造活动:" + order.getMintActivityId(), orderId.toString(), order.getGasPrice(),
  229. order.getUserId().toString(), bindCardId, "mintOrder");
  230. }
  231. public String recharge(Long userId, BigDecimal amount) {
  232. BigDecimal minAmount = sysConfigService.getBigDecimal("min_recharge_amount");
  233. if (amount.compareTo(minAmount) < 0) {
  234. throw new BusinessException("充值金额不能小于" + minAmount);
  235. }
  236. if (amount.compareTo(new BigDecimal("50000")) > 0) {
  237. throw new BusinessException("充值金额不能大于50000");
  238. }
  239. RechargeOrder order = RechargeOrder.builder()
  240. .id(snowflakeIdWorker.nextId())
  241. .userId(userId)
  242. .amount(amount)
  243. .status(OrderStatus.NOT_PAID)
  244. .build();
  245. rechargeOrderRepo.save(order);
  246. switch (PAY_CHANNEL) {
  247. case "sandPay":
  248. return sandPayService.requestAlipay(order.getId() + "", order.getAmount(),
  249. "余额充值", "余额充值",
  250. SandPayService.getTimeout(order.getCreatedAt(), 180),
  251. "{\"type\":\"recharge\",\"id\":\"" + order.getId() + "\"}");
  252. case "hmPay":
  253. return hmPayService.requestAlipay(order.getId() + "", order.getAmount(),
  254. "余额充值",
  255. HMPayService.getTimeout(order.getCreatedAt(), 180),
  256. "recharge", generalProperties.getHost() + "/9th/home");
  257. }
  258. throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
  259. }
  260. public Map<String, Object> rechargeAgreement(Long userId, BigDecimal amount, String bindCardId) {
  261. BigDecimal minAmount = sysConfigService.getBigDecimal("min_recharge_amount");
  262. if (amount.compareTo(minAmount) < 0) {
  263. throw new BusinessException("充值金额不能小于" + minAmount);
  264. }
  265. if (amount.compareTo(new BigDecimal("50000")) > 0) {
  266. throw new BusinessException("充值金额不能大于50000");
  267. }
  268. RechargeOrder order = RechargeOrder.builder()
  269. .id(snowflakeIdWorker.nextId())
  270. .userId(userId)
  271. .amount(amount)
  272. .status(OrderStatus.NOT_PAID)
  273. .build();
  274. rechargeOrderRepo.save(order);
  275. if (StringUtils.isEmpty(bindCardId)) {
  276. bindCardId = userBankCardRepo.findByUserId(order.getUserId())
  277. .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null);
  278. }
  279. if (StringUtils.isEmpty(bindCardId)) {
  280. throw new BusinessException("请先绑定银行卡");
  281. }
  282. return payEaseService.pay("余额充值", order.getId().toString(), order.getAmount(),
  283. order.getUserId().toString(), bindCardId, "recharge");
  284. }
  285. public JSONObject refund(String orderId, BigDecimal amount, String channel) {
  286. switch (channel) {
  287. case "sandPay": {
  288. JSONObject res = sandPayService.refund(orderId, amount);
  289. if (!"000000".equals(res.getJSONObject("head").getString("respCode"))) {
  290. throw new BusinessException("退款失败");
  291. }
  292. break;
  293. }
  294. case "hmPay": {
  295. JSONObject res = hmPayService.refund(orderId, amount);
  296. if (!"REFUND_SUCCESS".equals(res.getString("sub_code"))) {
  297. throw new BusinessException("退款失败");
  298. }
  299. break;
  300. }
  301. }
  302. throw new BusinessException("退款失败");
  303. }
  304. }