@ -57,6 +57,7 @@ import java.math.BigDecimal;
import java.time.LocalDate ;
import java.time.LocalDateTime ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.List ;
@ -1646,17 +1647,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
/ / 6 . 获取订单分账相关参数
String merchantNo = shopOrderLkl . getLkl_merchant_no ( ) ;
/ / 分账金额 = 应付总金额 - 运费 ( 支付时已计算好 )
Integer splitAmount = shopOrderLkl . getSplit_amt ( ) ;
splitAmount = CheckUtil . isEmpty ( splitAmount ) ? 0 : splitAmount ;
Integer shoppingFee = shopOrderLkl . getShopping_fee ( ) ;
shoppingFee = CheckUtil . isEmpty ( shoppingFee ) ? 0 : shoppingFee ;
/ / 商家分账比例
BigDecimal splitRatioMch = shopOrderLkl . getSplit_ratio ( ) ;
/ / 7 . 分账金额校验
if ( splitAmount < = 0 ) {
String errorMsg = String . format ( " 店铺[%s]订单[%s]分账金额[%d] 异常 ,跳过分账" ,
String errorMsg = String . format ( " 店铺[%s]订单[%s]分账金额[%d]低于1分钱, 跳过分账 " ,
shopOrderLkl . getStore_id ( ) , orderId , splitAmount ) ;
log . error ( errorMsg ) ;
errorMessages . append ( errorMsg ) . append ( " ; " ) ;
@ -1666,9 +1664,8 @@ public class LakalaApiServiceImpl implements LakalaApiService {
continue ;
}
/ / 8. 获取分账接收方信息
/ / 获取分账平台 接收方信息
LklLedgerMerReceiverBind platform = lklLedgerMerReceiverBindService . getPlatformByMerCupNo ( merchantNo ) ;
List < LklLedgerMerReceiverBind > distributors = lklLedgerMerReceiverBindService . selectDistributorByMerCupNo ( merchantNo ) ;
if ( platform = = null ) {
String errorMsg = String . format ( " 店铺[%s]未绑定平台方接收账户,跳过分账 " , shopOrderLkl . getStore_id ( ) ) ;
@ -1677,17 +1674,140 @@ public class LakalaApiServiceImpl implements LakalaApiService {
continue ;
}
/ / 9 . 判断是否可以分账 ( 商家比例不超过100 % )
boolean canSplit = splitRatioMch ! = null & & splitRatioMch . compareTo ( new BigDecimal ( 100 ) ) < = 0 ;
if ( ! canSplit ) {
String errorMsg = String . format ( " 店铺[%s]分账比例[%s]异常,无法分账 " ,
/ / 8 . 构建分账接收方列表
List < V3SacsSeparateRecvDatas > recvDatas = new ArrayList < > ( ) ;
/ / 9 . 获取商家分账比例并校验
BigDecimal splitRatioMch = shopOrderLkl . getSplit_ratio ( ) ;
/ / 判断商家分账比例是否有效 ( 必须在 ( 0 , 100 ] 范围内 )
boolean canSplitForMch = splitRatioMch ! = null
& & splitRatioMch . compareTo ( BigDecimal . ZERO ) > 0
& & splitRatioMch . compareTo ( new BigDecimal ( 100 ) ) < = 0 ;
if ( ! canSplitForMch ) {
String errorMsg = String . format ( " 店铺[%s]商家分账比例[%s]不在(0-100]范围内,无法分账 " ,
shopOrderLkl . getStore_id ( ) , splitRatioMch ) ;
log . error ( errorMsg ) ;
errorMessages . append ( errorMsg ) . append ( " ; " ) ;
continue ;
} else {
log . info ( " 店铺[%s]商家分账比例[%s]在(0-100]范围内,可以分账 " ,
shopOrderLkl . getStore_id ( ) , splitRatioMch ) ;
/ / 商家分账
BigDecimal mchRatio = splitRatioMch . divide ( new BigDecimal ( 100 ) ) ; / / 比如 : 94 / 100
Integer mchSplitCent = new BigDecimal ( splitAmount ) . multiply ( mchRatio ) . intValue ( ) ;
if ( mchSplitCent > 0 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvMerchantNo ( merchantNo ) ;
receiver . setSeparateValue ( mchSplitCent . toString ( ) ) ;
recvDatas . add ( receiver ) ;
log . debug ( " 商家分账:金额={}分,商户号={} " , mchSplitCent , merchantNo ) ;
}
}
/ / 10 . 构建分账请求对象
/ / 10 . 计算平台和代理商分账金额
Integer pdSplitAmount = 0 ;
/ / 计算平台 + 代理商的总比例 = 100 - 商家分账比例
BigDecimal splitRatioNoMch = new BigDecimal ( 100 ) . subtract ( splitRatioMch ) ;
/ / 判断平台和代理商分账比例是否有效 ( 必须在 [ 0 , 100 ) 范围内 )
boolean canSplitForNoMch = splitRatioNoMch ! = null
& & splitRatioNoMch . compareTo ( BigDecimal . ZERO ) > 0
& & splitRatioNoMch . compareTo ( new BigDecimal ( 100 ) ) < 0 ;
if ( ! canSplitForNoMch ) {
String errorMsg = String . format ( " 店铺[%s]平台和代理商分账比例[%s]不在[0-100)范围内,无法分账 " ,
shopOrderLkl . getStore_id ( ) , splitRatioNoMch ) ;
log . warn ( errorMsg ) ;
} else {
log . info ( " 店铺[%s]平台和代理商分账比例[%s]在[0-100)范围内,可以分账 " ,
shopOrderLkl . getStore_id ( ) , splitRatioNoMch ) ;
/ / 分账代理商接收方信息
List < LklLedgerMerReceiverBind > distributors = Collections . emptyList ( ) ;
/ / 判断要不要分账给平台和代理商 ( 分账金额太低或者没有平台 、 代理商 , 就不用分账 )
/ / 计算平台和代理商分账金额 , 小于1分钱 , 不进行平台和代理商分账
BigDecimal notMchRatio = splitRatioNoMch . divide ( new BigDecimal ( 100 ) ) ; / / 比如 : 6 / 100
/ / 平台方和代理商总计分账金额
pdSplitAmount = notMchRatio . multiply ( new BigDecimal ( splitAmount ) ) . intValue ( ) ;
if ( pdSplitAmount > 1 ) {
/ / 11 . 判断是否能分账给代理商
/ / 如果有平台和代理商同时存在 , 平台分账剩余资金20 % ; 代理商分账剩余资金80 % ;
/ / 能分账给代理商的条件 : 总分账金额 * 0 . 2要大于1分钱
boolean canSplitForDistributors = pdSplitAmount * 0 . 2 > 1 ;
/ / 12 . 根据是否能分账给代理商决定分账模式
if ( canSplitForDistributors ) {
/ / 获取分账代理商接收方信息
distributors = lklLedgerMerReceiverBindService . selectDistributorByMerCupNo ( merchantNo ) ;
/ / 根据是否有代理商决定分账模式
if ( ! CollectionUtils . isEmpty ( distributors ) ) {
/ / 平台 + 代理商分账模式
log . debug ( " 订单[{}]采用平台+代理商分账模式 " , orderId ) ;
/ / 平台收取剩余资金20 % 手续费
Integer platformValue = pdSplitAmount * 20 / 100 ;
if ( platformValue > = 1 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( platform . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( platformValue . toString ( ) ) ;
recvDatas . add ( receiver ) ;
log . debug ( " 平台分账:金额={}分,接收方={} " , platformValue , platform . getReceiver_no ( ) ) ;
}
/ / 代理商分账 ( 扣除平台20 % 后的剩余比例 )
Integer distributorValue = pdSplitAmount - platformValue ;
if ( distributorValue > = 1 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( distributors . get ( 0 ) . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( distributorValue . toString ( ) ) ;
recvDatas . add ( receiver ) ;
log . debug ( " 代理商分账:金额={}分,接收方={} " , distributorValue , distributors . get ( 0 ) . getReceiver_no ( ) ) ;
}
}
} else {
/ / 仅平台分账模式
log . debug ( " 订单[{}]采用仅平台分账模式 " , orderId ) ;
if ( pdSplitAmount > 1 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( platform . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( pdSplitAmount . toString ( ) ) ;
recvDatas . add ( receiver ) ;
log . debug ( " 平台分账:金额={}分,接收方={} " , pdSplitAmount , platform . getReceiver_no ( ) ) ;
}
}
/ / 13 . 记录详细的分账信息 , 便于部署后排查问题
if ( log . isDebugEnabled ( ) ) {
StringBuilder detailLog = new StringBuilder ( ) ;
detailLog . append ( " 详细分账信息: " ) ;
detailLog . append ( " 订单ID= " ) . append ( shopOrderLkl . getOrder_id ( ) ) . append ( " , " ) ;
detailLog . append ( " 商户号= " ) . append ( merchantNo ) . append ( " , " ) ;
detailLog . append ( " 分账流水号= " ) . append ( shopOrderLkl . getLkl_split_log_no ( ) ) . append ( " , " ) ;
detailLog . append ( " 外部分账单号= " ) . append ( shopOrderLkl . getOut_separate_no ( ) ) . append ( " , " ) ;
detailLog . append ( " 分账总金额= " ) . append ( splitAmount ) . append ( " 分, " ) ;
detailLog . append ( " 商家分账比例= " ) . append ( splitRatioMch ) . append ( " %, " ) ;
detailLog . append ( " 平台接收方= " ) . append ( platform . getReceiver_no ( ) ) . append ( " , " ) ;
if ( canSplitForDistributors & & ! CollectionUtils . isEmpty ( distributors ) ) {
detailLog . append ( " 代理商接收方=[ " ) ;
for ( int i = 0 ; i < distributors . size ( ) ; i + + ) {
if ( i > 0 ) detailLog . append ( " , " ) ;
detailLog . append ( distributors . get ( i ) . getReceiver_no ( ) ) ;
}
detailLog . append ( " ], " ) ;
}
detailLog . append ( " 分账接收方数量= " ) . append ( recvDatas . size ( ) ) ;
log . debug ( detailLog . toString ( ) ) ;
}
}
}
/ / 14 . 构建分账请求对象
V3SacsSeparateRequest request = new V3SacsSeparateRequest ( ) ;
request . setMerchantNo ( merchantNo ) ;
request . setLogNo ( shopOrderLkl . getLkl_split_log_no ( ) ) ; / / 合单和非合单的流水号保存在此字段
@ -1695,101 +1815,17 @@ public class LakalaApiServiceImpl implements LakalaApiService {
request . setOutSeparateNo ( shopOrderLkl . getOut_separate_no ( ) ) ;
request . setTotalAmt ( splitAmount . toString ( ) ) ;
request . setLklOrgNo ( orgCode ) ;
request . setCalType ( " 0 " ) ;
request . setCalType ( " 0 " ) ; / / 0 - 按照指定金额 , 1 - 按照指定比例 。 默认 0
request . setNotifyUrl ( projectDomain + " /api/mobile/shop/lakala/sacs/separateNotify " ) ;
/ / 11 . 构建分账接收方列表
List < V3SacsSeparateRecvDatas > recvDatas = new ArrayList < > ( ) ;
Integer totalSeparateValue = 0 ; / / 平台方和代理商总计分账金额
/ / 12 . 处理分账逻辑 ( 如果可以分账 )
if ( canSplit ) {
/ / 计算平台 + 代理商的总比例
BigDecimal splitRatioNoMch = new BigDecimal ( 100 ) . subtract ( splitRatioMch ) ;
/ / 13 . 根据是否有代理商决定分账模式
if ( ! CollectionUtils . isEmpty ( distributors ) & & splitRatioNoMch . compareTo ( BigDecimal . ONE ) > 0 ) {
/ / 平台 + 代理商分账模式
log . debug ( " 订单[{}]采用平台+代理商分账模式 " , orderId ) ;
/ / 平台收取1 % 手续费
BigDecimal platformValue = CommonUtil . DecimalRoundHalfDown (
new BigDecimal ( splitAmount ) . multiply ( new BigDecimal ( " 0.01 " ) ) ) ;
if ( platformValue . compareTo ( BigDecimal . ZERO ) > 0 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( platform . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( platformValue . toString ( ) ) ;
recvDatas . add ( receiver ) ;
totalSeparateValue + = platformValue . intValue ( ) ;
log . debug ( " 平台分账:金额={}分,接收方={} " , platformValue , platform . getReceiver_no ( ) ) ;
}
/ / 代理商分账 ( 扣除平台1 % 后的剩余比例 )
BigDecimal distributorRatio = splitRatioNoMch . subtract ( new BigDecimal ( " 1 " ) ) . divide ( new BigDecimal ( 100 ) ) ;
BigDecimal distributorValue = CommonUtil . DecimalRoundHalfDown (
new BigDecimal ( splitAmount ) . multiply ( distributorRatio ) ) ;
if ( distributorValue . compareTo ( BigDecimal . ZERO ) > 0 & & ! distributors . isEmpty ( ) ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( distributors . get ( 0 ) . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( distributorValue . toString ( ) ) ;
recvDatas . add ( receiver ) ;
totalSeparateValue + = distributorValue . intValue ( ) ;
log . debug ( " 代理商分账:金额={}分,接收方={} " , distributorValue , distributors . get ( 0 ) . getReceiver_no ( ) ) ;
}
} else {
/ / 仅平台分账模式
log . debug ( " 订单[{}]采用仅平台分账模式 " , orderId ) ;
BigDecimal platformRatio = splitRatioNoMch . divide ( new BigDecimal ( 100 ) ) ;
BigDecimal platformValue = new BigDecimal ( splitAmount ) . multiply ( platformRatio ) ;
if ( platformValue . compareTo ( BigDecimal . ZERO ) > 0 ) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas ( ) ;
receiver . setRecvNo ( platform . getReceiver_no ( ) ) ;
receiver . setSeparateValue ( platformValue . toString ( ) ) ;
recvDatas . add ( receiver ) ;
totalSeparateValue + = platformValue . intValue ( ) ;
log . debug ( " 平台分账:金额={}分,接收方={} " , platformValue , platform . getReceiver_no ( ) ) ;
}
}
}
/ / 14 . 设置分账接收方列表
/ / 15 . 设置分账接收方列表
request . setRecvDatas ( recvDatas ) ;
log . info ( " 分账请求参数: 订单={}, 商户={}, 金额={}分, 分账接收方数量={} " ,
orderId , merchantNo , splitAmount , recvDatas . size ( ) ) ;
/ / 记录详细的分账信息 , 便于部署后排查问题
if ( log . isDebugEnabled ( ) ) {
StringBuilder detailLog = new StringBuilder ( ) ;
detailLog . append ( " 详细分账信息: " ) ;
detailLog . append ( " 订单ID= " ) . append ( shopOrderLkl . getOrder_id ( ) ) . append ( " , " ) ;
detailLog . append ( " 商户号= " ) . append ( merchantNo ) . append ( " , " ) ;
detailLog . append ( " 分账流水号= " ) . append ( shopOrderLkl . getLkl_split_log_no ( ) ) . append ( " , " ) ;
detailLog . append ( " 外部分账单号= " ) . append ( shopOrderLkl . getOut_separate_no ( ) ) . append ( " , " ) ;
detailLog . append ( " 分账总金额= " ) . append ( splitAmount ) . append ( " 分, " ) ;
detailLog . append ( " 运费= " ) . append ( shoppingFee ) . append ( " 分, " ) ;
detailLog . append ( " 商家分账比例= " ) . append ( splitRatioMch ) . append ( " %, " ) ;
detailLog . append ( " 平台接收方= " ) . append ( platform . getReceiver_no ( ) ) . append ( " , " ) ;
if ( ! CollectionUtils . isEmpty ( distributors ) ) {
detailLog . append ( " 代理商接收方=[ " ) ;
for ( int i = 0 ; i < distributors . size ( ) ; i + + ) {
if ( i > 0 ) detailLog . append ( " , " ) ;
detailLog . append ( distributors . get ( i ) . getReceiver_no ( ) ) ;
}
detailLog . append ( " ], " ) ;
}
detailLog . append ( " 分账接收方数量= " ) . append ( recvDatas . size ( ) ) ;
log . debug ( detailLog . toString ( ) ) ;
}
log . debug ( " 分账请求详细参数: {} " , JSONUtil . toJsonStr ( request ) ) ;
/ / 1 5 . 发送分账请求
/ / 16 . 发送分账请求
log . info ( " 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={} " ,
orderId , merchantNo , shopOrderLkl . getLkl_split_log_no ( ) ) ;
String response = LKLSDK . httpPost ( request ) ;
@ -1803,7 +1839,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
log . debug ( " 分账响应结果: {} " , response ) ;
/ / 1 6 . 解析响应结果
/ / 1 7 . 解析响应结果
JSONObject respJson = JSONUtil . parseObj ( response ) ;
if ( respJson = = null | | ! lklSacsSuccessCode . equals ( respJson . getStr ( " code " ) ) | | respJson . getJSONObject ( " resp_data " ) = = null ) {
String errorMsg = String . format ( " 拉卡拉返回格式异常,订单=%s, 商户=%s, 分账流水号=%s, 响应=%s, respJson=%s " ,
@ -1813,7 +1849,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
continue ;
}
/ / 1 7 . 保存分账记录
/ / 1 8 . 保存分账记录
JSONObject respData = respJson . getJSONObject ( " resp_data " ) ;
LklOrderSeparate lklOrderSeparate = new LklOrderSeparate ( ) ;
lklOrderSeparate . setSeparate_no ( respData . getStr ( " separate_no " ) ) ;
@ -1827,7 +1863,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
lklOrderSeparate . setLkl_org_no ( request . getLklOrgNo ( ) ) ;
lklOrderSeparate . setRecv_datas ( JSONUtil . toJsonStr ( request . getRecvDatas ( ) ) ) ;
lklOrderSeparate . setStatus ( respData . getStr ( " status " ) ) ;
lklOrderSeparate . setTotal_separate_value ( totalSeparateValue ) ;
lklOrderSeparate . setTotal_separate_value ( pdSplitAmount ) ;
try {
if ( lklOrderSeparateService . addOrUpdateByReceiverNo ( lklOrderSeparate ) ) {
@ -1852,7 +1888,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
}
/ / 1 8 . 返回最终处理结果
/ / 1 9 . 返回最终处理结果
log . info ( " 订单[{}]分账处理完成:总订单数={},成功处理数={} " , orderId , totalCount , successCount ) ;
if ( successCount = = 0 ) {
String result = " 分账全部失败: " + errorMessages ;