wujiefeng 1 год назад
Родитель
Сommit
7120093caa

+ 17 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/type/SettleStatus.java

@@ -0,0 +1,17 @@
+package com.zhongshu.card.client.type;
+
+import lombok.Getter;
+
+public enum SettleStatus {
+
+    Settle("已结算"),
+    WaitSettle("待结算")
+    ;
+
+    @Getter
+    private String remark;
+
+    SettleStatus(String remark) {
+        this.remark = remark;
+    }
+}

+ 134 - 2
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/pay/ChinaumsSenselessPayService.java

@@ -1,31 +1,39 @@
 package com.zhongshu.card.server.core.service.pay;
 
+import com.github.microservice.core.util.JsonUtil;
 import com.github.microservice.core.util.bean.BeanUtil;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.pay.client.model.AccountModel;
 import com.github.microservice.pay.client.model.PayProductParameter;
+import com.github.microservice.pay.client.model.chinaSenseless.ChinaSenselessPayRequest;
+import com.github.microservice.pay.client.model.chinaSenseless.ChinaSenselessRefundRequest;
 import com.github.microservice.pay.client.model.chinaSenseless.ChinaSenselessSignRet;
+import com.github.microservice.pay.client.model.ledger.TransferTransactionsModel;
 import com.github.microservice.pay.client.product.senseless.chinaumsSenseless.conf.ChinaumsSenselessConf;
 import com.github.microservice.pay.client.ret.ResultState;
 import com.github.microservice.pay.client.service.PayProductAccountService;
+import com.github.microservice.pay.client.service.ledger.TransactionLogService;
 import com.github.microservice.pay.client.service.product.SenselessPayService;
+import com.github.microservice.pay.client.type.ledger.TransactionStatus;
+import com.github.microservice.pay.client.type.ledger.TransactionType;
+import com.github.microservice.types.payment.PaymentChannelType;
 import com.github.microservice.types.payment.PaymentType;
 import com.zhongshu.card.client.model.pay.ChinaumsSenselessUserSignInfoModel;
 import com.zhongshu.card.client.model.pay.UnionApplySignParam;
 import com.zhongshu.card.client.type.ContractState;
 import com.zhongshu.card.server.core.dao.pay.ChinaumsSenselessUserSignInfoDao;
 import com.zhongshu.card.server.core.domain.pay.ChinaumsSenselessUserSignInfo;
+import com.zhongshu.card.server.core.domain.pay.PayAccount;
 import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.paySetting.OrgPayAccountService;
 import com.zhongshu.card.server.core.util.BeanUtils;
 import com.zhongshu.card.server.core.util.CommonUtil;
 import io.micrometer.common.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.poi.util.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import picocli.CommandLine;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 @Slf4j
@@ -44,6 +52,12 @@ public class ChinaumsSenselessPayService extends SuperService {
     @Autowired
     PayProductAccountService payProductAccountService;
 
+    @Autowired
+    PayAccountService payAccountService;
+
+    @Autowired
+    TransactionLogService transactionLogService;
+
 
     /**
      * 银联申请签约
@@ -201,6 +215,124 @@ public class ChinaumsSenselessPayService extends SuperService {
         return ResultContent.buildContent(toUserSignModel(userSignInfo));
     }
 
+    /**
+     * 支付
+     */
+    public Object senselessPay(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String remark) {
+
+        //获取银联支付产品账户及需要签约的商户号
+        String accountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
+        com.github.microservice.pay.client.ret.ResultContent<AccountModel> accountModelResultContent = payProductAccountService.get(accountName);
+        if (!accountModelResultContent.getState().equals(ResultState.Success)){
+            return accountModelResultContent;
+        }
+        ChinaumsSenselessConf conf = (ChinaumsSenselessConf) accountModelResultContent.getContent().getConf();
+        String mid = conf.getMchId();
+
+        //获取用户签约协议号
+        ChinaumsSenselessUserSignInfo userSignInfo = chinaumsSenselessUserSignInfoDao.findTopByUserIdAndMid(userId, mid);
+        if (userSignInfo==null || !userSignInfo.getContractState().equals(ContractState.SIGNED)){
+            return ResultContent.buildFail("用户未签约或状态未知");
+        }
+
+        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
+        payProductParameter.setAccountName(accountName);
+        ChinaSenselessPayRequest request = new ChinaSenselessPayRequest();
+        request.setMchntOrderId(orderNo);
+        request.setSrcReserve(JsonUtil.toJson(Map.of("userId", userId, "oid", oid, "projectOid", projectOid)));
+        request.setContractId(userSignInfo.getContractId());
+        request.setTotalAmount(total.toString());
+        request.setAttachedData(remark);
+        payProductParameter.setMeta(BeanUtil.bean2Map(request));
+        com.github.microservice.pay.client.ret.ResultContent<Object> collectionResultContent = senselessPayService.collection(payProductParameter);
+        return collectionResultContent;
+    }
+
+    public Object refund(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String refundOrderNo, String remark) {
+
+        String accountName = orgPayAccountService.queryOgPayAccount(projectOid, PaymentType.UnionFrictionlessPay);
+        com.github.microservice.pay.client.ret.ResultContent<AccountModel> accountModelResultContent = payProductAccountService.get(accountName);
+        if (!accountModelResultContent.getState().equals(ResultState.Success)){
+            return accountModelResultContent;
+        }
+        ChinaumsSenselessConf conf = (ChinaumsSenselessConf) accountModelResultContent.getContent().getConf();
+        String mid = conf.getMchId();
+
+        PayProductParameter<Object> payProductParameter = new PayProductParameter<>();
+        payProductParameter.setAccountName(accountName);
+        ChinaSenselessRefundRequest request = new ChinaSenselessRefundRequest();
+        request.setMchntOrderId(orderNo);
+        request.setVaMchntNo(mid);
+        request.setRefundAmount(total.toString());
+        request.setRefundOrderId(refundOrderNo);
+        request.setSysSource(JsonUtil.toJson(Map.of("userId", userId, "oid", oid, "projectOid", projectOid)));
+        payProductParameter.setMeta(BeanUtil.bean2Map(request));
+        return senselessPayService.refund(payProductParameter);
+    }
+
+    private Object handlePay(String projectOid, String oid, String userId, BigDecimal total, String orderNo, String remark) {
+        //TODO 判断支付状态
+
+        //获取项目总账
+        PayAccount projectParent = payAccountService.getProjectParent(projectOid);
+        //获取用户余额支付子账户
+        PayAccount userBalancePayment = payAccountService.getUserChildren(projectOid, userId, PaymentChannelType.SecretFreePayment);
+        //获取机构待结算账户
+        PayAccount orgWaitSettle = payAccountService.getOrgChildren(projectOid, oid, PaymentChannelType.WaitSettle);
+        //支付:项目余额子账- 用户无感支付子账+
+        //构建转账参数
+        TransferTransactionsModel transferModel = new TransferTransactionsModel();
+        //构建出账账户
+        TransferTransactionsModel.GeneralLedgerTransaction sourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        sourceTransaction.setGeneralLedgerId(projectParent.getLedgerId());
+        sourceTransaction.setOrderNumber(orderNo);
+        sourceTransaction.setTransactionType(TransactionType.Pay);
+        sourceTransaction.setTransactionStatus(TransactionStatus.Success);
+        sourceTransaction.setAmount(total.negate().longValue());
+        sourceTransaction.setRemark(remark);
+        sourceTransaction.setMeta(Map.of("paymentType",PaymentType.UnionFrictionlessPay, "description", "银联无感支付"));
+        transferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{sourceTransaction});
+
+        //构建入账账户
+        TransferTransactionsModel.GeneralLedgerTransaction destinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        destinationTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
+        destinationTransaction.setOrderNumber(orderNo);
+        destinationTransaction.setTransactionType(TransactionType.Pay);
+        destinationTransaction.setTransactionStatus(TransactionStatus.Success);
+        destinationTransaction.setAmount(total.longValue());
+        destinationTransaction.setRemark(remark);
+        destinationTransaction.setMeta(Map.of("paymentType",PaymentType.UnionFrictionlessPay, "description", "用户余额支付"));
+        transferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{destinationTransaction});
+        transactionLogService.transfer(transferModel);
+
+        //支付:项目余额子账- 用户无感支付子账+
+        //构建转账参数
+        TransferTransactionsModel payTransferModel = new TransferTransactionsModel();
+        //构建出账账户
+        TransferTransactionsModel.GeneralLedgerTransaction userSourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        userSourceTransaction.setGeneralLedgerId(userBalancePayment.getLedgerId());
+        userSourceTransaction.setOrderNumber(orderNo);
+        userSourceTransaction.setTransactionType(TransactionType.Pay);
+        userSourceTransaction.setTransactionStatus(TransactionStatus.Success);
+        userSourceTransaction.setAmount(total.negate().longValue());
+        userSourceTransaction.setRemark(remark);
+        userSourceTransaction.setMeta(Map.of("paymentType",PaymentType.UnionFrictionlessPay, "description", "银联无感支付"));
+        payTransferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{sourceTransaction});
+
+        //构建入账账户
+        TransferTransactionsModel.GeneralLedgerTransaction orgDestinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        destinationTransaction.setGeneralLedgerId(orgWaitSettle.getLedgerId());
+        destinationTransaction.setOrderNumber(orderNo);
+        destinationTransaction.setTransactionType(TransactionType.Pay);
+        destinationTransaction.setTransactionStatus(TransactionStatus.Success);
+        destinationTransaction.setAmount(total.longValue());
+        destinationTransaction.setRemark(remark);
+        destinationTransaction.setMeta(Map.of("paymentType",PaymentType.UnionFrictionlessPay, "description", "银联无感支付"));
+        payTransferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{destinationTransaction});
+        transactionLogService.transfer(payTransferModel);
+        return ResultContent.buildSuccess();
+    }
+
 
     private ChinaumsSenselessUserSignInfoModel toUserSignModel(ChinaumsSenselessUserSignInfo userSignInfo){
         ChinaumsSenselessUserSignInfoModel model = new ChinaumsSenselessUserSignInfoModel();

+ 2 - 2
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/pay/PayAccountService.java

@@ -134,7 +134,7 @@ public class PayAccountService {
         payAccount.setLevel(PayAccountLevel.OrgChildren);
         String ledgerId = createLedger("机构子账-" + channelType.getRemark(),
                 parent.getLedgerId(),
-                Map.of("projectOid", projectOid, "paymentChannelType", channelType, "level", PayAccountLevel.OrgChildren), 999999999L, -999999999L);
+                Map.of("projectOid", projectOid, "oid", oid,"paymentChannelType", channelType, "level", PayAccountLevel.OrgChildren), 999999999L, -999999999L);
         if (StringUtils.isBlank(ledgerId)){
             throw new Exception("支付中心创建用户子账失败");
         }
@@ -167,7 +167,7 @@ public class PayAccountService {
         payAccount.setUserId(userId);
         payAccount.setPaymentChannelType(channelType);
         payAccount.setLevel(PayAccountLevel.UserChildren);
-        String ledgerId = createLedger("用户子账-" + channelType.getRemark(), parent.getLedgerId(), Map.of("projectOid", projectOid, "paymentChannelType", channelType) , 999999999L, 0L);
+        String ledgerId = createLedger("用户子账-" + channelType.getRemark(), parent.getLedgerId(), Map.of("projectOid", projectOid, "paymentChannelType", channelType, "userId", userId) , 999999999L, 0L);
         if (StringUtils.isBlank(ledgerId)){
             throw new Exception("支付中心创建用户子账失败");
         }

+ 110 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/pay/SettleService.java

@@ -0,0 +1,110 @@
+package com.zhongshu.card.server.core.service.pay;
+
+import com.github.microservice.components.data.base.page.PageableModel;
+import com.github.microservice.pay.client.model.ledger.*;
+import com.github.microservice.pay.client.model.ledger.transaction.BaseQueryTransactionLogModel;
+import com.github.microservice.pay.client.model.ledger.transaction.GeneralLedgerQueryTransactionLogModel;
+import com.github.microservice.pay.client.model.ledger.transaction.TransactionLogAggregateRetModel;
+import com.github.microservice.pay.client.ret.ResultContent;
+import com.github.microservice.pay.client.ret.ResultState;
+import com.github.microservice.pay.client.service.ledger.TransactionLogService;
+import com.github.microservice.pay.client.type.ledger.TransactionStatus;
+import com.github.microservice.pay.client.type.ledger.TransactionType;
+import com.github.microservice.types.payment.PaymentChannelType;
+import com.github.microservice.types.payment.PaymentType;
+import com.zhongshu.card.client.type.SettleStatus;
+import com.zhongshu.card.server.core.domain.pay.PayAccount;
+import com.zhongshu.card.server.core.util.CommonUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.web.PagedModel;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Slf4j
+@Service
+public class SettleService {
+
+    @Autowired
+    PayAccountService payAccountService;
+
+    @Autowired
+    TransactionLogService transactionLogService;
+
+    @Autowired
+    SettleService settleService;
+
+    @Transactional
+    public Set<String> settle(String projectOid, String oid, Long startTime, Long endTime, String remark, PaymentType paymentType){
+        //获取机构-待结算子账
+        PayAccount waitSettleAccount = payAccountService.getOrgChildren(projectOid, oid, PaymentChannelType.WaitSettle);
+        //查询时间内所有待结算账单
+        GeneralLedgerQueryTransactionLogModel queryModel = new GeneralLedgerQueryTransactionLogModel();
+        PageableModel pageableModel = new PageableModel();
+        pageableModel.setPage(0);
+        pageableModel.setSize(1000000);
+        queryModel.setPage(pageableModel);
+        queryModel.setStartTime(startTime);
+        queryModel.setEndTime(endTime);
+        queryModel.setGeneralLedgerId(new String[]{waitSettleAccount.getLedgerId()});
+        //过滤出对应支付渠道的账单
+        queryModel.setFilter(Map.of("meta.paymentType", paymentType, "meta.settleStatus", SettleStatus.WaitSettle));
+        ResultContent<TransactionLogAggregateRetModel> aggregateResult = transactionLogService.aggregate(queryModel);
+        if (!aggregateResult.getState().equals(ResultState.Success)){
+            log.info("资金结算:查询待结算账单失败");
+            return null;
+        }
+        //收入-支出=可提现金额
+        Long settleAmount = aggregateResult.getContent().getStatistics().getCreditCount() - aggregateResult.getContent().getStatistics().getDebitCount();
+        //转账 机构待结算子账户-  机构待提现子账户+
+        PayAccount settleAccount = payAccountService.getOrgChildren(projectOid, oid, PaymentChannelType.Settle);
+
+        //构建转账参数
+        TransferTransactionsModel transferModel = new TransferTransactionsModel();
+        String settleNo = CommonUtil.UUID();
+        //构建出账账户
+        TransferTransactionsModel.GeneralLedgerTransaction sourceTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        sourceTransaction.setGeneralLedgerId(waitSettleAccount.getLedgerId());
+        sourceTransaction.setOrderNumber(settleNo);
+        sourceTransaction.setTransactionType(TransactionType.Settle);
+        sourceTransaction.setTransactionStatus(TransactionStatus.Success);
+        sourceTransaction.setAmount(-settleAmount);
+        sourceTransaction.setRemark(remark);
+        sourceTransaction.setMeta(Map.of("paymentType", paymentType, "paymentChannelType", paymentType.getChannelType(), "description", "结算"));
+        transferModel.setSource(new TransferTransactionsModel.GeneralLedgerTransaction[]{sourceTransaction});
+        //构建入账账户
+        TransferTransactionsModel.GeneralLedgerTransaction destinationTransaction = new TransferTransactionsModel.GeneralLedgerTransaction();
+        destinationTransaction.setGeneralLedgerId(settleAccount.getLedgerId());
+        destinationTransaction.setOrderNumber(settleNo);
+        destinationTransaction.setTransactionType(TransactionType.Settle);
+        destinationTransaction.setTransactionStatus(TransactionStatus.Success);
+        destinationTransaction.setAmount(settleAmount);
+        destinationTransaction.setRemark(remark);
+        destinationTransaction.setMeta(Map.of("paymentType", paymentType, "paymentChannelType", paymentType.getChannelType(), "description", "结算"));
+        transferModel.setDestinations(new TransferTransactionsModel.GeneralLedgerTransaction[]{destinationTransaction});
+        ResultContent<List<TransactionLogModel>> transfer = transactionLogService.transfer(transferModel);
+
+        List<TransactionLogModel> content = aggregateResult.getContent().getPages().getContent();
+
+        if (transfer.getState().equals(ResultState.Success)){
+            Set<String> orderNo = new HashSet<>();
+            content.forEach(it -> {
+                UpdateTransactionLogModel updateTransactionLogModel = new UpdateTransactionLogModel();
+                Map<String, Object> meta = it.getMeta();
+                meta.put("settleStatus", SettleStatus.Settle);
+                updateTransactionLogModel.setMeta(meta);
+                updateTransactionLogModel.setId(it.getId());
+                transactionLogService.update(updateTransactionLogModel);
+                orderNo.add(it.getOrderNumber());
+            });
+            return orderNo;
+        }
+        log.error("结算失败, projectOid: {}, paymentType: {}", projectOid, paymentType);
+        return null;
+    }
+}