非延时分账商户 逻辑

This commit is contained in:
2023-08-30 10:18:09 +08:00
parent 1f80d4e479
commit 7b468d11fe

View File

@@ -1,12 +1,308 @@
package com.jsowell.pile.service.orderlogic;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.jsowell.adapay.vo.OrderSettleResult;
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
import com.jsowell.common.enums.AcquirerEnum;
import com.jsowell.common.enums.MemberWalletEnum;
import com.jsowell.common.enums.ykc.*;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.*;
import com.jsowell.pile.dto.PayOrderDTO;
import com.jsowell.pile.dto.PayOrderSuccessCallbackDTO;
import com.jsowell.pile.transaction.dto.OrderTransactionDTO;
import com.jsowell.pile.vo.uniapp.MemberVO;
import com.jsowell.pile.vo.web.BalanceDeductionAmountVO;
import com.jsowell.pile.vo.web.UpdateMemberBalanceDTO;
import com.jsowell.wxpay.dto.WechatSendMsgDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 没有设置延时分账的运营商订单逻辑
*/
@Service
public class NotDelayMerchantOrderLogic {
public class NotDelayMerchantOrderLogic extends AbstractOrderLogic{
/**
* 余额支付订单
*
* @param dto
*/
@Override
public void balancePayOrder(PayOrderDTO dto) {
String orderCode = dto.getOrderCode(); // 订单编号
BigDecimal chargeAmount = dto.getPayAmount(); // 支付金额
// 查询该会员的余额
MemberVO memberVO = memberBasicInfoService.queryMemberInfoByMemberId(dto.getMemberId());
BigDecimal totalAccountAmount = memberVO.getPrincipalBalance();
if (totalAccountAmount.compareTo(chargeAmount) < 0) {
// 总余额小于充电金额
throw new BusinessException(ReturnCodeEnum.CODE_BALANCE_IS_INSUFFICIENT);
}
BigDecimal principalPay = chargeAmount;
// 更新会员钱包
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
.memberId(dto.getMemberId())
.type(MemberWalletEnum.TYPE_OUT.getValue())
.subType(MemberWalletEnum.SUBTYPE_PAYMENT_FOR_ORDER.getValue())
.updatePrincipalBalance(principalPay) // 使用本金支付的金额
.relatedOrderCode(orderCode)
.build();
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
// 查询余额充值有剩余的记录
List<BalanceDeductionAmountVO> list = calculateTheBalanceDeductionAmount(dto.getMemberId(), chargeAmount);
// 记录支订单付流水
List<OrderPayRecord> payRecordList = Lists.newArrayList();
for (BalanceDeductionAmountVO balanceDeductionAmountVO : list) {
String paymentId = balanceDeductionAmountVO.getPaymentId();
BigDecimal deductionAmount = balanceDeductionAmountVO.getDeductionAmount();
JSONObject json = new JSONObject();
json.put("paymentId", paymentId);
json.put("amount", deductionAmount);
// 记录流水
payRecordList.add(OrderPayRecord.builder()
.orderCode(orderCode)
.payMode(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())
.payAmount(deductionAmount)
.acquirer(AcquirerEnum.LOCAL.getValue())
.deductionRecord(json.toJSONString())
.createBy(dto.getMemberId())
.build());
}
// 订单支付流水入库
if (CollectionUtils.isNotEmpty(payRecordList)) {
orderPayRecordService.batchInsert(payRecordList);
for (OrderPayRecord record : payRecordList) {
String deductionRecord = record.getDeductionRecord();
JSONObject jsonObject = JSON.parseObject(deductionRecord);
String paymentId = jsonObject.getString("paymentId");
BigDecimal amount = jsonObject.getBigDecimal("amount");
// 余额支付 临时冻结金额
memberAdapayRecordService.updateFreezeAmount(paymentId, amount);
}
}
// 余额支付可以直接调支付回调方法
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(chargeAmount)
.payMode(dto.getPayMode())
.startMode(dto.getStartMode())
.acquirer(AcquirerEnum.LOCAL.getValue())
.build();
payOrderSuccessCallback(callbackDTO);
// 余额支付订单 记录会员交易流水
MemberTransactionRecord record = MemberTransactionRecord.builder()
.orderCode(orderCode)
.scenarioType(ScenarioEnum.ORDER.getValue())
.memberId(memberVO.getMemberId())
.actionType(ActionTypeEnum.FORWARD.getValue())
.payMode(PayModeEnum.PAYMENT_OF_BALANCE.getValue())
.paymentInstitutions(PaymentInstitutionsEnum.LOCAL_ACCOUNTS.getValue())
.amount(dto.getPayAmount()) // 单位元
.build();
memberTransactionRecordService.insertSelective(record);
}
/**
* 在线支付订单
*
* @param dto
*/
@Override
public Map<String, Object> onlinePaymentOrder(PayOrderDTO dto) {
// 2023-07-11 全部改为汇付支付
dto.setGoodsTitle("充电费用");
dto.setGoodsDesc("充电桩预付款金额");
Map<String, Object> weixinMap = adapayService.createPayment(dto);
return weixinMap;
}
/**
* 白名单支付订单
*
* @param dto
*/
@Override
public void whitelistPaymentOrder(PayOrderDTO dto) {
String orderCode = dto.getOrderCode();
BigDecimal payAmount = dto.getPayAmount();
String payMode = dto.getPayMode();
// 白名单直接算支付成功
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(payAmount)
.payMode(payMode)
.startMode(dto.getStartMode())
.acquirer(AcquirerEnum.LOCAL.getValue())
.build();
payOrderSuccessCallback(callbackDTO);
}
/**
* 订单结算
*
* @param data
* @param orderBasicInfo
*/
@Override
public void orderSettle(TransactionRecordsData data, OrderBasicInfo orderBasicInfo) {
logger.info("结算订单start data:{}, orderBasicInfo:{}", data.toString(), orderBasicInfo.toString());
// 判断订单状态
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
logger.info("结算订单:{}, 是订单完成状态", orderBasicInfo.getOrderCode());
return;
}
// 获取更新数据后的orderBasicInfo对象
returnUpdateOrderBasicInfo(orderBasicInfo, data);
// 获取更新数据后的orderDetail对象/更新订单详情 查询订单详情 修改订单数据
OrderDetail orderDetail = returnUpdateOrderDetail(orderBasicInfo, data);
// 更新数据库
OrderTransactionDTO dto = new OrderTransactionDTO();
dto.setOrderBasicInfo(orderBasicInfo);
dto.setOrderDetail(orderDetail);
transactionService.doUpdateOrder(dto);
// 订单支付结算and退款, delay商户部分解冻并退款, 非delay商户全部解冻并退款
orderPaymentSettlementAndRefund(orderBasicInfo);
// 将卡/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));
}
/**
* 卡状态解锁
*/
private void cardStatusUnlocked(String logicCard) {
try {
// 根据物理卡号查出当前为锁定状态的卡
PileAuthCard cardInfo = pileAuthCardService.selectSomeStatusCardInfo(CardStatusEnum.START_LOCK.getCode(), logicCard);
if (cardInfo != null) {
// 将此卡状态改为正常
cardInfo.setStatus(CardStatusEnum.NORMAL.getCode());
pileAuthCardService.updatePileAuthCard(cardInfo);
}
} catch (Exception e) {
logger.error("解锁卡状态 error,", e);
}
}
// uniApp 发送停止充电订阅消息
private void sendMsg(OrderBasicInfo orderBasicInfo) {
try {
WechatSendMsgDTO wechatSendMsgDTO = new WechatSendMsgDTO();
wechatSendMsgDTO.setOrderCode(orderBasicInfo.getOrderCode());
Map<String, String> resultMap = wxAppletRemoteService.stopChargingSendMsg(wechatSendMsgDTO);
logger.info("小程序发送充电停止推送消息 result:{}", JSON.toJSONString(resultMap));
} catch (Exception e) {
logger.error("小程序发送充电停止推送消息 error", e);
}
}
/**
* 解锁vin状态
*
* @param vinCode
*/
private void vinStatusUnlocked(String vinCode) {
try {
MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode);
if (plateInfo != null && (StringUtils.equals(plateInfo.getVinStatus(), "2"))) {
plateInfo.setVinStatus("1");
memberPlateNumberRelationService.updateMemberPlateNumberRelation(plateInfo);
}
} catch (Exception e) {
logger.error("解锁vin状态 error,", e);
}
}
/**
* 订单分账逻辑
* 订单结算完成就执行清分and退款
*/
private OrderSettleResult orderPaymentSettlementAndRefund(OrderBasicInfo orderBasicInfo) {
String merchantId = orderBasicInfo.getMerchantId();
String orderCode = orderBasicInfo.getOrderCode();
// 获取一级运营商信息
PileMerchantInfo merchantInfo = pileMerchantInfoService.getFirstLevelMerchantByMerchantId(merchantId);
if (merchantInfo == null) {
logger.info("订单分账逻辑-订单:{}, 查不到一级运营商信息", orderCode);
return null;
}
// 获取结算账户信息
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
logger.info("订单分账逻辑-订单:{}, 运营商id:{}, 没有配置结算账户信息", orderCode, merchantId);
return null;
}
try {
String payMode = orderBasicInfo.getPayMode();
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue())) {
// 余额支付
balancePaymentOrderRefund(orderBasicInfo);
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
// 微信支付
onlinePaymentOrderRefund(orderBasicInfo);
} else {
// 白名单支付
logger.info("订单:{}使用白名单支付,不进行退款处理", orderBasicInfo.getOrderCode());
}
} catch (Exception e) {
logger.error("订单退款逻辑异常orderCode:{}", orderBasicInfo.getOrderCode(), e);
}
return null;
}
/**
* 余额支付订单退款
*
* @param orderBasicInfo
*/
@Override
public void balancePaymentOrderRefund(OrderBasicInfo orderBasicInfo) {
}
/**
* 在线支付订单退款
*
* @param orderBasicInfo
*/
@Override
public void onlinePaymentOrderRefund(OrderBasicInfo orderBasicInfo) {
}
}