@Transactional(rollbackFor = Exception.class) public void overdueRepay(String repayId, String repayerId) throws InsufficientBalance, OverdueRepayException { LoanRepay lr = ht.get(LoanRepay.class, repayId); ht.evict(lr); lr = ht.get(LoanRepay.class, repayId, LockMode.UPGRADE); if (lr.getStatus().equals(LoanConstants.RepayStatus.OVERDUE) || lr.getStatus().equals(LoanConstants.RepayStatus.BAD_DEBT) || lr.getStatus().equals(RepayStatus.WAIT_REPAY_VERIFY)) { List<InvestRepay> irs = ht.find( "from InvestRepay ir where ir.invest.loan.id=? and ir.period=?", new Object[] {lr.getLoan().getId(), lr.getPeriod()}); double defaultInterest = lr.getDefaultInterest(); HashSet<Invest> invests = new HashSet<Invest>(); // 更改投资的还款信息 for (InvestRepay ir : irs) { ir.setStatus(LoanConstants.RepayStatus.COMPLETE); ir.setTime(new Date()); ht.update(ir); invests.add(ir.getInvest()); userBillBO.transferIntoBalance( ir.getInvest().getUser().getId(), ArithUtil.add(ir.getCorpus(), ir.getInterest(), ir.getDefaultInterest()), OperatorInfo.OVERDUE_REPAY, "投资:" + ir.getInvest().getId() + "收到还款, 还款ID:" + lr.getId() + " 借款ID:" + lr.getLoan().getId() + " 本金:" + ir.getCorpus() + " 利息:" + ir.getInterest() + " 罚息:" + ir.getDefaultInterest()); // 系统回收体验金 if (ir.getCorpusToSystem() != null && ir.getCorpusToSystem() > 0) { systemBillService.transferInto( ir.getCorpusToSystem(), OperatorInfo.OVERDUE_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,回收体验金, 还款ID:" + ir.getId()); } defaultInterest = ArithUtil.sub(defaultInterest, ir.getDefaultInterest()); // 投资者手续费 userBillBO.transferOutFromBalance( ir.getInvest().getUser().getId(), ir.getFee(), OperatorInfo.OVERDUE_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,扣除手续费, 还款ID:" + lr.getId()); systemBillService.transferInto( ir.getFee(), OperatorInfo.OVERDUE_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,扣除手续费, 还款ID:" + lr.getId() + ",项目ID:" + ir.getInvest().getLoan().getId()); } // 更改借款的还款信息 double payMoney = ArithUtil.add( ArithUtil.add(lr.getCorpus(), lr.getInterest()), lr.getFee(), lr.getDefaultInterest()); lr.setTime(new Date()); lr.setStatus(LoanConstants.RepayStatus.COMPLETE); // 记录repayWay信息,还款者id,如果有此id,则为代偿 lr.setRepayWay(repayerId); // 代偿账户,扣除还款。 userBillBO.transferOutFromBalance( repayerId, payMoney, OperatorInfo.OVERDUE_REPAY, "借款:" + lr.getLoan().getId() + "逾期还款, 还款ID:" + lr.getId() + " 本金:" + lr.getCorpus() + " 利息:" + lr.getInterest() + " 手续费:" + lr.getFee() + " 罚息:" + lr.getDefaultInterest()); // 借款者手续费 systemBillService.transferInto( lr.getFee(), OperatorInfo.OVERDUE_REPAY, "项目ID:" + lr.getLoan().getId() + "逾期还款,扣除手续费, 还款ID:" + lr.getId()); // 罚息转入网站账户 systemBillService.transferInto( defaultInterest, OperatorInfo.OVERDUE_REPAY, "项目ID:" + lr.getLoan().getId() + "逾期还款,扣除罚金, 还款ID:" + lr.getId()); ht.merge(lr); Long count = (Long) ht.find( "select count(repay) from LoanRepay repay where repay.loan.id=? and (repay.status=? or repay.status=?)", lr.getLoan().getId(), RepayStatus.OVERDUE, RepayStatus.BAD_DEBT) .get(0); if (count == 0) { // 如果没有逾期或者坏账的还款,则更改借款状态。 lr.getLoan().setStatus(LoanStatus.REPAYING); ht.update(lr.getLoan()); for (Invest invest : invests) { invest.setStatus(InvestStatus.REPAYING); ht.update(invest); } } // 如果不是自己还款,则产生代偿 if (!lr.getLoan().getUser().getId().equals(repayerId)) { RepayCompensation rc = new RepayCompensation(); rc.setId(IdGenerator.randomUUID()); rc.setLoanRepay(lr); rc.setRepayer(new User(repayerId)); rc.setCompensateTime(new Date()); rc.setStatus(CompensationStatus.COMPENSATED); ht.save(rc); } // 判断是否所有还款结束,更改等待还款的投资状态和还款状态,还有项目状态。 loanService.dealComplete(lr.getLoan().getId()); try { cancelTransfering(lr.getLoan().getId()); } catch (RepayException e) { throw new OverdueRepayException(e.getMessage(), e.getCause()); } } else { throw new OverdueRepayException("还款不处于逾期还款状态"); } }
@SuppressWarnings("unchecked") @Override @Transactional(rollbackFor = Exception.class) public void receiveOperationS2SCallback(ServletRequest request, ServletResponse response) { try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } String respXML = request.getParameter("notify"); // 响应的参数 为xml格式 log.debug("债权转让s2sCallback respXML:" + respXML.toString()); String sign = request.getParameter("sign"); // 签名 boolean flag = CFCASignUtil.isVerifySign(respXML, sign); if (flag) { // 验签成功 Map<String, String> map = Dom4jUtil.xmltoMap(respXML); String code = map.get("code"); String requestNo = map.get("requestNo").replaceFirst(YeePayConstants.RequestNoPre.TRANSFER, ""); if ("1".equals(code)) { // 易宝冻结金额成功 TrusteeshipOperation to = trusteeshipOperationBO.get(YeePayConstants.OperationType.TRANSFER, requestNo, "yeepay"); ht.evict(to); to = trusteeshipOperationBO.get(YeePayConstants.OperationType.TRANSFER, requestNo, "yeepay"); ht.evict(to); to = ht.get(TrusteeshipOperation.class, to.getId(), LockMode.UPGRADE); String[] params = to.getOperator().split("&"); Invest invest = ht.get(Invest.class, requestNo); // 债权购买人购买的债权转换成的一笔投资 TransferApply ta = ht.get(TransferApply.class, invest.getTransferApply().getId()); // 债权转让申请 if (TrusteeshipConstants.Status.PASSED.equals(to.getStatus())) { return; } // 调用易宝转账确认端口 boolean result = yeepayCpTransacionOperation.transactionComform( YeePayConstants.RequestNoPre.TRANSFER + requestNo, "CONFIRM"); if (result) { // 易宝转账确认成功 to.setStatus(TrusteeshipConstants.Status.PASSED); ht.update(to); /** * ***********************************平台操作begin************************************************** */ if (invest != null && ta != null) { invest.setStatus(InvestConstants.InvestStatus.REPAYING); invest.setTime(new Date()); // 成交时间 Invest orignInvest = ta.getInvest(); // 债权转让人转让的一笔投资 double investReaminCorpus = ArithUtil.sub(orignInvest.getMoney(), invest.getMoney()); // 原投资债权转让后剩余的投资金额 if (investReaminCorpus == 0.0) { orignInvest.setStatus(InvestStatus.COMPLETE); } orignInvest.setMoney(investReaminCorpus); double remainCorpus = transferService.calculateRemainCorpus(ta.getId()); // 未转出的本金 if (remainCorpus > 0.0) { // 债权未全部转出 ta.setStatus(TransferStatus.TRANSFERING); } else { // 债权全部转出 ta.setStatus(TransferStatus.TRANSFED); } // 债权的购买金额 double buyPrice = Double.parseDouble(params[0]); // 购买时候,扣除手续费,从转让人收到的金额中扣除。费用根据购买价格计算 double fee = feeConfigBO.getFee(FeePoint.TRANSFER, FeeType.FACTORAGE, null, null, buyPrice); // 购买时候,扣除手续费,从转让人收到的金额中扣除。费用根据购买价格计算 try { userBillBO.transferOutFromBalance( invest.getUser().getId(), buyPrice, OperatorInfo.TRANSFER_BUY, "债权:" + invest.getId() + "购买成功"); userBillBO.transferIntoBalance( ta.getInvest().getUser().getId(), buyPrice, OperatorInfo.TRANSFER, "债权:" + invest.getId() + "转让成功"); if (fee > 0.0) { sbs.transferInto(fee, OperatorInfo.TRANSFER, "购买债权手续费,编号:" + invest.getId()); userBillBO.transferOutFromBalance( ta.getInvest().getUser().getId(), fee, OperatorInfo.TRANSFER, "债权转让成功手续费,编号:" + ta.getId()); } } catch (InsufficientBalance e) { log.debug("s2sCallback债权转让平台划款时出错!"); // throw new RuntimeException("债权转让平台划款时出错!"); } ta.setInvest(orignInvest); ht.update(invest); ht.update(ta); double corpusRate = Double.parseDouble(params[1]); // 购买的本金占剩余本金的比例 generateTransferRepay( ta.getInvest().getInvestRepays(), invest, corpusRate); // 生成购买债权后的还款数据,调整之前的还款数据 /** * ***********************************平台操作end********************************************************* */ } } else { // 易宝转账确认失败 to.setStatus(TrusteeshipConstants.Status.REFUSED); ht.update(to); /** * ***********************************平台操作begin************************************************** * if(invest != null && ta != null){ * invest.setStatus(InvestConstants.InvestStatus.CANCEL); * ta.setStatus(TransferStatus.TRANSFERING); double buyPrice * =Double.parseDouble(params[0]) ;//债权的购买金额 try { * userBillBO.unfreezeMoney(invest.getUser().getId(),buyPrice,OperatorInfo.TRANSFER, "债权:" * + invest.getId()+ "购买失败"); } catch (InsufficientBalance e) { throw new * RuntimeException("购买债权:"+ invest.getId() + "失败,解冻金额时出错!"); } ht.update(invest); * ht.update(ta); } * ***********************************平台操作end************************************************** */ // throw new YeePayOperationException("债权转让易宝转账确认失败"); } } } else { // 验签失败 log.debug("债权转让验签失败"); } }
@Transactional(readOnly = false, rollbackFor = Exception.class) public void normalRepay(LoanRepay repay, String repayerId) throws InsufficientBalance, NormalRepayException { ht.evict(repay); repay = ht.get(LoanRepay.class, repay.getId(), LockMode.UPGRADE); // 正常还款 if (!(repay.getStatus().equals(LoanConstants.RepayStatus.REPAYING) && !(repay.getStatus().equals(LoanConstants.RepayStatus.REPAYING_BACK)))) { // 该还款不处于正常还款状态。 throw new NormalRepayException("还款:" + repay.getId() + "不处于正常还款状态。"); } List<InvestRepay> irs = ht.find( "from InvestRepay ir where ir.invest.loan.id=? and ir.period=?", new Object[] {repay.getLoan().getId(), repay.getPeriod()}); // TODO:投资的所有还款信息加和,判断是否等于借款的还款信息,如果不相等,抛异常 // 更改投资的还款信息 for (InvestRepay ir : irs) { ir.setStatus(LoanConstants.RepayStatus.COMPLETE); ir.setTime(new Date()); ht.update(ir); userBillBO.transferIntoBalance( ir.getInvest().getUser().getId(), ArithUtil.add(ir.getCorpus(), ir.getInterest()), OperatorInfo.NORMAL_REPAY, "投资:" + ir.getInvest().getId() + "收到还款, 还款ID:" + repay.getId() + " 借款ID:" + repay.getLoan().getId() + " 本金:" + ir.getCorpus() + " 利息:" + ir.getInterest()); if (ir.getCorpusToSystem() != null && ir.getCorpusToSystem() != 0) { // 系统回收体验金 systemBillService.transferInto( ir.getCorpusToSystem(), OperatorInfo.NORMAL_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,回收体验金, 还款ID:" + repay.getId()); } // 投资者手续费 userBillBO.transferOutFromBalance( ir.getInvest().getUser().getId(), ir.getFee(), OperatorInfo.NORMAL_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,扣除手续费, 还款ID:" + repay.getId()); systemBillService.transferInto( ir.getFee(), OperatorInfo.NORMAL_REPAY, "投资:" + ir.getInvest().getId() + "收到还款,扣除手续费, 还款ID:" + repay.getId() + ",项目ID:" + ir.getInvest().getLoan().getId()); } try { cancelTransfering(repay.getLoan().getId()); } catch (RepayException e) { throw new NormalRepayException(e.getMessage(), e.getCause()); } // 更改借款的还款信息 double payMoney = ArithUtil.add(ArithUtil.add(repay.getCorpus(), repay.getInterest()), repay.getFee()); repay.setTime(new Date()); repay.setStatus(LoanConstants.RepayStatus.COMPLETE); // 记录repayWay信息,还款者id,如果有此id,则为代偿 repay.setRepayWay(repayerId); // 借款者的账户,扣除还款。 userBillBO.transferOutFromBalance( repayerId, payMoney, OperatorInfo.NORMAL_REPAY, "借款:" + repay.getLoan().getId() + "正常还款, 还款ID:" + repay.getId() + " 本金:" + repay.getCorpus() + " 利息:" + repay.getInterest() + " 手续费:" + repay.getFee()); // 借款者手续费 systemBillService.transferInto( repay.getFee(), OperatorInfo.NORMAL_REPAY, "项目ID:" + repay.getLoan().getId() + "正常还款,扣除手续费, 还款ID:" + repay.getId()); ht.merge(repay); // 如果不是自己还款,则产生代偿 if (!repay.getLoan().getUser().getId().equals(repayerId)) { RepayCompensation rc = new RepayCompensation(); rc.setId(IdGenerator.randomUUID()); rc.setLoanRepay(repay); rc.setRepayer(new User(repayerId)); rc.setCompensateTime(new Date()); rc.setStatus(CompensationStatus.COMPENSATED); ht.save(rc); } // 判断是否所有还款结束,更改等待还款的投资状态和还款状态,还有项目状态。 loanService.dealComplete(repay.getLoan().getId()); }