package com.izouma.nineth.service; import com.alibaba.fastjson.JSONObject; import com.izouma.nineth.config.GeneralProperties; import com.izouma.nineth.domain.*; import com.izouma.nineth.dto.UserBankCard; import com.izouma.nineth.enums.MintOrderStatus; import com.izouma.nineth.enums.OrderStatus; import com.izouma.nineth.enums.PayMethod; import com.izouma.nineth.event.OrderNotifyEvent; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.*; import com.izouma.nineth.utils.DateTimeUtils; import com.izouma.nineth.utils.SnowflakeIdWorker; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.cache.annotation.Cacheable; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Map; import java.util.Objects; import java.util.Optional; @Service @Slf4j @AllArgsConstructor public class OrderPayService { private static String PAY_CHANNEL = "sandPay"; private final OrderService orderService; private final OrderRepo orderRepo; private final MintOrderRepo mintOrderRepo; private final GiftOrderRepo giftOrderRepo; private final SandPayService sandPayService; private final HMPayService hmPayService; private final GeneralProperties generalProperties; private final UserBalanceService userBalanceService; private final RocketMQTemplate rocketMQTemplate; private final GiftOrderService giftOrderService; private final MintOrderService mintOrderService; private final UserRepo userRepo; private final SnowflakeIdWorker snowflakeIdWorker; private final RechargeOrderRepo rechargeOrderRepo; private final SysConfigService sysConfigService; private final PasswordEncoder passwordEncoder; private final PayEaseService payEaseService; private final UserBankCardRepo userBankCardRepo; public static void setPayChannel(String payChannel) { if ("hmPay".equals(payChannel) || "sandPay".equals(payChannel)) { PAY_CHANNEL = payChannel; } } public String paddingOrderId(String orderId) { if (orderId != null && orderId.length() < 12) { StringBuilder orderIdBuilder = new StringBuilder(orderId); for (int i = orderIdBuilder.length(); i < 12; i++) { orderIdBuilder.insert(0, "0"); } orderId = orderIdBuilder.toString(); } return orderId; } @Cacheable(value = "payOrder", key = "'order#'+#orderId") public String payOrder(Long orderId) { Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } switch (PAY_CHANNEL) { case "sandPay": return sandPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(), order.getName(), SandPayService.getTimeout(order.getCreatedAt(), 180), "{\"type\":\"order\",\"id\":\"" + orderId + "\"}"); case "hmPay": return hmPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(), HMPayService.getTimeout(order.getCreatedAt(), 180), "order", generalProperties.getHost() + "/9th/orderDetail?id=" + orderId); } throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付"); } public void payOrderBalance(Long orderId, Long userId, String tradeCode) { Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (!Objects.equals(order.getUserId(), userId)) { throw new BusinessException("订单不属于该用户"); } String encodedPwd = userRepo.findTradeCode(userId); if (StringUtils.isEmpty(encodedPwd)) { throw new BusinessException("请先设置交易密码"); } if (!passwordEncoder.matches(tradeCode, encodedPwd)) { throw new BusinessException("交易码错误"); } BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getTotalPrice(), orderId, order.getName()); rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(), new OrderNotifyEvent(orderId, PayMethod.BALANCE, record.getId().toString(), System.currentTimeMillis())); } @Cacheable(value = "payOrder", key = "'order#'+#orderId") public Map payOrderAgreement(Long orderId, String bindCardId) { Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (StringUtils.isEmpty(bindCardId)) { bindCardId = userBankCardRepo.findByUserId(order.getUserId()) .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null); } if (StringUtils.isEmpty(bindCardId)) { throw new BusinessException("请先绑定银行卡"); } return payEaseService.pay(order.getName(), orderId.toString(), order.getTotalPrice(), order.getUserId().toString(), bindCardId, "order"); } public void confirmOrderAgreement(String requestId, String paymentOrderId, String code) { try { payEaseService.payConfirm(requestId, paymentOrderId, code); } catch (BusinessException e) { try { new Thread(() -> { orderService.cancel(Long.parseLong(requestId)); }).start(); } catch (Exception ee) { } throw e; } } @Cacheable(value = "payOrder", key = "'gift#'+#orderId") public String payGiftOrder(Long orderId) { GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } switch (PAY_CHANNEL) { case "sandPay": return sandPayService.requestAlipay(orderId + "", order.getGasPrice(), "转赠" + order.getAssetId(), "转赠" + order.getAssetId(), SandPayService.getTimeout(order.getCreatedAt(), 180), "{\"type\":\"gift\",\"id\":\"" + orderId + "\"}"); case "hmPay": return hmPayService.requestAlipay(orderId + "", order.getGasPrice(), "转赠" + order.getAssetId(), HMPayService.getTimeout(order.getCreatedAt(), 180), "gift", generalProperties.getHost() + "/9th/home"); } throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付"); } public void payGiftBalance(Long orderId, Long userId, String tradeCode) { GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (!Objects.equals(order.getUserId(), userId)) { throw new BusinessException("订单不属于该用户"); } if (!Objects.equals(userRepo.findTradeCode(userId), tradeCode)) { throw new BusinessException("交易码错误"); } BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getGasPrice(), orderId, "转赠"); giftOrderService.giftNotify(orderId, PayMethod.BALANCE, record.getId().toString()); } @Cacheable(value = "payOrder", key = "'gift#'+#orderId") public Map payGiftOrderAgreement(Long orderId, String bindCardId) { GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (StringUtils.isEmpty(bindCardId)) { bindCardId = userBankCardRepo.findByUserId(order.getUserId()) .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null); } if (StringUtils.isEmpty(bindCardId)) { throw new BusinessException("请先绑定银行卡"); } return payEaseService.pay("转赠" + order.getAssetId(), orderId.toString(), order.getGasPrice(), order.getUserId().toString(), bindCardId, "gift"); } @Cacheable(value = "payOrder", key = "'mintOrder#'+#orderId") public String payMintOrder(Long orderId) { MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != MintOrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } switch (PAY_CHANNEL) { case "sandPay": return sandPayService.requestAlipay(orderId + "", order.getGasPrice(), "铸造活动:" + order.getMintActivityId(), "铸造活动:" + order.getMintActivityId(), SandPayService.getTimeout(order.getCreatedAt(), 180), "{\"type\":\"mintOrder\",\"id\":\"" + orderId + "\"}"); case "hmPay": return hmPayService.requestAlipay(orderId + "", order.getGasPrice(), "铸造活动:" + order.getMintActivityId(), HMPayService.getTimeout(order.getCreatedAt(), 180), "mintOrder", generalProperties.getHost() + "/9th/home"); } throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付"); } public void payMintOrderBalance(Long orderId, Long userId, String tradeCode) { MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != MintOrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (!Objects.equals(order.getUserId(), userId)) { throw new BusinessException("订单不属于该用户"); } if (!Objects.equals(userRepo.findTradeCode(userId), tradeCode)) { throw new BusinessException("交易码错误"); } BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getGasPrice(), orderId, "铸造活动"); giftOrderService.giftNotify(orderId, PayMethod.BALANCE, record.getId().toString()); } @Cacheable(value = "payOrder", key = "'mint#'+#orderId") public Map payMintOrderAgreement(Long orderId, String bindCardId) { MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != MintOrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } if (StringUtils.isEmpty(bindCardId)) { bindCardId = userBankCardRepo.findByUserId(order.getUserId()) .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null); } if (StringUtils.isEmpty(bindCardId)) { throw new BusinessException("请先绑定银行卡"); } return payEaseService.pay("铸造活动:" + order.getMintActivityId(), orderId.toString(), order.getGasPrice(), order.getUserId().toString(), bindCardId, "mintOrder"); } public String recharge(Long userId, BigDecimal amount) { BigDecimal minAmount = sysConfigService.getBigDecimal("min_recharge_amount"); if (amount.compareTo(minAmount) < 0) { throw new BusinessException("充值金额不能小于" + minAmount); } if (amount.compareTo(new BigDecimal("50000")) > 0) { throw new BusinessException("充值金额不能大于50000"); } RechargeOrder order = RechargeOrder.builder() .id(snowflakeIdWorker.nextId()) .userId(userId) .amount(amount) .status(OrderStatus.NOT_PAID) .build(); rechargeOrderRepo.save(order); switch (PAY_CHANNEL) { case "sandPay": return sandPayService.requestAlipay(order.getId() + "", order.getAmount(), "余额充值", "余额充值", SandPayService.getTimeout(order.getCreatedAt(), 180), "{\"type\":\"recharge\",\"id\":\"" + order.getId() + "\"}"); case "hmPay": return hmPayService.requestAlipay(order.getId() + "", order.getAmount(), "余额充值", HMPayService.getTimeout(order.getCreatedAt(), 180), "recharge", generalProperties.getHost() + "/9th/home"); } throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付"); } public Map rechargeAgreement(Long userId, BigDecimal amount, String bindCardId) { BigDecimal minAmount = sysConfigService.getBigDecimal("min_recharge_amount"); if (amount.compareTo(minAmount) < 0) { throw new BusinessException("充值金额不能小于" + minAmount); } if (amount.compareTo(new BigDecimal("50000")) > 0) { throw new BusinessException("充值金额不能大于50000"); } RechargeOrder order = RechargeOrder.builder() .id(snowflakeIdWorker.nextId()) .userId(userId) .amount(amount) .status(OrderStatus.NOT_PAID) .build(); rechargeOrderRepo.save(order); if (StringUtils.isEmpty(bindCardId)) { bindCardId = userBankCardRepo.findByUserId(order.getUserId()) .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null); } if (StringUtils.isEmpty(bindCardId)) { throw new BusinessException("请先绑定银行卡"); } return payEaseService.pay("余额充值", order.getId().toString(), order.getAmount(), order.getUserId().toString(), bindCardId, "recharge"); } public JSONObject refund(String orderId, BigDecimal amount, String channel) { switch (channel) { case "sandPay": { JSONObject res = sandPayService.refund(orderId, amount); if (!"000000".equals(res.getJSONObject("head").getString("respCode"))) { throw new BusinessException("退款失败"); } break; } case "hmPay": { JSONObject res = hmPayService.refund(orderId, amount); if (!"REFUND_SUCCESS".equals(res.getString("sub_code"))) { throw new BusinessException("退款失败"); } break; } } throw new BusinessException("退款失败"); } }