可用分账金额查询接口开发

This commit is contained in:
Jack 2025-09-17 20:00:57 +08:00
parent cb96775ee6
commit 2a26e37d62
13 changed files with 156 additions and 24 deletions

View File

@ -44,8 +44,12 @@ public class ShopOrderLkl implements Serializable {
private Integer split_amt;
private Integer split_amt_ref;
private Integer shopping_fee;
private Integer shopping_fee_inner;
private BigDecimal split_ratio;
private String payment_time;
@ -92,6 +96,8 @@ public class ShopOrderLkl implements Serializable {
private Integer separate_status;
private String separate_remark;
private Integer status;
private Date created_at;

View File

@ -142,8 +142,8 @@ public class LklSeparateDTO implements java.io.Serializable {
// 基于总金额的分账计算测试用例带refCanSeparateAmount
logger.info("\n\n基于总金额的分账计算测试用例 - 带参考可分账金额:");
LklSeparateDTO dto7 = new LklSeparateDTO();
dto7.setTotalSeparateAmount(502);
dto7.setShippingFee(500);
dto7.setTotalSeparateAmount(1);
dto7.setShippingFee(0);
dto7.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉比例0.25%
dto7.setMchRatio(new BigDecimal("0.94")); // 商户比例90%
dto7.setPlatRatio(new BigDecimal("0.01")); // 平台比例5%

View File

@ -0,0 +1,42 @@
/*
* 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.controller.admin;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "拉卡拉相关接口 - 后端控制器")
@RestController
@RequestMapping("/admin/shop/lakala")
public class LakalaAdminController extends BaseControllerImpl {
@Resource
private LakalaApiService lakalaPayService;
@ApiOperation(value = "查询拉卡拉商户可分账的金额", notes = "查询拉卡拉商户可分账的金额")
@RequestMapping(value = "/sacs/queryMchSplitAmt", method = RequestMethod.POST)
public CommonResult queryMchCanSplitAmt(@RequestBody JSONObject paramsJSON) {
JSONObject resultJSON = lakalaPayService.queryMchCanSplitAmtInner(paramsJSON.getStr("merchantNo"), paramsJSON.getStr("logNo"), paramsJSON.getStr("logDate"));
if (resultJSON != null) {
return CommonResult.success(resultJSON);
}
return CommonResult.failed();
}
}

View File

@ -162,13 +162,6 @@ public class LakalaController extends BaseControllerImpl {
@ApiOperation(value = "跳转到拉卡拉签署合同链接", notes = "跳转到拉卡拉签署合同链接")
@RequestMapping(value = "/sign/ec/{code}", method = RequestMethod.GET)
public ModelAndView jumpToSignLklEcLink(@PathVariable Long code) {
// // 根据 code 值决定重定向到哪个 URL
// String resultUrl = lklLedgerEcService.getLklEcResultUrl(code);
// if (StrUtil.isBlank(resultUrl)) {
// return new RedirectView("https://mall.gpxscs.cn/mchapp");
// }
// return new RedirectView(resultUrl);
// 根据 code 值获取结果 URL
String resultUrl = lklLedgerEcService.getLklEcResultUrl(code);

View File

@ -235,6 +235,23 @@ public interface LakalaApiService {
*/
Pair<String, String> queryMchCanSplitAmt(String merchantNo, String logNo, String logDate);
/**
* 查询拉卡拉商户可分账的金额
* 参考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 queryMchCanSplitAmtInner(String merchantNo, String logNo, String logDate);
/**
* 订单分账撤销
* 参考https://o.lakala.com/#/home/document/detail?id=390

View File

@ -1747,6 +1747,52 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return null;
}
try {
JSONObject respData = queryMchCanSplitAmtInner(merchantNo, logNo, logDate);
if (respData == null) {
log.error("[查询可分账金额] 内部查询返回空结果, merchantNo={}, logNo={}, logDate={}", merchantNo, logNo, logDate);
return null;
}
String totalSeparateAmt = respData.getStr("total_separate_amt");
String canSeparateAmt = respData.getStr("can_separate_amt");
if (StringUtils.isAnyBlank(totalSeparateAmt, canSeparateAmt)) {
log.error("[查询可分账金额] 返回数据字段缺失, merchantNo={}, logNo={}, logDate={}, totalSeparateAmt={}, canSeparateAmt={}",
merchantNo, logNo, logDate, totalSeparateAmt, canSeparateAmt);
return null;
}
return Pair.of(totalSeparateAmt, canSeparateAmt);
} catch (Exception e) {
log.error("[查询可分账金额] 查询过程中发生未知异常, merchantNo={}, logNo={}, logDate={}", merchantNo, logNo, logDate, e);
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 queryMchCanSplitAmtInner(String merchantNo, String logNo, String logDate) {
if (StringUtils.isAnyBlank(merchantNo, logNo, logDate)) {
log.warn("[查询可分账金额] 参数校验失败:缺少必要参数, merchantNo={}, logNo={}, logDate={}", merchantNo, logNo, logDate);
return null;
}
try {
log.info("[查询可分账金额] 开始查询商户可分账金额, merchantNo={}, logNo={}, logDate={}", merchantNo, logNo, logDate);
@ -1767,27 +1813,33 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
JSONObject lklRespJSON = JSONUtil.parseObj(responseStr);
if (lklRespJSON == null || !lklSacsSuccessCode.equals(lklRespJSON.getStr("code")) || lklRespJSON.get("resp_data") == null) {
if (lklRespJSON == null || !lklSacsSuccessCode.equals(lklRespJSON.getStr("code"))) {
log.error("[查询可分账金额] 返回值有误, merchantNo={}, logNo={}, logDate={}, response={}",
merchantNo, logNo, logDate, responseStr);
return null;
}
JSONObject respData = (JSONObject) lklRespJSON.get("resp_data");
if (respData == null
|| StringUtils.isAnyBlank(respData.getStr("total_separate_amt"), respData.getStr("can_separate_amt"))) {
Object respDataObj = lklRespJSON.get("resp_data");
if (respDataObj == null || !(respDataObj instanceof JSONObject)) {
log.error("[查询可分账金额] 返回数据字段缺失或格式错误, merchantNo={}, logNo={}, logDate={}, respData={}",
merchantNo, logNo, logDate, respDataObj);
return null;
}
JSONObject respData = (JSONObject) respDataObj;
String totalSeparateAmt = respData.getStr("total_separate_amt");
String canSeparateAmt = respData.getStr("can_separate_amt");
if (StringUtils.isAnyBlank(totalSeparateAmt, canSeparateAmt)) {
log.error("[查询可分账金额] 返回数据字段缺失, merchantNo={}, logNo={}, logDate={}, respData={}",
merchantNo, logNo, logDate, respData);
return null;
}
String totalSeparateAmt = respData.getStr("total_separate_amt");
String canSeparateAmt = respData.getStr("can_separate_amt");
log.info("[查询可分账金额] 查询成功, merchantNo={}, logNo={}, logDate={}, totalSeparateAmt={}, canSeparateAmt={}",
merchantNo, logNo, logDate, totalSeparateAmt, canSeparateAmt);
return Pair.of(totalSeparateAmt, canSeparateAmt);
return respData;
} catch (SDKException e) {
log.error("[查询可分账金额] 账户余额查询失败, merchantNo={}, logNo={}, logDate={}", merchantNo, logNo, logDate, e);
return null;
@ -2265,7 +2317,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String errorMsg = String.format("[分账操作] 拉卡拉无响应,订单=%s商户=%s分账流水号=%s",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no());
// 更改分账状态分账失败
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail);
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
log.error(errorMsg);
return Pair.of(false, "拉卡拉无响应");
}
@ -2278,7 +2330,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String errorMsg = String.format("[分账操作] 拉卡拉返回格式异常,订单=%s商户=%s分账流水号=%s响应=%srespJson=%s",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no(), response, respJson);
// 更改分账状态分账失败
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail);
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
log.error(errorMsg);
return Pair.of(false, "拉卡拉分账异常:[" + respJson.getStr("code") + "]" + respJson.getStr("msg"));
}
@ -2452,9 +2504,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 8. 持久化处理 - 更新分账记录到数据库
boolean updateSuccess = lklOrderSeparateService.addOrUpdateByReceiverNo(lklOrderSeparate);
if (!updateSuccess) {
// 更改分账状态分账失败
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Fail);
String errorMsg = String.format("分账记录更新失败, separateNo=%s", separateNo);
// 更改分账状态分账失败
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Fail, errorMsg);
log.error("[拉卡拉分账通知] {}", errorMsg);
return JSONUtil.createObj()
.put("code", "FAIL")
@ -2462,7 +2514,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
// 更改分账状态分账成功
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Success);
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Success, "分账成功");
// 9. 记录处理成功日志
log.info("[拉卡拉分账通知] 分账通知处理成功, separateNo={}, status={}", separateNo, status);

View File

@ -100,7 +100,8 @@ public interface ShopOrderLklService extends IBaseService<ShopOrderLkl> {
*
* @param lklReceiveLogNo 拉卡拉确认收货对账单流水号
* @param separateStatus 分账状态1-已分账2-未分账3-分账已失败
* @param separateRemark 分账问题备注
* @return
*/
Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus);
Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateRemark);
}

View File

@ -509,10 +509,11 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
*
* @param lklReceiveLogNo 拉卡拉确认收货对账单流水号
* @param separateStatus 分账状态1-已分账2-未分账3-分账已失败
* @param separateRemark 分账问题备注
* @return 更新结果 true-成功 false-失败
*/
@Override
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus) {
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateRemark) {
// 检查参数是否全部为空
if (StringUtils.isBlank(lklReceiveLogNo) || separateStatus == null) {
log.warn("[更新分账状态] 参数校验失败:缺少必要参数, lklReceiveLogNo={}, separateStatus={}", lklReceiveLogNo, separateStatus);

View File

@ -161,6 +161,10 @@ lakala:
#机构代码
org_code: 1951582
is_prod: false
# 是否收内部邮费
has_shopping_fee_inner: true
# 内部邮费,单位(分)
shopping_fee_inner: 500
# 拉卡拉拓客进件配置
tk:
#服务地址

View File

@ -161,6 +161,10 @@ lakala:
#机构代码
org_code: 1951582
is_prod: false
# 是否收内部邮费
has_shopping_fee_inner: true
# 内部邮费,单位(分)
shopping_fee_inner: 500
# 拉卡拉拓客进件配置
tk:
#服务地址

View File

@ -177,6 +177,10 @@ lakala:
#机构代码
org_code: 980688
is_prod: true
# 是否收内部邮费
has_shopping_fee_inner: false
# 内部邮费,单位(分)
shopping_fee_inner: 500
tk:
#服务地址
server_url: https://tkapi.lakala.com

View File

@ -165,6 +165,10 @@ lakala:
#机构代码
org_code: 1951582
is_prod: false
# 是否收内部邮费
has_shopping_fee_inner: true
# 内部邮费,单位(分)
shopping_fee_inner: 500
# 拉卡拉拓客进件配置
tk:
#服务地址

View File

@ -165,6 +165,10 @@ lakala:
#机构代码
org_code: 1951582
is_prod: false
# 是否收内部邮费
has_shopping_fee_inner: true
# 内部邮费,单位(分)
shopping_fee_inner: 500
# 拉卡拉拓客进件配置
tk:
#服务地址