update 修改结算订单逻辑

This commit is contained in:
2023-08-25 17:21:39 +08:00
parent 033ddb40e7
commit 8cf8d39a9e
4 changed files with 133 additions and 66 deletions

View File

@@ -51,11 +51,15 @@ public class CacheConstants {
public static final String PILE_PROGRAM_VERSION = "pile_program_version_"; public static final String PILE_PROGRAM_VERSION = "pile_program_version_";
// 查询订单回调 // 查询订单微信支付回调
public static final String QUERY_ORDER_WECHAT_CALLBACK = "query_order_wechat_callback:"; public static final String QUERY_ORDER_WECHAT_CALLBACK = "query_order_wechat_callback:";
// 查询订单汇付支付回调
public static final String QUERY_ORDER_ADAPAY_CALLBACK = "query_order_adapay_callback:"; public static final String QUERY_ORDER_ADAPAY_CALLBACK = "query_order_adapay_callback:";
// 通过paymentId 查询汇付支付回调
public static final String QUERY_ADAPAY_CALLBACK_RECORD_BY_PAYMENT_ID = "query_adapay_callback_record_by_payment_id:";
// 汇付支付参数 // 汇付支付参数
public static final String ADAPAY_ORDER_PARAM = "adapay_order_param:"; public static final String ADAPAY_ORDER_PARAM = "adapay_order_param:";

View File

@@ -27,6 +27,7 @@ public class AdapayCallbackRecordServiceImpl implements AdapayCallbackRecordServ
/** /**
* 根据订单号查询支付回调信息 * 根据订单号查询支付回调信息
*
* @param orderCode * @param orderCode
* @return * @return
*/ */
@@ -55,6 +56,23 @@ public class AdapayCallbackRecordServiceImpl implements AdapayCallbackRecordServ
@Override @Override
public AdapayCallbackRecord selectByPaymentId(String paymentId) { public AdapayCallbackRecord selectByPaymentId(String paymentId) {
return adapayCallbackRecordMapper.selectByPaymentId(paymentId); if (StringUtils.isBlank(paymentId)) {
return null;
}
// 加缓存缓存一周 由于回调结果不会变动,所以不用写清缓存的逻辑了
String redisKey = CacheConstants.QUERY_ADAPAY_CALLBACK_RECORD_BY_PAYMENT_ID + paymentId;
AdapayCallbackRecord record = redisCache.getCacheObject(redisKey);
if (record != null) {
return record;
}
try {
record = adapayCallbackRecordMapper.selectByPaymentId(paymentId);
if (record != null) {
redisCache.setCacheObject(redisKey, record, CacheConstants.cache_expire_time_1d);
}
} catch (Exception e) {
log.error("查询汇付支付回调记录失败", e);
}
return record;
} }
} }

View File

@@ -686,17 +686,62 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
@Override @Override
public void settleOrder(TransactionRecordsData data, OrderBasicInfo orderBasicInfo) { public void settleOrder(TransactionRecordsData data, OrderBasicInfo orderBasicInfo) {
logger.info("结算订单start data:{}, orderBasicInfo:{}", data.toString(), orderBasicInfo.toString()); logger.info("结算订单start data:{}, orderBasicInfo:{}", data.toString(), orderBasicInfo.toString());
String orderCode = orderBasicInfo.getOrderCode();
String memberId = orderBasicInfo.getMemberId();
// 判断订单状态 // 判断订单状态
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) { if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
logger.info("结算订单:{}, 是订单完成状态", orderCode); logger.info("结算订单:{}, 是订单完成状态", orderBasicInfo.getOrderCode());
return; return;
} }
// 消费金额就是订单总金额 // 获取更新数据后的orderBasicInfo对象
BigDecimal orderAmount = new BigDecimal(data.getConsumptionAmount()); returnUpdateOrderBasicInfo(orderBasicInfo, data);
// 获取更新数据后的orderDetail对象/更新订单详情 查询订单详情 修改订单数据
OrderDetail orderDetail = returnUpdateOrderDetail(orderBasicInfo, data);
// 更新数据库
OrderTransactionDTO dto = new OrderTransactionDTO();
dto.setOrderBasicInfo(orderBasicInfo);
dto.setOrderDetail(orderDetail);
transactionService.doUpdateOrder(dto);
// 需要退款的情况
BigDecimal residue = orderBasicInfo.getRefundAmount();
if (residue.compareTo(BigDecimal.ZERO) > 0) {
// 执行退款逻辑
try {
refundOrder(orderBasicInfo, residue);
} catch (Exception e) {
logger.error("订单退款逻辑异常orderCode:{}", orderBasicInfo.getOrderCode(), e);
}
}
// 将卡/vin状态解锁
if (!StringUtils.equals("0000000000000000", data.getLogicCard())) {
cardStatusUnlocked(orderBasicInfo.getLogicCard());
}
// 如果是vin启动将启动锁定状态改为正常
if (StringUtils.equals(data.getTransactionIdentifier(), "05")) {
vinStatusUnlocked(data.getVinCode());
}
// 发送停止充电订阅消息
sendMsg(orderBasicInfo);
// 从redis中取出实时记录保存到表中
realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode());
// TODO 如果该站点的停车场优惠券信息配置不为空,则需绑定一张优惠券
logger.info("结算订单end:{} OrderTransactionDTO:{}", orderBasicInfo.getOrderCode(), JSONObject.toJSONString(dto));
}
/**
* 返回更新后的OrderBasicInfo对象
* 专用方法,其他地方如果要用请仔细检查
*/
private void returnUpdateOrderBasicInfo(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
// 订单编号
String orderCode = orderBasicInfo.getOrderCode();
// 消费金额就是订单总金额/交易记录传过来的消费金额
BigDecimal orderAmount = new BigDecimal(data.getConsumptionAmount());
// 付款金额 - 实际消费金额,如果有剩余,需要走退款操作 当使用余额支付时payAmount = principalPay + giftPay // 付款金额 - 实际消费金额,如果有剩余,需要走退款操作 当使用余额支付时payAmount = principalPay + giftPay
BigDecimal payAmount = orderBasicInfo.getPayAmount(); BigDecimal payAmount = orderBasicInfo.getPayAmount();
@@ -705,7 +750,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
logger.info("结算订单:【{}】充电桩传来的消费金额:【{}】大于付款金额:【{}】, 消费金额设置为付款金额相等数据", orderCode, orderAmount, payAmount); logger.info("结算订单:【{}】充电桩传来的消费金额:【{}】大于付款金额:【{}】, 消费金额设置为付款金额相等数据", orderCode, orderAmount, payAmount);
orderAmount = payAmount; orderAmount = payAmount;
} }
orderBasicInfo.setOrderAmount(orderAmount); // 订单总金额 orderBasicInfo.setOrderAmount(orderAmount); // 订单总金额
// 虚拟金额 指订单消费中不参与结算的部分 // 虚拟金额 指订单消费中不参与结算的部分
@@ -717,14 +761,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// 剩余需要退回的金额 residue // 剩余需要退回的金额 residue
BigDecimal residue = payAmount.subtract(orderAmount); BigDecimal residue = payAmount.subtract(orderAmount);
if (residue.compareTo(BigDecimal.ZERO) > 0) {
// 执行退款逻辑
try {
refundOrder(orderBasicInfo, residue);
} catch (Exception e) {
logger.error("订单退款逻辑异常orderCode:{}", orderCode, e);
}
}
// 把交易记录中的用电量,金额等信息 更新到orderBasicInfo和orderDetail // 把交易记录中的用电量,金额等信息 更新到orderBasicInfo和orderDetail
orderBasicInfo.setVirtualAmount(virtualAmount); // 虚拟金额 orderBasicInfo.setVirtualAmount(virtualAmount); // 虚拟金额
@@ -733,7 +769,16 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
orderBasicInfo.setReason(data.getStopReasonMsg()); // 充电停止原因 orderBasicInfo.setReason(data.getStopReasonMsg()); // 充电停止原因
orderBasicInfo.setSettlementTime(DateUtils.getNowDate()); // 结算时间 orderBasicInfo.setSettlementTime(DateUtils.getNowDate()); // 结算时间
orderBasicInfo.setRefundAmount(residue); // 结算退款金额 orderBasicInfo.setRefundAmount(residue); // 结算退款金额
}
/**
* 获取更新数据后的orderDetail对象
* 专用方法,其他地方如果要用请仔细检查
* @return 查询并更新过数据的orderDetail
*/
private OrderDetail returnUpdateOrderDetail(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
String orderCode = orderBasicInfo.getOrderCode();
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
// 更新订单详情 查询订单详情 修改订单数据 // 更新订单详情 查询订单详情 修改订单数据
OrderDetail orderDetail = getOrderDetailByOrderCode(orderCode); OrderDetail orderDetail = getOrderDetailByOrderCode(orderCode);
try { try {
@@ -811,30 +856,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
} catch (Exception e) { } catch (Exception e) {
logger.error("设置订单详情参数发生异常", e); logger.error("设置订单详情参数发生异常", e);
} }
return orderDetail;
OrderTransactionDTO dto = new OrderTransactionDTO();
dto.setOrderBasicInfo(orderBasicInfo);
dto.setOrderDetail(orderDetail);
transactionService.doUpdateOrder(dto);
logger.info("结算订单end:{} OrderTransactionDTO:{}", orderCode, JSONObject.toJSONString(dto));
// 将卡/vin状态解锁
if (!StringUtils.equals("0000000000000000", data.getLogicCard())) {
cardStatusUnlocked(orderBasicInfo.getLogicCard());
}
// 如果是vin启动将启动锁定状态改为正常
if (StringUtils.equals(data.getTransactionIdentifier(), "05")) {
vinStatusUnlocked(data.getVinCode());
}
// 发送停止充电订阅消息
sendMsg(orderBasicInfo);
// 从redis中取出实时记录保存到表中
realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderCode);
// TODO 如果该站点的停车场优惠券信息配置不为空,则需绑定一张优惠券
} }
/** /**
@@ -944,9 +966,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
this.weChatRefund(applyRefundDTO); this.weChatRefund(applyRefundDTO);
} else if (StringUtils.equals(transactionRecord.getPaymentInstitutions(), PaymentInstitutionsEnum.ADAPAY.getValue())) { } else if (StringUtils.equals(transactionRecord.getPaymentInstitutions(), PaymentInstitutionsEnum.ADAPAY.getValue())) {
// 汇付退款需要一级运营商的小程序appId, 否则会退款失败 // 汇付退款需要一级运营商的小程序appId, 否则会退款失败
PileMerchantInfo pileMerchantInfo = pileMerchantInfoService.selectPileMerchantInfoById(orderBasicInfo.getMerchantId()); String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderBasicInfo.getMerchantId());
if (pileMerchantInfo != null) { if (StringUtils.isNotBlank(wechatAppId)) {
applyRefundDTO.setWechatAppId(pileMerchantInfo.getAppId()); applyRefundDTO.setWechatAppId(wechatAppId);
} }
this.refundOrderWithAdapay(applyRefundDTO); this.refundOrderWithAdapay(applyRefundDTO);
} }
@@ -1174,7 +1196,10 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
for (BalanceDeductionAmountVO vo : list) { for (BalanceDeductionAmountVO vo : list) {
String paymentId = vo.getPaymentId(); String paymentId = vo.getPaymentId();
BigDecimal deductionAmount = vo.getDeductionAmount(); BigDecimal deductionAmount = vo.getDeductionAmount();
// 调汇付的分账接口 确认交易 String delayMode = vo.getDelayMode();
if (StringUtils.equals(delayMode, Constants.ADAPAY_PAY_MODE_DELAY)) {
// 延时分账使用确认交易API
PaymentConfirmResponse paymentConfirmResponse = adapayService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, deductionAmount, orderCode, wechatAppId); PaymentConfirmResponse paymentConfirmResponse = adapayService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, deductionAmount, orderCode, wechatAppId);
if (paymentConfirmResponse != null && paymentConfirmResponse.isNotFailed()) { if (paymentConfirmResponse != null && paymentConfirmResponse.isNotFailed()) {
confirmAmt = confirmAmt.add(new BigDecimal(paymentConfirmResponse.getConfirmed_amt())); confirmAmt = confirmAmt.add(new BigDecimal(paymentConfirmResponse.getConfirmed_amt()));
@@ -1190,6 +1215,10 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt())); record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt()));
memberAdapayRecordService.updateByPrimaryKeySelective(record); memberAdapayRecordService.updateByPrimaryKeySelective(record);
} }
} else {
// 实时分账
logger.info("实时分账");
}
} }
// 分账接口返回的信息 // 分账接口返回的信息
@@ -1219,7 +1248,13 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
BigDecimal balanceAmt = memberAdapayRecord.getBalanceAmt(); BigDecimal balanceAmt = memberAdapayRecord.getBalanceAmt();
// 该笔支付扣除金额 // 该笔支付扣除金额
BigDecimal deductionAmount; BigDecimal deductionAmount;
// 获取延时分账模式 延时分账的使用撤销方法退款,实时分账的使用退款方法
AdapayCallbackRecord callbackRecord = adapayCallbackRecordService.selectByPaymentId(memberAdapayRecord.getPaymentId());
String payMode = null;
if (callbackRecord != null) {
JSONObject expendJsonObject = JSON.parseObject(callbackRecord.getExpend());
payMode = expendJsonObject.getString("payMode");
}
// 消费金额 - 剩余金额 // 消费金额 - 剩余金额
tempAmount = tempAmount.subtract(balanceAmt); tempAmount = tempAmount.subtract(balanceAmt);
if (tempAmount.compareTo(BigDecimal.ZERO) >= 0) { if (tempAmount.compareTo(BigDecimal.ZERO) >= 0) {
@@ -1229,6 +1264,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
.memberId(memberId) .memberId(memberId)
.paymentId(memberAdapayRecord.getPaymentId()) .paymentId(memberAdapayRecord.getPaymentId())
.deductionAmount(deductionAmount) .deductionAmount(deductionAmount)
.delayMode(payMode)
.build(); .build();
resultList.add(build); resultList.add(build);
} else { } else {
@@ -1238,6 +1274,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
.memberId(memberId) .memberId(memberId)
.paymentId(memberAdapayRecord.getPaymentId()) .paymentId(memberAdapayRecord.getPaymentId())
.deductionAmount(deductionAmount) .deductionAmount(deductionAmount)
.delayMode(payMode)
.build(); .build();
resultList.add(build); resultList.add(build);
break; break;
@@ -2321,7 +2358,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
/** /**
* 汇付支付-订单退款处理逻辑 * 汇付支付-订单退款处理逻辑
* * 汇付支付订单退款
* @param dto * @param dto
*/ */
@Override @Override
@@ -2343,7 +2380,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR);
} }
// 拿orderCode查询延时分账模式 延时分账的使用撤销方法退款,实时分账的使用退款方法 // 获取延时分账模式 延时分账的使用撤销方法退款,实时分账的使用退款方法
String expend = callbackRecord.getExpend(); String expend = callbackRecord.getExpend();
JSONObject expendJsonObject = JSON.parseObject(expend); JSONObject expendJsonObject = JSON.parseObject(expend);
String payMode = expendJsonObject.getString("payMode"); String payMode = expendJsonObject.getString("payMode");
@@ -2417,8 +2454,13 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
// } // }
} }
/**
* 汇付支付余额退款
* @param dto
*/
@Override @Override
public void refundBalanceWithAdapay(ApplyRefundDTO dto){ public void refundBalanceWithAdapay(ApplyRefundDTO dto){
// 做个拦截,如果前一笔退款没有完成,就抛异常
String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + dto.getMemberId(); String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + dto.getMemberId();
PaymentReverseResponse redisResult = redisCache.getCacheObject(redisKey); PaymentReverseResponse redisResult = redisCache.getCacheObject(redisKey);
if (Objects.nonNull(redisResult)) { if (Objects.nonNull(redisResult)) {
@@ -2438,9 +2480,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_MEMBER_BALANCE_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_REFUND_MEMBER_BALANCE_ERROR);
} }
// 模拟放缓存
// redisCache.setCacheObject(redisKey, new PaymentReverseResponse(), CacheConstants.cache_expire_time_30m);
// 查询用户充值余额订单 过滤掉已经退款的充值订单 // 查询用户充值余额订单 过滤掉已经退款的充值订单
List<BalanceDeductionAmountVO> list = calculateTheBalanceDeductionAmount(dto.getMemberId(), refundAmount); List<BalanceDeductionAmountVO> list = calculateTheBalanceDeductionAmount(dto.getMemberId(), refundAmount);
for (BalanceDeductionAmountVO vo : list) { for (BalanceDeductionAmountVO vo : list) {

View File

@@ -24,4 +24,10 @@ public class BalanceDeductionAmountVO {
* 扣除金额 * 扣除金额
*/ */
private BigDecimal deductionAmount; private BigDecimal deductionAmount;
/**
* 该笔支付单的分账方式
* delay表示延时分账其他情况表示实时分账
*/
private String delayMode;
} }