...
|
...
|
@@ -15,6 +15,7 @@ import com.yohobuy.ufo.model.order.req.ManualDealRequest; |
|
|
import com.yohobuy.ufo.model.user.resp.AuthorizeResultRespVO;
|
|
|
import com.yohoufo.common.alarm.CommonAlarmEventPublisher;
|
|
|
import com.yohoufo.common.caller.UfoServiceCaller;
|
|
|
import com.yohoufo.common.utils.DateUtil;
|
|
|
import com.yohoufo.common.utils.TimeUtils;
|
|
|
import com.yohoufo.dal.order.*;
|
|
|
import com.yohoufo.dal.order.model.*;
|
...
|
...
|
@@ -36,11 +37,9 @@ import com.yohoufo.order.service.BuyerOrderPaymentService; |
|
|
import com.yohoufo.order.service.IPaymentService;
|
|
|
import com.yohoufo.order.service.MerchantOrderPaymentService;
|
|
|
import com.yohoufo.order.service.SellerOrderPaymentService;
|
|
|
import com.yohoufo.order.service.handler.BuyerCancelCompensateComputeHandler;
|
|
|
import com.yohoufo.order.service.handler.BuyerOrderPayDiffTimeHandler;
|
|
|
import com.yohoufo.order.service.pay.AbstractPayService;
|
|
|
import com.yohoufo.order.service.pay.alipay.AlipayOuyinService;
|
|
|
import com.yohoufo.order.service.pay.alipay.AlipayServiceAbstract;
|
|
|
import com.yohoufo.order.service.pay.wallet.WalletPayService;
|
|
|
import com.yohoufo.order.service.pay.weixin.WeixinMiniappPayService;
|
|
|
import com.yohoufo.order.service.pay.weixin.WeixinPayUFORealAppService;
|
...
|
...
|
@@ -65,6 +64,7 @@ import java.util.Objects; |
|
|
import java.util.function.BiFunction;
|
|
|
|
|
|
import static com.yohoufo.order.common.TransferCase.EARNEST_MONEY_TO_BUYER;
|
|
|
import static com.yohoufo.order.utils.ServiceExceptions.throwServiceExceptionIf;
|
|
|
|
|
|
@Service
|
|
|
public class PaymentServiceImpl implements IPaymentService {
|
...
|
...
|
@@ -385,13 +385,9 @@ public class PaymentServiceImpl implements IPaymentService { |
|
|
|
|
|
logger.info("transferSuccess 旧流水更新成功,准备加新流水 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
|
|
|
// 加新流水
|
|
|
tradeBills.setDealRelateId(tradeBills.getId());
|
|
|
tradeBills.setId(null);
|
|
|
tradeBills.setTradeStatus(100);
|
|
|
tradeBills.setCreateTime(now);
|
|
|
addTradeBills(tradeBills);
|
|
|
|
|
|
logger.info("transferSuccess 加新流水成功,准备修改转账状态 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
|
|
|
addSuccessTradeBills(tradeBills);
|
|
|
|
|
|
logger.info("transferSuccess 加新流水成功,准备修改转账状态 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
|
|
|
OrdersPayTransfer newTransfer = new OrdersPayTransfer();
|
|
|
newTransfer.setId(transfer.getId());
|
|
|
newTransfer.setStatus(1);
|
...
|
...
|
@@ -981,78 +977,73 @@ public class PaymentServiceImpl implements IPaymentService { |
|
|
public void manualDeal(ManualDealRequest req) {
|
|
|
logger.info("manualDeal人工打款开始参数req={}", req);
|
|
|
Integer tradeBillsId = req.getTradeBillsId();
|
|
|
if (tradeBillsId == null || tradeBillsId < 1) {
|
|
|
throw new ServiceException(400, "manualDeal:流水Id不合法");
|
|
|
}
|
|
|
if (req.getOperateUid() == null || req.getOperateUid() < 1) {
|
|
|
throw new ServiceException(400, "manualDeal:客服uid不合法");
|
|
|
}
|
|
|
if (StringUtils.isBlank(req.getOperateUname())) {
|
|
|
throw new ServiceException(400, "manualDeal:客服名称不合法");
|
|
|
}
|
|
|
TradeBills tradeBills = tradeBillsMapper.selectByPrimaryKey(tradeBillsId);
|
|
|
if (tradeBills == null) {
|
|
|
throw new ServiceException(400, "manualDeal:流水不存在");
|
|
|
}
|
|
|
if (tradeBills.getTradeStatus() == 100) {
|
|
|
throw new ServiceException(400, "manualDeal:该流水不是失败的");
|
|
|
}
|
|
|
if (tradeBills.getIncomeOutcome()==null || tradeBills.getIncomeOutcome()!=1) {
|
|
|
throw new ServiceException(400, "manualDeal:该流水不是退款类型");
|
|
|
}
|
|
|
// 查询处理过的
|
|
|
if (tradeBillsMapper.selectByDealRelateId(tradeBillsId) != null) {
|
|
|
throw new ServiceException(400, "manualDeal:该流水已经处理过");
|
|
|
}
|
|
|
long orderCode = tradeBills.getOrderCode();
|
|
|
String logTag = "manualDeal orderCode is " + orderCode + "tradeBillId is " + tradeBillsId;
|
|
|
AuthorizeResultRespVO account = getAlipayAccount(tradeBills.getUid());
|
|
|
if (account == null ||
|
|
|
(StringUtils.isBlank(account.getAlipayAccount()) && StringUtils.isBlank(account.getAlipayId()))) {
|
|
|
logger.warn("manualDealErr uid {} 没有获取到有效的支付宝账号", tradeBills.getUid());
|
|
|
throw new ServiceException(400, "uid[" + tradeBills.getUid() + "]没有获取到有效的支付宝账号");
|
|
|
}
|
|
|
String alipayAccount = null;
|
|
|
if(StringUtils.isNotBlank(account.getAlipayId())) {
|
|
|
logger.info("manualDeal uid {} 支付宝账号uid有值优先使用{}", tradeBills.getUid(), account.getAlipayId());
|
|
|
alipayAccount = account.getAlipayId();
|
|
|
} else if(StringUtils.isNotBlank(account.getAlipayAccount())) {
|
|
|
logger.info("manualDeal uid {} 支付宝账号uid无值使用账号{}", tradeBills.getUid(), account.getAlipayAccount());
|
|
|
alipayAccount = account.getAlipayAccount();
|
|
|
}
|
|
|
throwServiceExceptionIf(tradeBillsId == null || tradeBillsId < 1, 400, "流水Id不合法");
|
|
|
throwServiceExceptionIf(req.getOperateUid() == null || req.getOperateUid() < 1, 400, "客服uid不合法");
|
|
|
throwServiceExceptionIf(StringUtils.isBlank(req.getOperateUname()), 400, "客服名称不合法");
|
|
|
TradeBills tradeBills = tradeBillsMapper.selectByPrimaryKey(tradeBillsId);
|
|
|
throwServiceExceptionIf(tradeBills == null, 400, "流水不存在");
|
|
|
throwServiceExceptionIf(tradeBills.getTradeStatus() == 100, 400, "该流水不是失败的");
|
|
|
throwServiceExceptionIf(tradeBills.getIncomeOutcome() == null || tradeBills.getIncomeOutcome() != 1, 400, "该流水不是退款类型");
|
|
|
// 是否处理过的
|
|
|
throwServiceExceptionIf(Objects.nonNull(tradeBillsMapper.selectByDealRelateId(tradeBillsId)), 400, "该流水已经处理过");
|
|
|
|
|
|
|
|
|
BigDecimal amount = null;
|
|
|
String logTag = String.format("manual deal orderCode is %s tradeBillId is %s uid is %s",tradeBills.getOrderCode(),tradeBillsId,tradeBills.getUid());
|
|
|
BigDecimal amount;
|
|
|
try {
|
|
|
amount = new BigDecimal(req.getAmount()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
|
|
|
} catch (Exception e) {
|
|
|
throw new ServiceException(400, "manualDeal:金额不合法");
|
|
|
throw new ServiceException(400, "转账金额不合法");
|
|
|
}
|
|
|
if (amount.compareTo(new BigDecimal("0.1")) < 0) {
|
|
|
throw new ServiceException(400, "manualDeal:金额小于0.1");
|
|
|
throw new ServiceException(400, "转账金额小于0.1");
|
|
|
}
|
|
|
if (tradeBills.getAmount().compareTo(amount) != 0) {
|
|
|
throw new ServiceException(400, "manualDeal:金额有误");
|
|
|
throw new ServiceException(400, "转账金额有误");
|
|
|
}
|
|
|
|
|
|
int now = (int) (System.currentTimeMillis() / 1000);
|
|
|
// 预标记成功
|
|
|
TradeBills preSuccess = new TradeBills();
|
|
|
preSuccess.setId(tradeBills.getId());
|
|
|
preSuccess.setDealTime(now);
|
|
|
preSuccess.setDealStatus(1);
|
|
|
preSuccess.setDealUid(req.getOperateUid());
|
|
|
preSuccess.setDealUserName(req.getOperateUname());
|
|
|
|
|
|
tradeBills.setDealUid(req.getOperateUid());
|
|
|
tradeBills.setDealUserName(req.getOperateUname());
|
|
|
|
|
|
if (tradeBillsMapper.updateSelectiveByPrimaryKey(preSuccess) == 0) {
|
|
|
throw new ServiceException(400, "manualDeal:流水已经处理过id=" + tradeBills.getId());
|
|
|
TradeBills lockKey = new TradeBills();
|
|
|
lockKey.setId(tradeBills.getId());
|
|
|
lockKey.setDealTime((int) (System.currentTimeMillis() / 1000));
|
|
|
lockKey.setDealStatus(1);
|
|
|
lockKey.setDealUid(req.getOperateUid());
|
|
|
lockKey.setDealUserName(req.getOperateUname());
|
|
|
if (!tryLock(logTag, lockKey)) {
|
|
|
throw new ServiceException(400, "流水已经处理过id=" + tradeBills.getId());
|
|
|
}
|
|
|
|
|
|
boolean isMerchantExit = false;
|
|
|
// 是否为退出入驻订单
|
|
|
|
|
|
// 退货款或普通用户退保证金
|
|
|
if (isRefundGoodsMoneyTradeBills(tradeBills) || isRefundEarnestMoneyTradeBills(tradeBills)) {
|
|
|
refund(logTag, tradeBills, amount, lockKey);
|
|
|
}
|
|
|
// 转账
|
|
|
else {
|
|
|
transfer(logTag, tradeBills, amount, lockKey);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// '1:买家uid; 2:卖家uid','1:保证金;2:货款;3:补偿款', '1:用户收入; 2:用户支出'
|
|
|
private boolean isRefundGoodsMoneyTradeBills(TradeBills tradeBills) {
|
|
|
return tradeBills.getUserType() == 1
|
|
|
&& tradeBills.getTradeType() == 2
|
|
|
&& tradeBills.getIncomeOutcome() == 1;
|
|
|
}
|
|
|
|
|
|
// '1:买家uid; 2:卖家uid','1:保证金;2:货款;3:补偿款', '1:用户收入; 2:用户支出'
|
|
|
private boolean isRefundEarnestMoneyTradeBills(TradeBills tradeBills) {
|
|
|
long orderCode = tradeBills.getOrderCode();
|
|
|
return tradeBills.getUserType() == 2
|
|
|
&& tradeBills.getTradeType() == 1
|
|
|
&& tradeBills.getIncomeOutcome() == 1
|
|
|
&& !isMerchantExit(orderCode);
|
|
|
}
|
|
|
|
|
|
private boolean isMerchantExit(long orderCode) {
|
|
|
boolean isMerchantExit = false;
|
|
|
// 是否为退出入驻订单
|
|
|
CodeMeta codeMeta = orderCodeGenerator.expId(orderCode);
|
|
|
if(codeMeta.getType() == OrderCodeType.SELLER_RECHARGE_EARNEST_TYPE.getType()) {
|
|
|
EntrySellerRechargeOrder order = entrySellerRechargeOrderMapper.selectByOrderCode(orderCode);
|
...
|
...
|
@@ -1060,82 +1051,110 @@ public class PaymentServiceImpl implements IPaymentService { |
|
|
if (order.getStatus() == 0) {
|
|
|
isMerchantExit = true;
|
|
|
} else {
|
|
|
throw new ServiceException(400, "manualDeal:退款已成功,id=" + tradeBills.getId());
|
|
|
throw new ServiceException(400, "退款已成功");
|
|
|
}
|
|
|
} else {
|
|
|
throw new ServiceException(400, "manualDeal:商家退出入驻订单异常,id=" + tradeBills.getId());
|
|
|
throw new ServiceException(400, "商家退出入驻订单异常");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// '1:买家uid; 2:卖家uid','1:保证金;2:货款;3:补偿款', '1:用户收入; 2:用户支出'
|
|
|
return isMerchantExit;
|
|
|
}
|
|
|
|
|
|
private void refund(String logTag, TradeBills tradeBills, BigDecimal amount, TradeBills lockKey) {
|
|
|
long orderCode = tradeBills.getOrderCode();
|
|
|
PayRefundBo refundBo = null;
|
|
|
try {
|
|
|
if (/* 退货款 */((tradeBills.getUserType() == 1 && tradeBills.getTradeType() == 2 && tradeBills.getIncomeOutcome() == 1)
|
|
|
/* 退保证金(普通用户) */
|
|
|
|| (tradeBills.getUserType() == 2 && tradeBills.getTradeType() == 1 && tradeBills.getIncomeOutcome() == 1 && !isMerchantExit))) {
|
|
|
logger.warn("manualDeal人工退款 , tradeBills is {}", tradeBills);
|
|
|
refundBo = manualRefund(orderCode, amount);
|
|
|
if (refundBo.getRefundStatus() == RefundContant.PAYMENT_REFUND_RESULTCODE_SUCCESS) {
|
|
|
// 加新流水
|
|
|
tradeBills.setDealRelateId(tradeBills.getId());
|
|
|
tradeBills.setId(null);
|
|
|
tradeBills.setTradeStatus(100);
|
|
|
tradeBills.setCreateTime(now);
|
|
|
addTradeBills(tradeBills);
|
|
|
return;
|
|
|
} else {
|
|
|
throw new ServiceException(500, "退款失败:" + refundBo.getRefundMsg());
|
|
|
}
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("manualDealErr 退款失败 , tradeBillsId is {}, msg is {}", tradeBillsId, e.getMessage());
|
|
|
String alarmMsg = "订单号:" + orderCode + ",操作类型(退款),流水id=" + tradeBillsId + ",msg=" + e.getMessage();
|
|
|
if (refundBo != null) {
|
|
|
alarmMsg += ",DETAIL=" + JSON.toJSONString(refundBo);
|
|
|
}
|
|
|
logger.info("manualDealErr 退款失败 , alarmMsg is {}", alarmMsg);
|
|
|
alarm("人工处理退款失败", "ufo.order.manualDeal", alarmMsg );
|
|
|
preSuccess.setDealStatus(0);
|
|
|
tradeBillsMapper.updateToFailByPrimaryKey(preSuccess);
|
|
|
if (e instanceof ServiceException) {
|
|
|
throw new ServiceException(((ServiceException) e).getCode(), "退款失败id=" + tradeBillsId + "," + e.getMessage());
|
|
|
} else {
|
|
|
throw new ServiceException(500, "退款失败id=" + tradeBillsId);
|
|
|
}
|
|
|
}
|
|
|
try {
|
|
|
|
|
|
logger.warn("{}, refund money is {}", logTag, tradeBills);
|
|
|
refundBo = manualRefund(orderCode, amount);
|
|
|
if (refundBo.getRefundStatus() == RefundContant.PAYMENT_REFUND_RESULTCODE_SUCCESS) {
|
|
|
// 加新流水
|
|
|
addSuccessTradeBills(tradeBills);
|
|
|
} else {
|
|
|
throw new ServiceException(500, "退款失败:" + refundBo.getRefundMsg());
|
|
|
}
|
|
|
return;
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("{}, refund fail.", logTag, e);
|
|
|
String alarmMsg = "订单号:" + orderCode + ",操作类型(退款),流水id=" + tradeBills.getId() + ",msg=" + e.getMessage();
|
|
|
if (refundBo != null) {
|
|
|
alarmMsg += ",DETAIL=" + JSON.toJSONString(refundBo);
|
|
|
}
|
|
|
alarm("人工处理退款失败", "ufo.order.manualDeal", alarmMsg);
|
|
|
releaseLock(logTag, lockKey);
|
|
|
if (e instanceof ServiceException) {
|
|
|
throw e;
|
|
|
} else {
|
|
|
throw new ServiceException(500, "退款失败[" + tradeBills.getId() + "]");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void transfer(String logTag, TradeBills tradeBills, BigDecimal amount, TradeBills lockKey) {
|
|
|
long orderCode = tradeBills.getOrderCode();
|
|
|
try {
|
|
|
AuthorizeResultRespVO account = getAlipayAccount(tradeBills.getUid());
|
|
|
if (account == null ||
|
|
|
(StringUtils.isBlank(account.getAlipayAccount()) && StringUtils.isBlank(account.getAlipayId()))) {
|
|
|
logger.warn("{}, can not find a alipay account", logTag);
|
|
|
throw new ServiceException(400, "uid[" + tradeBills.getUid() + "]没有获取到有效的支付宝账号");
|
|
|
}
|
|
|
OrdersPayTransfer transfer = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode);
|
|
|
ServiceExceptions.throwServiceExceptionIf(() -> Objects.isNull(transfer),
|
|
|
400, "转账记录不存在[" + tradeBillsId + "]");
|
|
|
ServiceExceptions.throwServiceExceptionIf(() -> transfer.getStatus() == 1,
|
|
|
throwServiceExceptionIf(() -> Objects.isNull(transfer),
|
|
|
400, "转账记录不存在[" + tradeBills.getId() + "]");
|
|
|
throwServiceExceptionIf(() -> transfer.getStatus() == 1,
|
|
|
400, "转账记录已成功转账,请不要重复操作。");
|
|
|
Integer interfaceType = transfer.getInterfaceType();
|
|
|
logger.info("{}, transfer channel router {}", logTag, interfaceType);
|
|
|
if (OrdersPayTransfer.INTERFACE_TYPE_TRANSFER_WHEN_EXCEED_MILLION.equals(interfaceType)) {
|
|
|
transferWithAlipayExceedMillionTransfer(tradeBills, orderCode, logTag, account, amount, transfer);
|
|
|
} else {
|
|
|
transferWithAlipayTransfer(logTag, tradeBills, orderCode, account, amount, now, transfer);
|
|
|
transferWithAlipayTransfer(logTag, tradeBills, orderCode, account, amount, transfer);
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("{}, transfer fail", logTag, e);
|
|
|
alarm("人工处理转账失败",
|
|
|
"ufo.order.manualDeal",
|
|
|
"订单号:" + orderCode + ",操作类型(转账),流水id=" + tradeBillsId + ",msg=" + e.getMessage());
|
|
|
logger.info("{}, rollback lock", logTag);
|
|
|
preSuccess.setDealStatus(0);
|
|
|
tradeBillsMapper.updateToFailByPrimaryKey(preSuccess);
|
|
|
logger.info("{}, rollback lock success", logTag);
|
|
|
"订单号:" + orderCode + ",操作类型(转账),流水id=" + tradeBills.getId() + ",msg=" + e.getMessage());
|
|
|
|
|
|
releaseLock(logTag, lockKey);
|
|
|
|
|
|
if (e instanceof ServiceException) {
|
|
|
throw e;
|
|
|
} else {
|
|
|
ServiceExceptions.throwServiceException(500, "转账失败id=" + tradeBillsId);
|
|
|
ServiceExceptions.throwServiceException(500, "转账失败[" + tradeBills.getId() + "]");
|
|
|
}
|
|
|
} finally {
|
|
|
logger.info("{}, complete", logTag);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private boolean tryLock(String logTag, TradeBills key) {
|
|
|
logger.info("{}, try lock", logTag);
|
|
|
int row = tradeBillsMapper.updateSelectiveByPrimaryKey(key);
|
|
|
if (row == 0) {
|
|
|
logger.info("{}, i not got the lock", logTag);
|
|
|
return false;
|
|
|
} else {
|
|
|
logger.info("{}, i got the lock", logTag);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void releaseLock(String logTag, TradeBills key) {
|
|
|
logger.info("{}, release lock", logTag);
|
|
|
key.setDealStatus(0);
|
|
|
tradeBillsMapper.updateToFailByPrimaryKey(key);
|
|
|
logger.info("{}, release lock success", logTag);
|
|
|
}
|
|
|
|
|
|
private void addSuccessTradeBills(TradeBills tradeBills) {
|
|
|
tradeBills.setDealRelateId(tradeBills.getId());
|
|
|
tradeBills.setId(null);
|
|
|
tradeBills.setTradeStatus(100);
|
|
|
tradeBills.setCreateTime(DateUtil.getCurrentTimeSecond());
|
|
|
addTradeBills(tradeBills);
|
|
|
}
|
|
|
|
|
|
private void transferWithAlipayTransfer(String logTag, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, BigDecimal amount, int now, OrdersPayTransfer transfer) {
|
|
|
private void transferWithAlipayTransfer(String logTag, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, BigDecimal amount, OrdersPayTransfer transfer) {
|
|
|
TransferResult transferResult = alipayService.newAlipayTransfer()
|
|
|
.transferOrderCode(Long.toString(orderCode))
|
|
|
.alipayUid(account.getAlipayId())
|
...
|
...
|
@@ -1145,17 +1164,13 @@ public class PaymentServiceImpl implements IPaymentService { |
|
|
if (transferResult.getCode() == 200) {
|
|
|
logger.info("{}, transfer success and out trade no is {}", logTag, orderCode);
|
|
|
// 加新流水
|
|
|
tradeBills.setDealRelateId(tradeBills.getId());
|
|
|
tradeBills.setId(null);
|
|
|
tradeBills.setTradeStatus(100);
|
|
|
tradeBills.setCreateTime(now);
|
|
|
addTradeBills(tradeBills);
|
|
|
addSuccessTradeBills(tradeBills);
|
|
|
// ?
|
|
|
OrdersPayTransfer transferSuccess = new OrdersPayTransfer();
|
|
|
transferSuccess.setId(transfer.getId());
|
|
|
transferSuccess.setAlipayTradeId(transferResult.getTradeNo());
|
|
|
transferSuccess.setStatus(1);
|
|
|
transferSuccess.setUpdateTime(now);
|
|
|
transferSuccess.setUpdateTime(DateUtil.getCurrentTimeSecond());
|
|
|
ordersPayTransferMapper.updateByPrimaryKeySelective(transferSuccess);
|
|
|
}else {
|
|
|
logger.warn("{}, transfer fail {}", logTag,transferResult);
|
...
|
...
|
|