增加分账指令模块,和表结构

This commit is contained in:
Jack 2025-05-18 23:49:10 +08:00
parent 42dc03453d
commit a01c9adb25
10 changed files with 276 additions and 34 deletions

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.common.modules.lakala;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("lkl_order_separate")
@ApiModel(value = "拉卡拉分账接收方", description = "拉卡拉分账接收方表")
public class LklOrderSeparate {
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增Id", example = "1")
private Long id;
@ApiModelProperty(value = "拉卡拉外部商户号")
private String merchant_no;
@ApiModelProperty(value = "拉卡拉对账单流水号 posp流水号查清结算用")
private String log_no;
@ApiModelProperty(value = "交易日期yyyyMMdd查清结算用")
private String log_date;
@ApiModelProperty(value = "商户分账指令流水号,每个商户号下唯一,否则会校验失败")
private String out_separate_no;
@ApiModelProperty(value = "分账指令流水号,分账系统生成唯一流水")
private String separate_no;
@ApiModelProperty(value = "分账总金额,单位:分")
private String total_amt;
@ApiModelProperty(value = "分账计算类型0- 按照指定金额1- 按照指定比例。默认 0")
private String cal_type;
@ApiModelProperty(value = "指令类型 SEPARATE-分账, CANCEL-分账撤销FALLBACK-分账回退")
private String cmd_type;
@ApiModelProperty(value = "分账接收类型0-全部分账到商户本身。1-分账到多方,默认 1")
private String separate_type;
@ApiModelProperty(value = "分账日期 yyyyMMdd")
private String separate_date;
@ApiModelProperty(value = "完成日期 yyyyMMdd")
private String finish_date;
@ApiModelProperty(value = "拉卡拉异步通知回调地址")
private String notify_url;
@ApiModelProperty(value = "分账接收数据对象JSON 格式")
private String recv_datas;
@ApiModelProperty(value = "最终分账明细JSON 格式")
private String detail_datas;
@ApiModelProperty(value = "拉卡拉机构编号")
private String lkl_org_no;
@ApiModelProperty(value = "分账状态PROCESSING-处理中, ACCEPTED-已受理, SUCCESS-成功, FAIL-失败")
private String status;
@ApiModelProperty(value = "处理状态ACCEPTED-已受理, PROCESSING-处理中, FAIL-失败, SUCCESS-成功")
private String final_status;
@ApiModelProperty(value = "新建时间")
private Date created_at;
@ApiModelProperty(value = "更新时间")
private Date updated_at;
}

View File

@ -81,7 +81,6 @@ public class ShopMchEntry implements Serializable {
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "店铺地区编号省份code/城市code/区code")
private String store_district;
@ -211,6 +210,9 @@ public class ShopMchEntry implements Serializable {
@ApiModelProperty(value = "拉卡拉银联商户号(唯一)")
private String lkl_mer_cup_no;
@ApiModelProperty(value = "拉卡拉分配的业务终端号")
private String lkl_term_no;
@ApiModelProperty(value = "拉卡拉审核状态1-已通过2-未通过")
private Integer lkl_tk_audit_status;

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.shop.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklOrderSeparate;
import org.springframework.stereotype.Repository;
@Repository
public interface LklOrderSeparateMapper extends BaseMapper<LklOrderSeparate> {
}

View File

@ -9,6 +9,7 @@
package com.suisung.mall.shop.lakala.service;
import cn.hutool.json.JSONObject;
import com.lkl.laop.sdk.request.V3SacsSeparateRequest;
import com.suisung.mall.common.api.CommonResult;
import org.springframework.data.util.Pair;
@ -181,13 +182,31 @@ public interface LakalaApiService {
*/
JSONObject getBankCardBin(String bankCardNo);
/**
* @param imgURL
* @param imgType 法人身份证正面图FR_ID_CARD_FRONT法人身份证反面FR_ID_CARD_BEHIND
* 身份证正面ID_CARD_FRONT身份证反面ID_CARD_BEHIND
* 营业执照BUSINESS_LICENSE银行卡BANK_CARD
* 查询拉卡拉商户可分账的金额
* 参考https://o.lakala.com/#/home/document/detail?id=394
*
* @param merchantNo 拉卡拉外部商户号
* @param logNo 拉卡拉对账单流水号
* @param logDate 拉卡拉对账单交易日期 yyyyMMdd
* @return 响应结果 {
* "merchant_no": "82229005943096D",
* "total_separate_amt": "9900",
* "can_separate_amt": "0",
* "log_date": "20221220",
* "log_no": "66210306990190"
* }
*/
JSONObject queryMchCanSplitAmt(String merchantNo, String logNo, String logDate);
/**
* 拉卡拉订单分账用户下单成功之后进行分账
* 说明分账指令是异步处理模式响应报文成功时指令状态是status: PROCESSING需要等待分账结果通知或者主动发起查询建议主动发起查询与分账指令动作之间间隔15秒以上
* 参考https://o.lakala.com/#/home/document/detail?id=389
*
* @param v3SacsSeparateRequest
* @return
*/
Pair<Boolean, String> innerDoOrderSeparate(V3SacsSeparateRequest v3SacsSeparateRequest);
}

View File

@ -62,6 +62,7 @@ import java.util.List;
public class LakalaApiServiceImpl implements LakalaApiService {
private static final boolean init = false;
private static final String lklSuccessCode = "000000";
private static final String lklSacsSuccessCode = "SACS0000";
// 可选的两个参数不同的店铺商家可以数据库里配置不同的商户号和终端号
@Value("${lakala.merchant_no}")
public String merchantNo; // 拉卡拉分配的商户号
@ -1165,7 +1166,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 判断分账接收方记录是否存在存在就不再新建了
LklLedgerReceiver lklLedgerReceiverOld = lklLedgerReceiverService.getByCondition(paramsJSON.getStr("licenseNo"), paramsJSON.getStr("contactMobile"), paramsJSON.getLong("platformId"));
if (lklLedgerReceiverOld != null) {
return CommonResult.success(lklLedgerReceiverOld, "分账接收方已创建过!");
return CommonResult.success(lklLedgerReceiverOld, "接收方已创建过!");
}
// 1. 配置初始化
@ -1232,7 +1233,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String responseStr = LKLSDK.httpPost(req);
JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
if (StrUtil.isBlank(responseStr) || lakalaRespJSON == null) {
return CommonResult.failed(I18nUtil._("创建分账接收方响应!"));
return CommonResult.failed(I18nUtil._("创建分账接收方响应数据无效"));
// throw new ApiException(I18nUtil._("创建分账接收方无响应!"));
}
@ -1609,5 +1610,95 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return null;
}
/**
* 查询拉卡拉商户可分账的金额
* 参考https://o.lakala.com/#/home/document/detail?id=394
*
* @param merchantNo 拉卡拉外部商户号
* @param logNo 拉卡拉对账单流水号
* @param logDate 拉卡拉对账单交易日期 yyyyMMdd
* @return 响应结果 {
* "merchant_no": "82229005943096D",
* "total_separate_amt": "9900",
* "can_separate_amt": "0",
* "log_date": "20221220",
* "log_no": "66210306990190"
* }
*/
@Override
public JSONObject queryMchCanSplitAmt(String merchantNo, String logNo, String logDate) {
if (StrUtil.isBlank(merchantNo) || (StrUtil.isBlank(logNo) && StrUtil.isBlank(logDate))) {
return null;
}
// 1. 配置初始化
initLKLSDK();
//2. 装配数据
V3SacsQueryAmtRequest req = new V3SacsQueryAmtRequest();
req.setMerchantNo(merchantNo);
req.setLogNo(logNo);
req.setLogDate(logDate);
try {
//3. 发送请求
String responseStr = LKLSDK.httpPost(req);
if (StrUtil.isBlank(responseStr)) {
log.error(I18nUtil._("服务器无返回值!"));
return null;
}
JSONObject lklRespJSON = JSONUtil.parseObj(responseStr);
if (lklRespJSON == null || !lklSacsSuccessCode.equals(lklRespJSON.getStr("code")) || lklRespJSON.get("resp_data") == null) {
log.error(I18nUtil._("返回值有误!"));
return null;
}
return (JSONObject) lklRespJSON.get("resp_data");
} catch (SDKException e) {
log.error("账户余额查询失败:", e);
return null;
}
}
/**
* 拉卡拉订单分账用户下单成功之后进行分账
* 说明分账指令是异步处理模式响应报文成功时指令状态是status: PROCESSING需要等待分账结果通知或者主动发起查询建议主动发起查询与分账指令动作之间间隔15秒以上
* 参考https://o.lakala.com/#/home/document/detail?id=389
*
* @param v3SacsSeparateRequest
* @return
*/
@Override
public Pair<Boolean, String> innerDoOrderSeparate(V3SacsSeparateRequest v3SacsSeparateRequest) {
if (v3SacsSeparateRequest == null) {
return Pair.of(false, "分账参数不能为空");
}
// 1. 配置初始化
initLKLSDK();
try {
log.debug("分账执行请求参数:{}", JSONUtil.toJsonStr(v3SacsSeparateRequest));
//3. 发送请求
String responseStr = LKLSDK.httpPost(v3SacsSeparateRequest);
if (StrUtil.isBlank(responseStr)) {
return Pair.of(false, "服务器无返回值!");
}
JSONObject lklRespJSON = JSONUtil.parseObj(responseStr);
if (lklRespJSON == null || !lklSacsSuccessCode.equals(lklRespJSON.getStr("code")) || lklRespJSON.get("resp_data") == null) {
log.error("返回值有误!");
return Pair.of(false, "返回值有误!");
}
return Pair.of(true, "分账成功执行,处理中");
} catch (SDKException e) {
log.error("账户余额查询失败:", e);
return Pair.of(false, "分账发生错误");
}
}
}

View File

@ -578,13 +578,18 @@ public class LklTkServiceImpl {
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号
String merInnerNo = dataJSON.getStr("customerNo"); //拉卡拉内部商户号
String termNos = dataJSON.getStr("termNos"); //拉卡拉分配的业务终端号
if (StrUtil.isBlank(merInnerNo) || StrUtil.isBlank(merCupNo)) {
return new JSONObject().set("code", "FAIL").set("message", "返回数据有误");
}
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo);
if (ObjectUtil.isEmpty(shopMchEntry)) {
logger.error("拉卡拉进件异步通知:返回的内部商户号:{} 入驻信息不存在!", merInnerNo);
return new JSONObject().put("code", "FAIL").put("message", "内部商户号:" + merInnerNo + " 入驻信息不存在");
}
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(merInnerNo, merCupNo, CommonConstant.Enable, null, data);
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(merInnerNo, merCupNo, termNos, CommonConstant.Enable, null, data);
if (!success) {
return new JSONObject().set("code", "FAIL").set("message", "更新商户号失败");
// throw new ApiException("更新商户号失败");
@ -610,29 +615,27 @@ public class LklTkServiceImpl {
// 1电子合同给商家申请分账功能使用务必检查是否申请过申请过忽略
// 下一步等待拉卡拉审核通过再绑定接收方和商家的关系
Pair<Boolean, String> retPair = lakalaApiService.innerApplyLedgerMer(merCupNo);
// 2新增一个接收方记录起码要一个平台方代理商根据入驻信息新增
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(merCupNo, shopMchEntry.getDistributor_id());
if (retPair.getFirst() && genSuccess) {
return new JSONObject().put("code", "SUCCESS").put("message", "处理成功");
}
if (!retPair.getFirst()) {
String message = "商家申请分账功能失败:" + retPair.getSecond();
logger.error(message);
return new JSONObject().set("code", "FAIL").set("message", message);
// throw new ApiException(message);
}
// 2新增一个接收方记录起码要一个平台方代理商根据入驻信息新增
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(merCupNo, shopMchEntry.getDistributor_id());
if (!genSuccess) {
logger.error("申请分账接收方失败");
return new JSONObject().set("code", "FAIL").set("message", "申请分账接收方失败");
// throw new ApiException("申请分账接收方失败");
}
// 更新商家的hasEsigned状态=1
// lklLedgerMemberService.updateMulStatus("", shopMchEntry.getLogin_mobile(), 1, 0, 0, 0);
return new JSONObject().put("code", "SUCCESS").put("message", "处理成功");
}
return new JSONObject().set("code", "FAIL").set("message", "进件回调处理失败");
// throw new ApiException("进件回调处理失败");
}
/**

View File

@ -158,16 +158,17 @@ public interface ShopMchEntryService {
Boolean updateMerchEntryLklMerCupNo(String loginMobile, Integer lklAuditStatus, String lklMerCupNo, String lklMerInnerNo, String lklTkRegParams, String lklTkRegResp);
/**
* 更新商家入驻申请的拉卡拉审核状态和响应数据
* 根据拉卡拉内部商户号更新商家入驻申请的拉卡拉审核状态和响应数据
*
* @param lklMerCupNo 拉卡拉银联商户号
* @param lklInnerMerNo 拉卡拉内部商户号
* @param lklAuditStatus 拉卡拉审核状态
* @param approvalStatus 审批状态
* @param lklTkRegResp 进件返回的数据
* @param lklInnerMerNo 拉卡拉内部商户号
* @param lklMerCupNo 拉卡拉外部商户号
* @param termNos 拉卡拉分配的业务终端号
* @param lklAuditStatus 拉卡拉审核状态
* @param approvalStatus 入驻材料审核状态
* @param lklTkRegNotifyReq lklTkRegResp 异步请求参数
* @return
*/
Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklMerCupNo, String lklInnerMerNo, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegResp);
Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklMerCupNo, String lklInnerMerNo, String termNos, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegNotifyReq);
/**

View File

@ -800,14 +800,16 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
/**
* 根据拉卡拉内部商户号更新商家入驻申请的拉卡拉审核状态和响应数据
*
* @param lklInnerMerNo
* @param lklMerCupNo
* @param lklAuditStatus
* @param lklTkRegNotifyReq
* @param lklInnerMerNo 拉卡拉内部商户号
* @param lklMerCupNo 拉卡拉外部商户号
* @param termNos 拉卡拉分配的业务终端号
* @param lklAuditStatus 拉卡拉审核状态
* @param approvalStatus 入驻材料审核状态
* @param lklTkRegNotifyReq 异步通知返回的请求数据
* @return
*/
@Override
public Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklInnerMerNo, String lklMerCupNo, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegNotifyReq) {
public Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklMerCupNo, String lklInnerMerNo, String termNos, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegNotifyReq) {
if (StrUtil.isBlank(lklMerCupNo)) {
return false;
}
@ -819,6 +821,10 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
updateWrapper.set("lkl_mer_cup_no", lklMerCupNo);
}
if (StrUtil.isNotBlank(termNos)) {
updateWrapper.set("lkl_term_no", termNos);
}
if (ObjectUtil.isNotEmpty(lklAuditStatus)) {
updateWrapper.set("lkl_tk_audit_status", lklAuditStatus);
}
@ -830,8 +836,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
if (StrUtil.isNotBlank(lklTkRegNotifyReq)) {
updateWrapper.set("lkl_tk_reg_notify_req", lklTkRegNotifyReq);
}
return update(updateWrapper);
}

View File

@ -3051,6 +3051,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
shopStoreBase.setStore_is_selfsupport(0);
shopStoreBase.setStore_o2o_flag(0);
shopStoreBase.setSubsite_id(0);
// 拉卡拉外部商户号
shopStoreBase.setLkl_merchant_no(shopMchEntry.getLkl_mer_cup_no());
// 拉卡拉分配的终端号
shopStoreBase.setLkl_term_no(shopMchEntry.getLkl_term_no());
shopStoreBase.setStore_state_id(StateCode.STORE_STATE_YES);//店铺资料信息状态(ENUM):3210-待完善资料; 3220-等待审核 ; 3230-资料审核没有通过;3240-资料审核通过,待付款
shopStoreBase.setStore_time(DateUtil.date());
shopStoreBase.setStore_end_time(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * 5); // 5年

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklOrderSeparateMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>