Merge #68 into master from cc_20260313_ws_wallet

网商钱包分账对接

* cc_20260313_ws_wallet: (9 commits squashed)

  - fix:新店开通网商钱包

  - fix:网商钱包开通回调修改

  - fix

  - fix

  - fix:关闭网商开通回调接口验签

  - Merge branch 'master' into cc_20260313_ws_wallet
    
    # Conflicts:
    #	coolstore-partner-service/src/main/java/com/cool/store/service/wallet/WalletService.java
    #	coolstore-partner-service/src/main/java/com/cool/store/service/wallet/impl/WalletServiceImpl.java
    #	coolstore-partner-web/src/main/java/com/cool/store/controller/webc/MiniWalletController.java

  - fix:钱包批量转账新增钱包类型字段

  - fix:网商钱包分账对接

  - fix

Signed-off-by: 王非凡 <accounts_67eba0c5fee9c49c80c8e2b4@mail.teambition.com>
Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>

CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/68
This commit is contained in:
王非凡
2026-03-23 09:00:24 +00:00
committed by 正新
parent 3b1e6f6cb9
commit 728bd0f8ef
20 changed files with 218 additions and 14 deletions

View File

@@ -18,7 +18,8 @@ public enum AllocationPayStatusEnum {
PAID(1, "已支付"),
FAIL(2, "支付失败"),
PAYING(3, "支付中"),
CANCEL(4, "已取消")
CANCEL(4, "已取消"),
UNPAID(5, "未支付"),
;
private final Integer status;

View File

@@ -6,6 +6,7 @@ import com.cool.store.mapper.fees.ShopAllocationInfoMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
import java.util.Objects;
@@ -60,4 +61,23 @@ public class ShopAllocationInfoDAO {
}
shopAllocationInfoMapper.insertOrUpdateBatch(list);
}
/**
* 更新分账状态
* @param shopId 门店id
* @param expenseTypes 费用类型列表
* @param status 状态
*/
public void updateStatusByShopId(Long shopId, List<String> expenseTypes, Integer status) {
if (CollectionUtils.isEmpty(expenseTypes)) {
return;
}
Example example = new Example(ShopAllocationInfoDO.class);
example.createCriteria()
.andEqualTo("shopId", shopId)
.andIn("expenseType", expenseTypes);
ShopAllocationInfoDO allocationInfoDO = new ShopAllocationInfoDO();
allocationInfoDO.setStatus(status);
shopAllocationInfoMapper.updateByExampleSelective(allocationInfoDO, example);
}
}

View File

@@ -125,4 +125,28 @@ public class WalletPayInfoDAO {
walletPayInfoDO.setClaimStatus(claimStatus);
walletPayInfoMapper.updateByExampleSelective(walletPayInfoDO, example);
}
/**
* 根据批次编号查询
* @param batchCode 批次编号
* @return 列表
*/
public List<WalletPayInfoDO> getByBatchCode(String batchCode) {
Example example = new Example(WalletPayInfoDO.class);
example.createCriteria().andEqualTo("batchCode", batchCode);
return walletPayInfoMapper.selectByExample(example);
}
/**
* 根据批次编号更新支付状态
* @param batchCode 批次编号
* @param payStatus 支付状态
*/
public void updatePayStatusByBatchCode(String batchCode, Integer payStatus) {
Example example = new Example(WalletPayInfoDO.class);
example.createCriteria().andEqualTo("batchCode", batchCode);
WalletPayInfoDO walletPayInfoDO = new WalletPayInfoDO();
walletPayInfoDO.setPayStatus(payStatus);
walletPayInfoMapper.updateByExampleSelective(walletPayInfoDO, example);
}
}

View File

@@ -56,4 +56,27 @@ public class WalletTradeDAO {
}
return walletTradeMapper.updateBatchByPayNo(list) > 0;
}
/**
* 查询支付中交易单批次号
* @param module 业务模块
* @param type 交易类型
* @return 批次号列表
*/
public List<String> getPayingOrderBatchCode(String module, Integer type) {
return walletTradeMapper.getPayingOrderBatchCode(module, type);
}
/**
* 根据批次号更新支付状态
* @param batchCode 批次号
* @param payStatus 支付状态
*/
public void updatePayStatusByBatchCode(String batchCode, Integer payStatus) {
Example example = new Example(WalletTradeDO.class);
example.createCriteria().andEqualTo("batchCode", batchCode);
WalletTradeDO walletTradeDO = new WalletTradeDO();
walletTradeDO.setPayStatus(payStatus);
walletTradeMapper.updateByExampleSelective(walletTradeDO, example);
}
}

View File

@@ -12,4 +12,12 @@ public interface WalletTradeMapper extends Mapper<WalletTradeDO> {
int updateByPayNo(WalletTradeDO record);
int updateBatchByPayNo(@Param("list") List<WalletTradeDO> list);
/**
* 查询支付中交易单批次号
* @param module 业务模块
* @param type 交易类型
* @return 批次号列表
*/
List<String> getPayingOrderBatchCode(@Param("module") String module, @Param("type") Integer type);
}

View File

@@ -18,13 +18,14 @@
<result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="create_user_id" jdbcType="VARCHAR" property="createUserId" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="batch_code" jdbcType="VARCHAR" property="batchCode" />
</resultMap>
<insert id="insertBatch" parameterType="java.util.List">
INSERT INTO zxjp_fees_wallet_pay_info (shop_id, module, pay_no, pay_user_name, pay_amount, trade_id, pay_status, pay_time, claim_status, expense_types, remark, create_user_id)
INSERT INTO zxjp_fees_wallet_pay_info (shop_id, module, pay_no, pay_user_name, pay_amount, trade_id, pay_status, pay_time, claim_status, expense_types, remark, create_user_id, batch_code)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.shopId}, #{item.module}, #{item.payNo}, #{item.payUserName}, #{item.payAmount}, #{item.tradeId}, #{item.payStatus}, #{item.payTime}, #{item.claimStatus}, #{item.expenseTypes}, #{item.remark}, #{item.createUserId})
(#{item.shopId}, #{item.module}, #{item.payNo}, #{item.payUserName}, #{item.payAmount}, #{item.tradeId}, #{item.payStatus}, #{item.payTime}, #{item.claimStatus}, #{item.expenseTypes}, #{item.remark}, #{item.createUserId}, #{item.batchCode})
</foreach>
</insert>

View File

@@ -17,14 +17,15 @@
<result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="create_user_id" jdbcType="VARCHAR" property="createUserId" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="batch_code" jdbcType="VARCHAR" property="batchCode" />
</resultMap>
<!-- 批量新增 -->
<insert id="insertBatch" parameterType="java.util.List">
INSERT INTO zxjp_wallet_trade (module, pay_no, trade_id, type, pay_user_name, pay_amount, pay_status, pay_time, remark, create_user_id)
INSERT INTO zxjp_wallet_trade (module, pay_no, trade_id, type, pay_user_name, pay_amount, pay_status, pay_time, remark, create_user_id, batch_code)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.module}, #{item.payNo}, #{item.tradeId}, #{item.type}, #{item.payUserName}, #{item.payAmount}, #{item.payStatus}, #{item.payTime}, #{item.remark}, #{item.createUserId})
(#{item.module}, #{item.payNo}, #{item.tradeId}, #{item.type}, #{item.payUserName}, #{item.payAmount}, #{item.payStatus}, #{item.payTime}, #{item.remark}, #{item.createUserId}, #{item.batchCode})
</foreach>
</insert>
@@ -63,4 +64,11 @@
WHERE pay_no = #{item.payNo}
</foreach>
</update>
<select id="getPayingOrderBatchCode" resultType="java.lang.String">
SELECT batch_code, pay_status
FROM zxjp_wallet_trade
WHERE pay_status = 3 AND module = #{module} AND type = #{type} AND batch_code IS NOT NULL
GROUP BY batch_code
</select>
</mapper>

View File

@@ -19,6 +19,9 @@ public class BatchTransferDTO {
@ApiModelProperty("批量转账数据")
private List<TransDataRequest> transArray;
@ApiModelProperty("批次号")
private String batchCode;
@Data
public static class TransDataRequest {

View File

@@ -102,6 +102,12 @@ public class WalletPayInfoDO {
@Column(name = "create_time")
private Date createTime;
/**
* 批量分账批次号
*/
@Column(name = "batch_code")
private String batchCode;
public WalletPayInfoDO(String module, Long shopId, String payNo, String payUserName, BigDecimal payAmount, String expenseType, String createUserId, String tradeId) {
this.shopId = shopId;
this.payNo = payNo;
@@ -127,6 +133,7 @@ public class WalletPayInfoDO {
walletTradeDO.setPayTime(this.payTime);
walletTradeDO.setRemark(this.remark);
walletTradeDO.setCreateUserId(this.createUserId);
walletTradeDO.setBatchCode(this.batchCode);
return walletTradeDO;
}
}

View File

@@ -85,4 +85,10 @@ public class WalletTradeDO {
*/
@Column(name = "create_time")
private Date createTime;
/**
* 批量分账批次号
*/
@Column(name = "batch_code")
private String batchCode;
}

View File

@@ -19,7 +19,7 @@ public class FranchisePayTypeUpdateRequest {
@NotNull(message = "门店id不能为空")
private Long shopId;
@ApiModelProperty("支付方式1线下支付 2平安钱包支付")
@ApiModelProperty("支付方式1线下支付 2网商钱包支付")
@NotNull(message = "支付方式不能为空")
private Integer payType;
}

View File

@@ -0,0 +1,22 @@
package com.cool.store.request.wallet;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>
* 批量转账分账查询
* </p>
*
* @author wangff
* @since 2026/3/18
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BatchTransferQueryRequest {
@ApiModelProperty("批次号")
private String batchCode;
}

View File

@@ -17,6 +17,10 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
public class BatchTransferRequest {
/**
* 钱包类型1平安2网商
*/
private Integer walletType = 2;
private String outStoreId;

View File

@@ -22,7 +22,7 @@ public class ReceiptCallBackRequest {
private Integer claimStatus;
/**
* 支付方式,线下支付-0平安钱包支付-2
* 支付方式,线下支付-0网商钱包支付-2
*/
private Integer payWay;

View File

@@ -25,6 +25,12 @@ public interface WalletPayInfoService {
*/
Boolean pay(WalletPayRequest request, String oldPayNo);
/**
* 查询并更新批量支付结果
* @param batchCode 批次编号
*/
void queryAndUpdateBatchTransferStatus(String batchCode);
/**
* 重新支付
* @param request 钱包重新支付Request

View File

@@ -15,6 +15,7 @@ import com.cool.store.dao.fees.WalletPayInfoDAO;
import com.cool.store.dao.wallet.WalletTradeDAO;
import com.cool.store.dto.wallet.AccountInfoDTO;
import com.cool.store.dto.wallet.BatchTransferDTO;
import com.cool.store.request.wallet.BatchTransferQueryRequest;
import com.cool.store.request.wallet.BatchTransferRequest;
import com.cool.store.dto.wallet.TransferDTO;
import com.cool.store.entity.FranchiseFeeDO;
@@ -123,7 +124,7 @@ public class WalletPayInfoServiceImpl implements WalletPayInfoService {
assert feeItem != null;
return new BatchTransferRequest.TransDataRequest(payNo, feeItem.getFeeItemId(), shopAllocationInfoDO.getPayeeCode(), null, payAmount.toString(), feeItem.getDesc());
});
BatchTransferRequest transRequest = new BatchTransferRequest(shopInfo.getStoreId(), request.getPayPwd(), transDataList);
BatchTransferRequest transRequest = new BatchTransferRequest(2, shopInfo.getStoreId(), request.getPayPwd(), transDataList);
BatchTransferDTO batchTransferDTO = walletApiService.batchTransfer(transRequest);
if (CollectionUtils.isEmpty(batchTransferDTO.getTransArray())) {
throw new ServiceException(ErrorCodeEnum.WALLET_TRANS_FAIL);
@@ -134,7 +135,8 @@ public class WalletPayInfoServiceImpl implements WalletPayInfoService {
WalletPayInfoDO walletPayInfoDO = new WalletPayInfoDO(
WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), request.getShopId(), transResult.getReqNo(), user.getUsername(), new BigDecimal(transResult.getAmount()), feeItemEnum.getExpenseType(), user.getPartnerId(), String.valueOf(transResult.getTradeId())
);
// 这里只返回成功或失败
walletPayInfoDO.setBatchCode(batchTransferDTO.getBatchCode());
// 平安这里只返回成功或失败,网商只返回处理中
walletPayInfoDO.setPayStatus(batchTransferDTO.getTradeStatus());
if (StringUtils.isNotBlank(oldPayNo)) {
walletRePayInfoList.add(walletPayInfoDO);
@@ -179,6 +181,35 @@ public class WalletPayInfoServiceImpl implements WalletPayInfoService {
return true;
}
@Override
@Transactional
public void queryAndUpdateBatchTransferStatus(String batchCode) {
BatchTransferDTO batchTransferDTO = walletApiService.queryBatchTransfer(new BatchTransferQueryRequest(batchCode));
// 根据批次号更新交易单
walletTradeDAO.updatePayStatusByBatchCode(batchCode, batchTransferDTO.getTradeStatus());
// 根据批次号更新业务单
List<WalletPayInfoDO> payInfoList = walletPayInfoDAO.getByBatchCode(batchCode);
if (CollectionUtils.isEmpty(payInfoList)) {
log.error("查询并更新批量转账状态异常,业务单为空");
return;
}
walletPayInfoDAO.updatePayStatusByBatchCode(batchCode, batchTransferDTO.getTradeStatus());
// 更新分账信息
Long shopId = payInfoList.get(0).getShopId();
List<String> expenseTypes = CollStreamUtil.toList(payInfoList, WalletPayInfoDO::getExpenseTypes);
shopAllocationInfoDAO.updateStatusByShopId(shopId, expenseTypes, batchTransferDTO.getTradeStatus());
// 校验并流转流程
if (AllocationPayStatusEnum.PAID.getStatus().equals(batchTransferDTO.getTradeStatus())) {
ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
// 校验并流转流程
verifyAndProcessFlow(shopInfo.getId());
// 推送缴费单数据到新管家
if (CollectionUtils.isNotEmpty(payInfoList)) {
pushReceiptRequest(payInfoList, shopInfo);
}
}
}
/**
* 推送账单到新管家
*/

View File

@@ -954,6 +954,7 @@ public class MiniStoreOrderServiceImpl implements MiniStoreOrderService {
BatchTransferRequest batchTransferRequest = new BatchTransferRequest();
batchTransferRequest.setOutStoreId(shopInfo.getStoreId());
batchTransferRequest.setPayPwd(request.getPayPwd());
batchTransferRequest.setWalletType(2);
List<BatchTransferRequest.TransDataRequest> transArray = new ArrayList<>();
for (PreAllocationRecordDO record : allocationRecords) {

View File

@@ -275,4 +275,11 @@ public class WalletApiService {
public WsPayAccountDTO wsPayAccountQuery(OutStoreIdRequest request) {
return walletHttpClientRest.postWithSign(walletBaseUrl + "/open/crm/account/ws/v1/queryCollectionAccount", request, WsPayAccountDTO.class);
}
/**
* 批量转账分账查询
*/
public BatchTransferDTO queryBatchTransfer(BatchTransferQueryRequest request) {
return walletHttpClientRest.postWithSign(walletBaseUrl + "/open/crm/trans/v1/queryBatchTransfer", request, BatchTransferDTO.class);
}
}

View File

@@ -116,6 +116,7 @@ public class TestController {
ReceiptCallBackRequest receiptRequest = new ReceiptCallBackRequest();
receiptRequest.setReceiptId(payInfoDO.getPayNo());
receiptRequest.setClaimStatus(1);
receiptRequest.setPayWay(2);
openApiService.changeReceiptStatus(receiptRequest);
List<WalletPayInfoDO> list = walletPayInfoDAO.getByShopId(payInfoDO.getShopId(), WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), null);
List<ShopAllocationInfoDO> allocationList = shopAllocationInfoDAO.getByShopId(payInfoDO.getShopId());

View File

@@ -5,17 +5,16 @@ import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.*;
import com.cool.store.dao.tp.TpApplyFormDAO;
import com.cool.store.dao.wallet.WalletTradeDAO;
import com.cool.store.dto.*;
import com.cool.store.dto.store.StoreOrderTimeDTO;
import com.cool.store.dto.xgj.XgjPayResultDTO;
import com.cool.store.entity.*;
import com.cool.store.entity.tp.TpApplyFormDO;
import com.cool.store.enums.*;
import com.cool.store.enums.tp.TpFormStatusEnum;
import com.cool.store.enums.close.CloseTypeEnum;
import com.cool.store.enums.close.RefundPayStatusEnum;
import com.cool.store.enums.close.XgjRefundPayStatusEnum;
import com.cool.store.enums.master.StoreCloseReasonEnum;
import com.cool.store.enums.wallet.WalletTradeModuleEnum;
import com.cool.store.mapper.ApplyLicenseMapper;
import com.cool.store.mapper.LineInfoMapper;
import com.cool.store.mapper.TrainingExperienceMapper;
@@ -25,14 +24,13 @@ import com.cool.store.request.ZxjpApiRequest;
import com.cool.store.request.bigdata.LatestOrderDateRequest;
import com.cool.store.request.tp.TpApplyQueryRequest;
import com.cool.store.request.close.store.CloseStoreApplyRequest;
import com.cool.store.request.xgj.XgjPaymentRequest;
import com.cool.store.response.bigdata.LatestOrderDateResponse;
import com.cool.store.service.*;
import com.cool.store.service.close.CloseStoreRefundService;
import com.cool.store.service.close.CloseStoreService;
import com.cool.store.service.fees.WalletPayInfoService;
import com.cool.store.service.impl.CommonService;
import com.cool.store.service.tp.TpApplyService;
import com.cool.store.utils.CoolDateUtils;
import com.cool.store.utils.MDCUtils;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
@@ -129,6 +127,10 @@ public class XxlJobHandler {
ThirdXgjService thirdXgjService;
@Resource
CloseStoreRefundService closeStoreRefundService;
@Resource
WalletPayInfoService walletPayInfoService;
@Resource
WalletTradeDAO walletTradeDAO;
/**
@@ -612,4 +614,33 @@ public class XxlJobHandler {
}
log.info("------end refundOrderStatus------");
}
/**
* 钱包批量转账分账支付状态查询
*/
@XxlJob("batchTransferQuery")
public void batchTransferQuery() {
MDCUtils.put(CommonConstants.REQUEST_ID, UUID.randomUUID().toString());
log.info("------start batchTransferQuery------");
boolean hasNext = true;
int pageNum = 1;
int pageSize = CommonConstants.BATCH_SIZE;
while (hasNext) {
PageHelper.startPage(pageNum, pageSize);
List<String> batchCodes = walletTradeDAO.getPayingOrderBatchCode(WalletTradeModuleEnum.FRANCHISE_PAY.getModule(), 1);
hasNext = batchCodes.size() >= pageSize;
if (CollectionUtils.isEmpty(batchCodes)) {
break;
}
for (String batchCode : batchCodes) {
try {
walletPayInfoService.queryAndUpdateBatchTransferStatus(batchCode);
} catch (Exception e) {
log.error("钱包批量转账分账支付状态查询失败, batchCode:{}", batchCode, e);
}
}
pageNum++;
}
log.info("------end batchTransferQuery------");
}
}