package com.crm.pay.service.impl; import com.alibaba.fastjson.JSON; import com.crm.pay.dao.mapper.FinanceDepositMapper; import com.crm.pay.dao.mapper.GoldenOrderMapper; import com.crm.pay.dao.repository.*; import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity; import com.crm.pay.entity.FinanceDepositCallbackValidateUpdateEntity; import com.crm.pay.service.*; import com.crm.rely.backend.configuration.LocaleMessage; import com.crm.rely.backend.core.constant.Constants; import com.crm.rely.backend.core.constant.EmailSendEnum; import com.crm.rely.backend.core.constant.MapConstants; import com.crm.rely.backend.core.constant.StatusConstants; import com.crm.rely.backend.core.dto.base.BaseResultDto; import com.crm.rely.backend.core.dto.base.PageDto; import com.crm.rely.backend.core.dto.base.ResultWithPagerDto; import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity; import com.crm.rely.backend.core.entity.web.notice.record.WebNoticeRecordAndEmailMqEntity; import com.crm.rely.backend.core.exception.PayValidatedException; import com.crm.rely.backend.core.exception.ServiceException; import com.crm.rely.backend.core.pojo.table.SysConfigTable; import com.crm.rely.backend.model.constant.ConfigConstants; import com.crm.rely.backend.model.constant.EmailTemplateConstants; import com.crm.rely.backend.model.constant.PayConstants; import com.crm.rely.backend.model.dto.finance.deposit.FinanceDepositDto; import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity; import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositApproveEntity; import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositDeleteEntity; import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositSearchListEntity; import com.crm.rely.backend.model.entity.sys.config.SysConfigAutolimitEntity; import com.crm.rely.backend.model.entity.sys.config.SysConfigFinanceEntity; import com.crm.rely.backend.model.pojo.table.*; import com.crm.rely.backend.model.pojo.view.FinanceDepositView; import com.crm.rely.backend.model.util.CustomInfoUtil; import com.crm.rely.backend.service.EmailService; import com.crm.rely.backend.service.MqSendService; import com.crm.rely.backend.service.RedisService; import com.crm.rely.backend.util.*; import com.google.common.base.Strings; import lombok.extern.log4j.Log4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.sql.Time; import java.util.*; /** * @description: * @author: houn * @create: 2019-05-05 20:31 */ @Log4j @Service public class FinanceDepositServiceImpl implements FinanceDepositService { @Autowired private LocaleMessage localeMessage; @Autowired private FinanceDepositRepository financeDepositRepository; @Autowired private FinanceDepositMapper financeDepositMapper; @Autowired private SysConfigService sysConfigService; @Autowired private CustomLoginService customLoginService; @Autowired private CustomInfoRepository customInfoRepository; @Autowired private SysRemittanceChannelService sysRemittanceChannelService; @Autowired private SysChannelBankService sysChannelBankService; @Autowired private FinanceRateService financeRateService; @Autowired private GoldenOrderRepository goldenOrderRepository; @Autowired private GoldenOrderDetailsRepository goldenOrderDetailsRepository; @Autowired private GoldenGoodsRepository goldenGoodsRepository; @Autowired private GoldenOrderMapper goldenOrderMapper; @Autowired private RedisService redisService; @Autowired private SysRemittanceChannelRepository sysRemittanceChannelRepository; @Autowired private EmailService emailService; @Autowired private MqSendService mqSendService; /** * 保存入金信息 * * @param balanceSaveEntity 入金实体 * @return * @throws ServiceException * @throws PayValidatedException */ @Override @Transactional(rollbackFor = Exception.class) public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException, PayValidatedException { //获取入金通道 SysRemittanceChannelTable channel = sysRemittanceChannelService.getSysRemittanceChannelByCode(balanceSaveEntity.getPayType()); if (channel == null) { throw new ServiceException(PayConstants.FINANCE_DEPOSIT_CHANNEL_NOT_EMPTY); } return save(balanceSaveEntity, channel); } /** * 添加支付订单 以后有种支付方式 调用此方法 * * @param balanceSaveEntity 入金保存信息 * @param channel 入金通道信息 * @return 支付url */ @Override @Transactional(rollbackFor = Exception.class) public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel) throws ServiceException, PayValidatedException { return save(balanceSaveEntity, null, channel); } @Override @Transactional(rollbackFor = Exception.class) public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity, SysChannelBankTable sysChannelBankTable, SysRemittanceChannelTable channel) throws ServiceException, PayValidatedException { List goodsTables = goldenGoodsRepository.findAllByIdIn(balanceSaveEntity.getGoodIds()); BigDecimal goodsPrice = BigDecimal.ZERO; for (GoldenGoodsTable goldenGoodsTable : goodsTables) { goodsPrice = goodsPrice.add(goldenGoodsTable.getGoodsPrice()); } if (goodsPrice.compareTo(balanceSaveEntity.getAmount()) > 0 ) { throw new ServiceException("goods_amount_error"); } GoldenOrderDetailsTable detailsTable = goldenOrderMapper.getByCustomIdAndGoodsIdIn(balanceSaveEntity.getAddUser(), balanceSaveEntity.getGoodIds()); if(detailsTable != null){ throw new ServiceException("goods_purchased_error"); } if (Strings.isNullOrEmpty(balanceSaveEntity.getCurrency())) { balanceSaveEntity.setCurrency(channel.getCurrency()); } if (Strings.isNullOrEmpty(balanceSaveEntity.getTransformCurrency()) && sysChannelBankTable == null) { balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency()); } if (balanceSaveEntity.getActivityDeposit() == null) { balanceSaveEntity.setActivityDeposit(0); } if (balanceSaveEntity.getCustomId() == null && balanceSaveEntity.getAddUser() != null) { balanceSaveEntity.setCustomId(balanceSaveEntity.getAddUser()); } //验证通道 if (channel == null) { throw new ServiceException(PayConstants.FINANCE_DEPOSIT_CHANNEL_NOT_EMPTY); } //获取通道银行列表 if (sysChannelBankTable == null) { sysChannelBankTable = getChannelBank(balanceSaveEntity, channel); } //判断支付系统中是否已经计算过金额 如果为空 则在这里计算 BigDecimal transformAmount = getTransformAmount(balanceSaveEntity, channel); //验证订单金额是否在可入金额范围内 validatedAmount(balanceSaveEntity, channel, sysChannelBankTable); //获取用户信息 CustomInfoTable customInfoTable = getCustomInfo(balanceSaveEntity); //如果存在限制国家 if (!Strings.isNullOrEmpty(channel.getCountrys())) { //分割国家 List countrys = Arrays.asList(channel.getCountrys().split(",")); //判断国家 如果国家不在列表中 则拒绝 if (!countrys.contains(customInfoTable.getCountry())) { throw ServiceException.exception(Constants.NOT_PERMIT); } } //如果存在省份限制 if (!Strings.isNullOrEmpty(channel.getStates())) { //分割国家 List states = Arrays.asList(channel.getStates().split(",")); //判断国家 如果国家不在列表中 则拒绝 if (!states.contains(customInfoTable.getState())) { throw ServiceException.exception(Constants.NOT_PERMIT); } } //使用优惠码 //MarketPromoCodeTable marketPromoCodeTable = usePromoCode(balanceSaveEntity, customInfoTable); //获取交易账号信息 //CustomLoginTable customLoginTable = getCustomLogin(balanceSaveEntity); //验证是否信用可亏损 //validatedCreditLoss(balanceSaveEntity, customLoginTable, marketPromoCodeTable); //设置入金实体的汇率 setFinanceDepositAddRate(balanceSaveEntity, channel, sysChannelBankTable); Long cId = customInfoTable.getCId(); //构建订单 FinanceDepositTable financeDepositTable = new FinanceDepositTable(); financeDepositTable.setCustomId(balanceSaveEntity.getCustomId()); financeDepositTable.setCId(cId); financeDepositTable.setCallbackValidateMq(balanceSaveEntity.getCallbackValidateMq()); if (balanceSaveEntity.getCallbackValidate() != null) { financeDepositTable.setCallbackValidate(2); } else { financeDepositTable.setCallbackValidate(null); } financeDepositTable.setDepositCurrency(balanceSaveEntity.getCurrency()); //financeDepositTable.setPromoCode(balanceSaveEntity.getPromoCode()); financeDepositTable.setBankMsg(balanceSaveEntity.getBankMsg()); financeDepositTable.setCallbackMq(balanceSaveEntity.getCallbackMq()); financeDepositTable.setExtParam(balanceSaveEntity.getExtParam()); financeDepositTable.setAmount(balanceSaveEntity.getAmount()); financeDepositTable.setStatus(PayConstants.APPLY_STATUS); financeDepositTable.setCallbackStatus(PayConstants.CALLBACE_PROCESSING_STATUS); financeDepositTable.setDepositStatus(PayConstants.MANAGER_PENDING_STATUS); financeDepositTable.setSubmitStatus(PayConstants.SUBMIT_PENDING_STATUS); financeDepositTable.setBankCode(balanceSaveEntity.getBankCode()); financeDepositTable.setPayType(balanceSaveEntity.getPayType()); financeDepositTable.setCurrency(balanceSaveEntity.getCurrency()); financeDepositTable.setTransformCurrency(balanceSaveEntity.getTransformCurrency()); financeDepositTable.setVoucherUrl(balanceSaveEntity.getVoucherUrl()); financeDepositTable.setActivityDeposit(balanceSaveEntity.getActivityDeposit()); if (balanceSaveEntity.getActivityDeposit() != null && balanceSaveEntity.getActivityDeposit().equals(1)) { financeDepositTable.setActivityStatus(1); } else { financeDepositTable.setActivityStatus(2); } if ("cny".equals(financeDepositTable.getTransformCurrency().toLowerCase()) || "thb".equals(financeDepositTable.getTransformCurrency().toLowerCase()) || "vnd".equals(financeDepositTable.getTransformCurrency().toLowerCase())) { transformAmount = transformAmount.divide(BigDecimal.ONE, 0, BigDecimal.ROUND_UP); } //获取订单用户名称 String name = customInfoTable.getName(); String orderNo = getOrderNo(); //获取和处理入金平台订单 Integer free = getFree(channel, sysChannelBankTable); BigDecimal depositAmount = getDepositAmount(financeDepositTable); if (free != null && free.compareTo(0) > 0) { depositAmount = depositAmount.multiply(new BigDecimal(1 - (free / 100.0))); } BigDecimal cnyAmount = getCnyAmount(balanceSaveEntity); financeDepositTable.setRate(balanceSaveEntity.getRate()); financeDepositTable.setTransformAmount(transformAmount); financeDepositTable.setCny(cnyAmount); financeDepositTable.setDepositAmount(depositAmount.setScale(2, BigDecimal.ROUND_DOWN)); financeDepositTable.setFree(free); financeDepositTable.setSerial(orderNo); financeDepositTable.setLogin(balanceSaveEntity.getLogin()); financeDepositTable.setName(name); //计算过期时间 如果通道设置中过期时间为0或者null 标识用不过期 这里也就不设置设置为null或者设置时间戳为0 if (channel.getExpire() != null & !channel.getExpire().equals(0)) { financeDepositTable.setExpireTime(DateUtil.operationMinute(channel.getExpire())); } financeDepositTable.setRemittanceChannelCode(channel.getCode()); financeDepositTable.setRemittanceChannelName(channel.getName()); financeDepositTable.setRemittanceChannelEnName(channel.getEnName()); financeDepositTable.setRemittanceChannelIcon(channel.getIcon()); financeDepositTable.setRemittanceChannelEnIcon(channel.getEnIcon()); financeDepositTable.setRemittanceChannelCurrency(channel.getCurrency()); financeDepositTable.setRemittanceChannelRequestUrl(channel.getRequestUrl()); financeDepositTable.setRemittanceChannelProperty(channel.getProperty()); financeDepositTable.setRemittanceChannelIntroduce(channel.getIntroduce()); financeDepositTable.setRemittanceChannelEnIntroduce(channel.getEnIntroduce()); financeDepositTable.setAddIp(balanceSaveEntity.getAddIp()); financeDepositTable.setAddTime(balanceSaveEntity.getAddTime()); financeDepositTable.setAddUser(balanceSaveEntity.getAddUser()); financeDepositTable.setCountry(customInfoTable.getCountry()); financeDepositTable.setCountryEnName(customInfoTable.getCountryEnName()); financeDepositTable.setCountryName(customInfoTable.getCountryName()); /*financeDepositTable.setSourceCode(customInfoTable.getSourceCode()); financeDepositTable.setSourceName(customInfoTable.getSourceName()); financeDepositTable.setSourceNameEn(customInfoTable.getSourceNameEn());*/ //保存订单信息 financeDepositRepository.save(financeDepositTable); GoldenOrderTable order = saveGoldenOrder(balanceSaveEntity, goodsTables, financeDepositTable); //mqSendService.send(PayConstants.ORDER_DEPOSIT_EXPIRE, order, channel.getExpire() * 1000); return financeDepositTable; } @Transactional(rollbackFor = Exception.class) public GoldenOrderTable saveGoldenOrder(FinanceDepositAddEntity balanceSaveEntity, List goodsTables,FinanceDepositTable financeDepositTable){ GoldenOrderTable order = new GoldenOrderTable(); order.setSerial(financeDepositTable.getSerial()); order.setCustomId(financeDepositTable.getCustomId()); order.setAmount(financeDepositTable.getAmount()); order.setCurrency(financeDepositTable.getCurrency()); order.setTransformAmount(financeDepositTable.getAmount()); order.setTransformCurrency(financeDepositTable.getCurrency()); order.setAddTime(financeDepositTable.getAddTime()); order.setStatus(PayConstants.ORDER_UP_PAY_STATUS); order.setPayName(balanceSaveEntity.getPayName()); order.setPayPhone(balanceSaveEntity.getPayPhone()); order.setChannelCode(financeDepositTable.getRemittanceChannelCode()); order.setChannelName(financeDepositTable.getRemittanceChannelName()); order.setChannelEnName(financeDepositTable.getRemittanceChannelEnName()); goldenOrderRepository.save(order); List details = new ArrayList<>(); for (GoldenGoodsTable goldenGoodsTable : goodsTables) { GoldenOrderDetailsTable detailsTable = new GoldenOrderDetailsTable(); BeanUtils.copyProperties(goldenGoodsTable, detailsTable); detailsTable.setGoodsId(goldenGoodsTable.getId()); detailsTable.setSerial(financeDepositTable.getSerial()); detailsTable.setCustomId(financeDepositTable.getCustomId()); details.add(detailsTable); } goldenOrderDetailsRepository.save(details); return order; } @Override public void save(FinanceDepositTable financeDepositTable) throws ServiceException, PayValidatedException { financeDepositRepository.save(financeDepositTable); } @Override @Transactional(rollbackFor = Exception.class) public void updateCallbackValidate(FinanceDepositCallbackValidateUpdateEntity financeDepositUpdateEntity) throws ServiceException { FinanceDepositTable financeDepositTable = financeDepositRepository.findFirstBySerial(financeDepositUpdateEntity.getSerial()); if (financeDepositTable == null) { return; } financeDepositUpdateEntity.setId(financeDepositTable.getId()); BeanUtils.copyProperties(financeDepositUpdateEntity, financeDepositTable); if (!PayConstants.CALLBACE_VALIDATE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackValidate())) { financeDepositTable.setCallbackStatus(PayConstants.CALLBACE_FAIL_STATUS); financeDepositTable.setNote("95"); } financeDepositRepository.save(financeDepositTable); } @Override @Transactional(rollbackFor = Exception.class) public FinanceDepositTable approve(FinanceDepositApproveEntity entity) throws ServiceException { FinanceDepositTable financeDepositTable = financeDepositRepository.findFirstById(entity.getId()); if (financeDepositTable == null) { throw ServiceException.exception(Constants.INFO_NOT_FOUND); } if (!StatusConstants.MANAGER_PENDING_STATUS.equals(financeDepositTable.getDepositStatus()) || !StatusConstants.APPLY_STATUS.equals(financeDepositTable.getStatus())) { throw ServiceException.exception(Constants.CANNOT_APPROVE); } if (entity.getAmount() == null && entity.getCny() == null) { entity.setCny(financeDepositTable.getCny()); entity.setAmount(financeDepositTable.getAmount()); } else if (entity.getAmount() != null) { entity.setCny(entity.getAmount().multiply(financeDepositTable.getRate())); } else if (entity.getCny() != null) { BigDecimal amount = entity.getCny().divide(financeDepositTable.getRate(), 10, BigDecimal.ROUND_HALF_UP); entity.setAmount(amount); } BeanUtils.copyProperties(entity, financeDepositTable); financeDepositRepository.save(financeDepositTable); // if (StatusConstants.PASSED_STATUS.equals(financeDepositTable.getStatus()) // && StatusConstants.MANAGER_COMPLETED_STATUS.equals(financeDepositTable.getDepositStatus())) { // // } CustomInfoTable customInfoTable = customInfoRepository.findFirstById(financeDepositTable.getCustomId()); if (customInfoTable == null) { throw new ServiceException(Constants.USER_NOT_EXIST_ERROR); } //调整客户是否有入金成功 if (StatusConstants.PASSED_STATUS.equals(entity.getStatus())) { if (customInfoTable.getPayStatus() == null || !customInfoTable.getPayStatus().equals(1)) { customInfoTable.setPayStatus(1); customInfoRepository.save(customInfoTable); } } sendCustomDepositEmail(financeDepositTable, customInfoTable); return financeDepositTable; } @Override @Transactional(rollbackFor = Exception.class) public void delete(FinanceDepositDeleteEntity entity) throws ServiceException { List allByIdIn = financeDepositRepository.findAllByIdIn(entity.getIds()); if (allByIdIn == null || allByIdIn.size() <= 0) { throw ServiceException.exception(Constants.INFO_NOT_FOUND); } financeDepositRepository.delete(allByIdIn); } @Override public ResultWithPagerDto searchPageList(FinanceDepositSearchListEntity entity) throws ServiceException { Integer count = financeDepositMapper.countList(entity); PageDto pageDto = PageDto.format(entity, count); if (count == null || count <= 0) { return ResultWithPagerDto.success(pageDto); } BaseResultDto> listBaseResultDto = searchList(entity); return ResultWithPagerDto.success(pageDto, listBaseResultDto.getData()); } @Override public BaseResultDto> searchList(FinanceDepositSearchListEntity entity) throws ServiceException { List financeDepositViews = financeDepositMapper.searchList(entity); if (financeDepositViews == null || financeDepositViews.size() <= 0) { throw new ServiceException(Constants.SYSTEM_ERROR); } List financeDepositDtos = new ArrayList<>(financeDepositViews.size()); for (FinanceDepositView financeDepositView : financeDepositViews) { FinanceDepositDto transform = transform(financeDepositView); financeDepositDtos.add(transform); } return BaseResultDto.success(financeDepositDtos); } @Override public FinanceDepositDto searchSingle(Long id) throws ServiceException { FinanceDepositView financeDepositMapperSingle = financeDepositMapper.getOne(id); if (financeDepositMapperSingle == null) { throw ServiceException.exception(Constants.INFO_NOT_FOUND); } return transform(financeDepositMapperSingle); } @Override @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) public void updateCallback(FinanceDepositCallbackUpdateEntity financeDepositCallbackUpdateEntity) throws ServiceException { String lockKey = "FINANCE_DEPOSIT:"; if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getSerial())) { lockKey = lockKey + financeDepositCallbackUpdateEntity.getSerial(); } else if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getTicket())) { lockKey = lockKey + financeDepositCallbackUpdateEntity.getTicket(); } else { throw ServiceException.exception(Constants.SYSTEM_ERROR); } String co = UUIDUtil.getUUID(); try { if (redisService.tryLock(lockKey, co, 60 * 1000)) { //获取订单 FinanceDepositTable financeDepositTable = null; if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getSerial())) { financeDepositTable = financeDepositRepository.findFirstBySerial(financeDepositCallbackUpdateEntity.getSerial()); } else if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getTicket())) { financeDepositTable = financeDepositRepository.findFirstByChannelSerial(financeDepositCallbackUpdateEntity.getTicket()); } else { throw ServiceException.exception(Constants.SYSTEM_ERROR); } if (financeDepositTable == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } CustomInfoTable customTable = customInfoRepository.findFirstById(financeDepositTable.getCustomId()); if (customTable == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } GoldenOrderTable orderTable = goldenOrderRepository.findFirstBySerial(financeDepositCallbackUpdateEntity.getSerial()); if (orderTable == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } if (!isIpWhitelist(financeDepositTable.getRemittanceChannelCode())) { throw ServiceException.exception("ip error"); } if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) { return; } //填充订单数据 if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getChannelSerial())) { financeDepositTable.setChannelSerial(financeDepositCallbackUpdateEntity.getChannelSerial()); } financeDepositTable.setStatus(financeDepositCallbackUpdateEntity.getStatus()); financeDepositTable.setCallbackStatus(financeDepositCallbackUpdateEntity.getCallbackStatus()); financeDepositTable.setModifyTime(new Date()); financeDepositTable.setCallbackTime(financeDepositCallbackUpdateEntity.getCallbackTime() == null ? new Date() : financeDepositCallbackUpdateEntity.getCallbackTime()); financeDepositTable.setNote(financeDepositCallbackUpdateEntity.getNote()); if (financeDepositCallbackUpdateEntity.getRate() != null) { financeDepositTable.setRate(financeDepositCallbackUpdateEntity.getRate()); } //根据回调实体中是否有金额判断回调订单金额可能存在变动 并再次进行计算填充 if (financeDepositCallbackUpdateEntity.getAmount() != null) { financeDepositTable.setAmount(financeDepositCallbackUpdateEntity.getAmount()); if (financeDepositCallbackUpdateEntity.getTransformAmount() != null) { financeDepositTable.setTransformAmount(financeDepositCallbackUpdateEntity.getTransformAmount()); } else { BigDecimal rate = financeDepositTable.getRate(); BigDecimal transformAmount = financeDepositCallbackUpdateEntity.getAmount().multiply(rate); financeDepositTable.setTransformAmount(transformAmount); } } else if (financeDepositCallbackUpdateEntity.getTransformAmount() != null) { if (financeDepositCallbackUpdateEntity.getTransformAmount().compareTo(financeDepositTable.getTransformAmount()) != 0) { financeDepositTable.setTransformAmount(financeDepositCallbackUpdateEntity.getTransformAmount()); BigDecimal rate = financeDepositTable.getRate(); BigDecimal amount = financeDepositTable.getTransformAmount().divide(rate, 10, BigDecimal.ROUND_HALF_UP); financeDepositTable.setAmount(amount); } else { financeDepositCallbackUpdateEntity.setTransformAmount(null); } } if (financeDepositCallbackUpdateEntity.getAmount() != null || financeDepositCallbackUpdateEntity.getTransformAmount() != null) { BigDecimal depositAmount = getDepositAmount(financeDepositTable); Integer free = financeDepositTable.getFree(); if (free != null && free.compareTo(0) > 0) { depositAmount = depositAmount.multiply(new BigDecimal(1 - (free / 100.0))); } financeDepositTable.setDepositAmount(depositAmount); BigDecimal cnyAmount = getCnyAmount(financeDepositTable); financeDepositTable.setCny(cnyAmount); } //保存回调数据 financeDepositTable.setCallbackData(financeDepositCallbackUpdateEntity.getCallbackData()); financeDepositTable.setModifyIp(getIp()); if (StringUtils.isNotEmpty(financeDepositCallbackUpdateEntity.getApproveDesc())) { financeDepositTable.setApproveDesc(financeDepositCallbackUpdateEntity.getApproveDesc()); financeDepositTable.setOperationType(PayConstants.OPERATION_TYPE_AUTOMATIC); financeDepositTable.setApproveTime(new Date()); } //更新订单 financeDepositRepository.save(financeDepositTable); //成功处理 if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) { BigDecimal totalSpendingAmount = customTable.getTotalSpendingAmount() == null ? BigDecimal.ZERO : customTable.getTotalSpendingAmount(); customTable.setTotalSpendingAmount(totalSpendingAmount.add(financeDepositTable.getAmount())); customInfoRepository.save(customTable); orderTable.setStatus(PayConstants.ORDER_PAY_STATUS); orderTable.setPayTime(financeDepositTable.getCallbackTime()); } else if (PayConstants.CALLBACE_FAIL_STATUS.equals(financeDepositTable.getCallbackStatus())) { orderTable.setStatus(PayConstants.ORDER_PAY_ERROR_STATUS); } orderTable.setModifyTime(new Date()); goldenOrderRepository.save(orderTable); if (customTable.getTotalSpendingAmount().compareTo(new BigDecimal(5000)) >= 0) { mqSendService.send(ConfigConstants.CUSTOM_REWARD_RECORD, customTable.getId()); } if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) { List detailsTables = goldenOrderDetailsRepository.getBySerial(financeDepositTable.getSerial()); for (GoldenOrderDetailsTable detailsTable : detailsTables) { sendCustomGoldenOrderEmail(financeDepositTable,detailsTable,customTable.getEmail()); } } } } catch (Exception e) { log.error(e.getMessage()); throw ServiceException.exception(Constants.SYSTEM_ERROR); } finally { redisService.unlock(lockKey, co); } } @Override public boolean isIpWhitelist(String channelCode) throws ServiceException { SysRemittanceChannelTable payChannel = sysRemittanceChannelRepository.getFirstByCode(channelCode); if (payChannel == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } if (Strings.isNullOrEmpty(payChannel.getWhitelist())) { return true; } String ip = getIp(); if (Strings.isNullOrEmpty(ip)) { return false; } log.info(String.format("pay callback,Whitelist error,Whitelist :%s,ip:%s", payChannel.getWhitelist(), ip)); if (Arrays.asList(payChannel.getWhitelist().split(",")).contains(ip)) { return true; } log.info(String.format("pay callback,Whitelist error")); return false; } /** * 获取通道银行信息 * * @param balanceSaveEntity * @param channel * @return * @throws ServiceException */ @Override public SysChannelBankTable getChannelBank(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel) throws ServiceException { SysChannelBankTable sysChannelBankTable = null; if (channel.getBankValid() != null && channel.getBankValid().equals(1)) { if (!Strings.isNullOrEmpty(balanceSaveEntity.getBankCode())) { sysChannelBankTable = sysChannelBankService.getByCode(balanceSaveEntity.getBankCode(), channel.getCode()); if (sysChannelBankTable == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } balanceSaveEntity.setTransformCurrency(sysChannelBankTable.getCurrency()); } else { throw new ServiceException(Constants.SYSTEM_ERROR); } } return sysChannelBankTable; } @Override @Transactional(rollbackFor = Exception.class) public FinanceDepositTable getBySerial(String serial) throws ServiceException { FinanceDepositTable financeDepositTable = financeDepositRepository.getFirstBySerial(serial); if (financeDepositTable == null) { throw ServiceException.exception(Constants.INFO_NOT_FOUND); } return financeDepositTable; } @Override public FinanceDepositTable getByChannelSerial(String channelSerial) throws ServiceException { FinanceDepositTable financeDepositTable = financeDepositRepository.getFirstByChannelSerial(channelSerial); return financeDepositTable; } /** * 过期时间修改状态 * @param content * @throws ServiceException */ @JmsListener(destination = PayConstants.ORDER_DEPOSIT_EXPIRE) @Transactional(rollbackFor = Exception.class) public void orderDepositExpire(String content) throws ServiceException { log.info(String.format("ORDER_DEPOSIT_EXPIRE,content:%s", content)); GoldenOrderTable order = JSON.parseObject(content, GoldenOrderTable.class); if (order == null) { log.error("ORDER_DEPOSIT_EXPIRE,entity is null"); return; } GoldenOrderTable table = goldenOrderRepository.findFirstBySerial(order.getSerial()); if (table == null) { return; } if (table.getStatus() == PayConstants.ORDER_UP_PAY_STATUS) { table.setStatus(PayConstants.ORDER_PAY_EXPIRED_STATUS); table.setModifyTime(new Date()); goldenOrderRepository.save(table); } } private FinanceDepositDto transform(FinanceDepositView financeDepositView) { FinanceDepositDto financeDepositDto = new FinanceDepositDto(); BeanUtils.copyProperties(financeDepositView, financeDepositDto); return financeDepositDto; } private void sendDepositEmail(FinanceDepositTable table) throws ServiceException { SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_DEPOSIT_MANAGER_EMAIL); if (sysConfigTable == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } String users = sysConfigTable.getValue(); if (users == null) { throw new ServiceException(Constants.SYSTEM_ERROR); } //构建map 用于后面邮件模版替换 Map map = new HashMap<>(10); map.put(MapConstants.LOGIN, table.getLogin() + ""); map.put(MapConstants.NAME, table.getName()); map.put(MapConstants.DEPOSIT_AMOUNT, table.getAmount() == null ? "" : String.format("%.2f", table.getAmount().doubleValue())); map.put(MapConstants.APPLY_TIME, DateUtil.formatTime(table.getAddTime())); map.put(MapConstants.SERIAL, table.getSerial()); map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date())); SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity(); sysEmailSendEntity.setSubject("CWG DEPOSIT"); sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.FINANCE_DEPOSIT_NOTICE); sysEmailSendEntity.setMap(map); sysEmailSendEntity.setTemplateName(EmailTemplateConstants.FINANCE_DEPOSIT_NOTICE_NAME); sysEmailSendEntity.setUsers(users); try { emailService.sendEmail(sysEmailSendEntity); } catch (Exception e) { e.printStackTrace(); } } private void sendCustomDepositEmail(FinanceDepositTable table, CustomInfoTable customInfoTable) throws ServiceException { //构建map 用于后面邮件模版替换 Map map = new HashMap<>(10); String name = CustomInfoUtil.getName(customInfoTable); map.put(MapConstants.NAME, name); map.put(MapConstants.LOGIN, String.valueOf(table.getLogin())); map.put(MapConstants.DEPOSIT_AMOUNT, table.getAmount() == null ? "" : String.format("%.2f", table.getAmount().doubleValue())); map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date())); map.put(MapConstants.APPROVE_DESC, table.getApproveDesc()); map.put(MapConstants.APPROVE_STATUS, table.getStatus().equals(2) ? "通过" : "拒绝"); SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity(); sysEmailSendEntity.setSubject("CWG DEPOSIT"); sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_FINANCE_DEPOSIT_NOTICE); sysEmailSendEntity.setMap(map); sysEmailSendEntity.setTemplateName(EmailTemplateConstants.FINANCE_DEPOSIT_APPROVE_NOTICE_RESULT); sysEmailSendEntity.setUsers(customInfoTable.getEmail()); try { emailService.sendEmail(sysEmailSendEntity); WebNoticeRecordAndEmailMqEntity mqEntity = new WebNoticeRecordAndEmailMqEntity(sysEmailSendEntity, table.getCId(), table.getCustomId()); mqSendService.send(Constants.WEB_NOTICE_PUT_RECORD, mqEntity); } catch (Exception e) { e.printStackTrace(); } } private void sendCustomGoldenOrderEmail(FinanceDepositTable table, GoldenOrderDetailsTable detailsTable,String email) throws ServiceException { //构建map 用于后面邮件模版替换 Map map = new HashMap<>(3); String name = table.getName(); map.put(MapConstants.NAME, name); map.put(ConfigConstants.DOWNLOAD_URL, detailsTable.getDownload()); map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date())); SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity(); sysEmailSendEntity.setSubject("Trading Education"); sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_ORDER_SUCCESS); sysEmailSendEntity.setMap(map); if (CountryUtil.isCN(table.getCountry())) { sysEmailSendEntity.setTemplateName(EmailTemplateConstants.CUSTOM_ORDER_SUCCESS_CN); } else { sysEmailSendEntity.setTemplateName(EmailTemplateConstants.CUSTOM_ORDER_SUCCESS_EN); } sysEmailSendEntity.setUsers(email); try { emailService.sendEmail(sysEmailSendEntity); WebNoticeRecordAndEmailMqEntity mqEntity = new WebNoticeRecordAndEmailMqEntity(sysEmailSendEntity, table.getCId(), table.getCustomId()); mqSendService.send(Constants.WEB_NOTICE_PUT_RECORD, mqEntity); } catch (Exception e) { e.printStackTrace(); } } private SysConfigFinanceEntity getConfigFinance() throws ServiceException { SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_CONFIGURE); SysConfigFinanceEntity financeEntity = JSON.parseObject(sysConfigTable.getValue(), SysConfigFinanceEntity.class); if (financeEntity == null) { throw ServiceException.exception(Constants.SYSTEM_ERROR); } return financeEntity; } /** * 验证最大和最小入金量 * * @param balanceSaveEntity * @throws ServiceException */ private void validatedAmount(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel, SysChannelBankTable sysChannelBankTable) throws ServiceException, PayValidatedException { BigDecimal max = null; BigDecimal min = null; List excludeCodes = null; List codes = new ArrayList<>(2); //获取自动时段最大入金量 SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.AUTOLIMIT_DEPOSIT_CONFIG); SysConfigAutolimitEntity sysConfigAutolimitEntity = JSON.parseObject(sysConfigTable.getValue(), SysConfigAutolimitEntity.class); if (sysConfigAutolimitEntity == null) { throw ServiceException.exception(Constants.SYSTEM_ERROR); } if (sysConfigAutolimitEntity.getAutolimitVaild() != null && sysConfigAutolimitEntity.getAutolimitVaild().equals(1)) { //特定通道排除在外 if (!Strings.isNullOrEmpty(sysConfigAutolimitEntity.getExcludeCodes())) { excludeCodes = Arrays.asList(sysConfigAutolimitEntity.getExcludeCodes().split(",")); } //验证时间在那个区间 if (excludeCodes == null || !excludeCodes.contains(balanceSaveEntity.getPayType())) { Date newDate = new Date(); Time newTime = Time.valueOf(newDate.getHours() + ":" + newDate.getMinutes() + ":" + newDate.getSeconds()); if (newTime.getTime() > sysConfigAutolimitEntity.getStartTime().getTime() && newTime.getTime() < sysConfigAutolimitEntity.getEndTime().getTime()) { max = sysConfigAutolimitEntity.getWithinIntervalAmount(); } else { max = sysConfigAutolimitEntity.getOutRangeAmount(); } } } //判断银行(货币)通道上是否携带最大最小入金量 if (sysChannelBankTable != null) { if (sysChannelBankTable.getMinAmount() != null) { min = sysChannelBankTable.getMinAmount(); } if (sysChannelBankTable.getMaxAmount() != null) { max = sysChannelBankTable.getMaxAmount(); } } //判断通道上是否携带最大入金量 if (max == null) { if (channel.getMaxAmount() == null) { codes.add(ConfigConstants.FINANCE_DEPOSIT_MAX); } else { max = channel.getMaxAmount(); } } //判断通道上是否携带最小入金量 if (min == null) { if (channel.getMinAmount() == null) { codes.add(ConfigConstants.FINANCE_DEPOSIT_MIN); } else { min = channel.getMinAmount(); } } //如果最大最小入金量都没设置 则使用全局设置的最大最小入金量 if (codes.size() > 0) { List configTables = sysConfigService.getByCodes(codes); if (configTables == null || configTables.size() < codes.size()) { throw new ServiceException(Constants.SYSTEM_ERROR); } for (SysConfigTable configTable : configTables) { if (ConfigConstants.FINANCE_DEPOSIT_MAX.equals(configTable.getCode())) { try { max = new BigDecimal(configTable.getValue()); } catch (NumberFormatException e) { throw new ServiceException(Constants.SYSTEM_ERROR); } } if (ConfigConstants.FINANCE_DEPOSIT_MIN.equals(configTable.getCode())) { try { min = new BigDecimal(configTable.getValue()); } catch (NumberFormatException e) { throw new ServiceException(Constants.SYSTEM_ERROR); } } } } if (balanceSaveEntity.getAmount().intValue() < min.intValue()) { throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN, PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN) + min.intValue() + " " + channel.getCurrency()); } if (balanceSaveEntity.getAmount().intValue() > max.intValue()) { throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN, PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN) + max.intValue() + " " + channel.getCurrency()); } } private void validatedAmount(FinanceDepositAddEntity balanceSaveEntity, SysConfigFinanceEntity financeEntity) throws ServiceException, PayValidatedException { if (balanceSaveEntity.getAmount().intValue() < financeEntity.getMinDeposit().intValue()) { throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN, PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN) + financeEntity.getMinDeposit().intValue()); } if (balanceSaveEntity.getAmount().intValue() > financeEntity.getMaxDeposit().intValue()) { throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN , PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN) + financeEntity.getMaxDeposit().intValue()); } } /** * 获取交易账户 * * @param balanceSaveEntity * @return * @throws ServiceException */ private CustomLoginTable getCustomLogin(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException { CustomLoginTable customLoginTable = customLoginService.getByCustomIdAndLogin(balanceSaveEntity.getCustomId(), balanceSaveEntity.getLogin()); if (customLoginTable == null) { throw ServiceException.exception(Constants.NOT_PERMIT); } return customLoginTable; } /** * 获取客户信息 * * @param balanceSaveEntity * @return * @throws ServiceException */ private CustomInfoTable getCustomInfo(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException { CustomInfoTable customInfoTable = customInfoRepository.getFirstById(balanceSaveEntity.getCustomId()); if (customInfoTable == null) { throw new ServiceException(Constants.USER_NOT_EXIST_ERROR); } return customInfoTable; } /** * 获取实际通道使用金额 * * @param balanceSaveEntity * @return * @throws ServiceException */ private BigDecimal getTransformAmount(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel) throws ServiceException { //获取汇率 如果特定通道没有汇率 则根据我方设定汇率计算 BigDecimal rate; if (balanceSaveEntity.getRate() == null) { if (channel.getRate() == null) { if (balanceSaveEntity.getCurrency().equals(balanceSaveEntity.getTransformCurrency())) { rate = BigDecimal.ONE; } else { rate = financeRateService.getRate(balanceSaveEntity.getCurrency(), balanceSaveEntity.getTransformCurrency(), 0, 1); } } else { rate = channel.getRate(); } balanceSaveEntity.setRate(rate); } BigDecimal transformAmount = null; if (balanceSaveEntity.getTransformAmount() != null) { transformAmount = balanceSaveEntity.getTransformAmount(); BigDecimal amount = transformAmount.divide(balanceSaveEntity.getRate(), 2, BigDecimal.ROUND_DOWN); balanceSaveEntity.setAmount(amount); } else { transformAmount = balanceSaveEntity.getAmount().multiply(balanceSaveEntity.getRate()); } return transformAmount; } /** * 获取手续费 * * @param channel * @param sysChannelBankTable * @return */ private Integer getFree(SysRemittanceChannelTable channel, SysChannelBankTable sysChannelBankTable) { Integer free = null; //判断如果银行(支付货币)类型关闭且通道汇率不为空 且通道汇率大于0 或者银行(支付货币)开启且银行(支付货币)汇率不为空 且银行(支付货币)汇率大于0 if ((channel.getBankValid() == null || channel.getBankValid().compareTo(0) == 0) && channel.getFree() != null && channel.getFree().compareTo(0) > 0) { free = channel.getFree(); } if ((channel.getBankValid() != null && channel.getBankValid().compareTo(0) > 0) && sysChannelBankTable != null && sysChannelBankTable.getFree() != null && sysChannelBankTable.getFree().compareTo(0) > 0) { free = sysChannelBankTable.getFree(); } return free; } private void setFinanceDepositAddRate(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel, SysChannelBankTable sysChannelBankTable) { if (balanceSaveEntity.getRate() != null) { return; } if (sysChannelBankTable != null && sysChannelBankTable.getRate() != null) { balanceSaveEntity.setRate(sysChannelBankTable.getRate()); return; } if (channel != null && channel.getRate() != null) { balanceSaveEntity.setRate(channel.getRate()); return; } } /** * 获取平台入金金额 * * @param financeDepositTable * @return * @throws ServiceException */ private BigDecimal getDepositAmount(FinanceDepositTable financeDepositTable) throws ServiceException { BigDecimal depositAmount = null; if (financeDepositTable.getDepositCurrency().equals(financeDepositTable.getCurrency())) { depositAmount = financeDepositTable.getAmount(); } else { //获取汇率 如果特定通道没有汇率 则根据我方设定汇率计算 BigDecimal rate = financeRateService.getRate(financeDepositTable.getCurrency(), financeDepositTable.getDepositCurrency(), 0, 1); if (rate == null) { log.error(String.format("currency:%s,depositCurrency:%s,type:%d", financeDepositTable.getCurrency(), financeDepositTable.getDepositCurrency(), 0)); throw ServiceException.exception(); } depositAmount = financeDepositTable.getAmount().multiply(rate); } return depositAmount; } /** * 获取cny金额 * * @param financeDepositTable * @return * @throws ServiceException */ private BigDecimal getCnyAmount(FinanceDepositTable financeDepositTable) throws ServiceException { BigDecimal cnyAmount = null; if ("CNY".equals(financeDepositTable.getTransformCurrency().toUpperCase())) { return financeDepositTable.getTransformAmount(); } BigDecimal cnyRate = financeRateService.getRate(financeDepositTable.getCurrency(), "CNY", 0, 1); if (cnyRate != null) { cnyAmount = financeDepositTable.getAmount().multiply(cnyRate); } return cnyAmount; } private BigDecimal getCnyAmount(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException { BigDecimal cnyAmount = null; BigDecimal cnyRate = financeRateService.getRate(balanceSaveEntity.getCurrency(), "CNY", 0, 1); if (cnyRate != null) { cnyAmount = balanceSaveEntity.getAmount().multiply(cnyRate); } return cnyAmount; } protected String getIp() throws ServiceException { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); if (requestAttributes == null) { return null; } HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); if (request == null) { return null; } String ip = GetIpAndMac.getIp(request); return ip; } /** * 生成订单号 * * @return 订单号 */ private String getOrderNo() { /** * 生成订单号 */ String orderNo = GetRandom.getOrderNo(PayConstants.DEPOSIT_HEAD); return orderNo; } }