Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fit-finance
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fitness-server
fit-finance
Commits
1751aced
Commit
1751aced
authored
May 07, 2024
by
程裕兵
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:pay refund and settle
parent
7e63c19d
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
658 additions
and
468 deletions
+658
-468
app/src/main/java/com/jiejing/fitness/finance/app/controller/merchant/StudioMerchantController.java
+5
-1
app/src/main/java/com/jiejing/fitness/finance/app/controller/task/FitFinanceTaskController.java
+8
-4
service/src/main/java/com/jiejing/fitness/finance/service/event/ListenerService.java
+4
-1
service/src/main/java/com/jiejing/fitness/finance/service/pay/PayService.java
+1
-36
service/src/main/java/com/jiejing/fitness/finance/service/pay/RefundService.java
+28
-0
service/src/main/java/com/jiejing/fitness/finance/service/pay/SettleService.java
+27
-0
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/PayConvert.java
+53
-116
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/RefundConvert.java
+71
-0
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/SettleConvert.java
+101
-0
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/PayServiceImpl.java
+5
-309
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/RefundServiceImpl.java
+72
-0
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/SettleServiceImpl.java
+280
-0
service/src/main/java/com/jiejing/fitness/finance/service/rpc/PayRpcService.java
+3
-1
No files found.
app/src/main/java/com/jiejing/fitness/finance/app/controller/merchant/StudioMerchantController.java
View file @
1751aced
...
@@ -26,6 +26,7 @@ import com.jiejing.fitness.finance.service.merchant.StudioMerchantService;
...
@@ -26,6 +26,7 @@ import com.jiejing.fitness.finance.service.merchant.StudioMerchantService;
import
com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams
;
import
com.jiejing.fitness.finance.service.merchant.params.ApplyStudioMerchantParams
;
import
com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApplyParams
;
import
com.jiejing.fitness.finance.service.merchant.params.PageStudioMerchantApplyParams
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.RefundService
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
...
@@ -51,6 +52,9 @@ public class StudioMerchantController implements StudioMerchantApi {
...
@@ -51,6 +52,9 @@ public class StudioMerchantController implements StudioMerchantApi {
@Resource
@Resource
private
PayService
payService
;
private
PayService
payService
;
@Resource
private
RefundService
refundService
;
@ApiOperation
(
value
=
"场馆入驻商户"
,
tags
=
{
TAG
})
@ApiOperation
(
value
=
"场馆入驻商户"
,
tags
=
{
TAG
})
@PostMapping
(
value
=
"/private/studioMerchant/getMerchant"
)
@PostMapping
(
value
=
"/private/studioMerchant/getMerchant"
)
@Override
@Override
...
@@ -179,7 +183,7 @@ public class StudioMerchantController implements StudioMerchantApi {
...
@@ -179,7 +183,7 @@ public class StudioMerchantController implements StudioMerchantApi {
@Override
@Override
public
JsonResult
<
RefundVO
>
refund
(
@RequestBody
@Valid
StudioMerchantRefundRequest
request
)
{
public
JsonResult
<
RefundVO
>
refund
(
@RequestBody
@Valid
StudioMerchantRefundRequest
request
)
{
StudioMerchantRefundParams
params
=
BeanUtil
.
map
(
request
,
StudioMerchantRefundParams
.
class
);
StudioMerchantRefundParams
params
=
BeanUtil
.
map
(
request
,
StudioMerchantRefundParams
.
class
);
return
JsonResult
.
success
(
pay
Service
.
merchantRefund
(
params
));
return
JsonResult
.
success
(
refund
Service
.
merchantRefund
(
params
));
}
}
}
}
app/src/main/java/com/jiejing/fitness/finance/app/controller/task/FitFinanceTaskController.java
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
app
.
controller
.
task
;
package
com
.
jiejing
.
fitness
.
finance
.
app
.
controller
.
task
;
import
com.jiejing.common.model.JsonResult
;
import
com.jiejing.common.model.JsonResult
;
import
com.jiejing.common.utils.time.TimeUtil
;
import
com.jiejing.fitness.finance.api.task.FitFinanceTaskApi
;
import
com.jiejing.fitness.finance.api.task.FitFinanceTaskApi
;
import
com.jiejing.fitness.finance.api.task.request.CheckSettleRequest
;
import
com.jiejing.fitness.finance.api.task.request.CheckSettleRequest
;
import
com.jiejing.fitness.finance.service.pay.
Pay
Service
;
import
com.jiejing.fitness.finance.service.pay.
Settle
Service
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
java.util.Date
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
javax.validation.Valid
;
import
javax.validation.Valid
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
...
@@ -18,14 +20,16 @@ import org.springframework.web.bind.annotation.RestController;
...
@@ -18,14 +20,16 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RestController
public
class
FitFinanceTaskController
implements
FitFinanceTaskApi
{
public
class
FitFinanceTaskController
implements
FitFinanceTaskApi
{
@Resource
@Resource
private
PayService
payService
;
private
SettleService
settleService
;
@ApiOperation
(
value
=
"对账"
,
tags
=
{
TAG
})
@ApiOperation
(
value
=
"对账"
,
tags
=
{
TAG
})
@PostMapping
(
value
=
"/private/task/checkSettle"
)
@PostMapping
(
value
=
"/private/task/checkSettle"
)
@Override
@Override
public
JsonResult
<
Void
>
checkSettle
(
@Valid
@RequestBody
CheckSettleRequest
request
)
{
public
JsonResult
<
Void
>
checkSettle
(
@Valid
@RequestBody
CheckSettleRequest
request
)
{
pay
Service
.
checkSettle
(
request
.
getMerchantId
(),
request
.
getSettleDate
());
settle
Service
.
checkSettle
(
request
.
getMerchantId
(),
request
.
getSettleDate
());
return
JsonResult
.
success
();
return
JsonResult
.
success
();
}
}
...
@@ -33,7 +37,7 @@ public class FitFinanceTaskController implements FitFinanceTaskApi {
...
@@ -33,7 +37,7 @@ public class FitFinanceTaskController implements FitFinanceTaskApi {
@PostMapping
(
value
=
"/private/task/syncSettle"
)
@PostMapping
(
value
=
"/private/task/syncSettle"
)
@Override
@Override
public
JsonResult
<
Void
>
syncSettle
(
@Valid
@RequestBody
CheckSettleRequest
request
)
{
public
JsonResult
<
Void
>
syncSettle
(
@Valid
@RequestBody
CheckSettleRequest
request
)
{
pay
Service
.
syncSettle
(
request
.
getMerchantId
(),
request
.
getSettleDate
());
settle
Service
.
syncSettle
(
request
.
getMerchantId
(),
request
.
getSettleDate
());
return
JsonResult
.
success
();
return
JsonResult
.
success
();
}
}
...
...
service/src/main/java/com/jiejing/fitness/finance/service/event/ListenerService.java
View file @
1751aced
...
@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
...
@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
import
com.jiejing.fitness.enums.finance.PartyTypeEnum
;
import
com.jiejing.fitness.enums.finance.PartyTypeEnum
;
import
com.jiejing.fitness.finance.service.merchant.StudioMerchantService
;
import
com.jiejing.fitness.finance.service.merchant.StudioMerchantService
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.RefundService
;
import
com.jiejing.paycenter.common.event.MerchantEvent
;
import
com.jiejing.paycenter.common.event.MerchantEvent
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
...
@@ -33,6 +34,8 @@ public class ListenerService {
...
@@ -33,6 +34,8 @@ public class ListenerService {
@Resource
@Resource
private
PayService
payService
;
private
PayService
payService
;
@Resource
private
RefundService
refundService
;
@EventHandler
(
value
=
MerchantEvent
.
class
,
binder
=
"biz-kafka"
,
maxAttempts
=
MAX_RETRY
)
@EventHandler
(
value
=
MerchantEvent
.
class
,
binder
=
"biz-kafka"
,
maxAttempts
=
MAX_RETRY
)
public
void
handleMerchantEvent
(
MerchantEvent
event
,
@Header
(
DELIVERY_ATTEMPT
)
int
retryNum
)
{
public
void
handleMerchantEvent
(
MerchantEvent
event
,
@Header
(
DELIVERY_ATTEMPT
)
int
retryNum
)
{
...
@@ -69,7 +72,7 @@ public class ListenerService {
...
@@ -69,7 +72,7 @@ public class ListenerService {
public
void
refundEventCallback
(
RefundEvent
event
,
@Header
(
DELIVERY_ATTEMPT
)
int
retryNum
)
{
public
void
refundEventCallback
(
RefundEvent
event
,
@Header
(
DELIVERY_ATTEMPT
)
int
retryNum
)
{
try
{
try
{
log
.
info
(
"start process refund event {}"
,
JSON
.
toJSONString
(
event
));
log
.
info
(
"start process refund event {}"
,
JSON
.
toJSONString
(
event
));
pay
Service
.
refundCallback
(
event
);
refund
Service
.
refundCallback
(
event
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
info
(
"process refund event fail {}"
,
event
.
getTransNo
(),
e
);
log
.
info
(
"process refund event fail {}"
,
event
.
getTransNo
(),
e
);
}
}
...
...
service/src/main/java/com/jiejing/fitness/finance/service/pay/PayService.java
View file @
1751aced
...
@@ -3,13 +3,9 @@ package com.jiejing.fitness.finance.service.pay;
...
@@ -3,13 +3,9 @@ package com.jiejing.fitness.finance.service.pay;
import
com.jiejing.fitness.finance.service.pay.params.AppPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.AppPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.NativePayParams
;
import
com.jiejing.fitness.finance.service.pay.params.NativePayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.paycenter.common.enums.common.PayChannelEnums
;
import
com.jiejing.paycenter.common.enums.common.PayChannelEnums
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
import
java.util.Date
;
/**
/**
* @author chengyubing
* @author chengyubing
...
@@ -44,7 +40,7 @@ public interface PayService {
...
@@ -44,7 +40,7 @@ public interface PayService {
PayVO
appPay
(
AppPayParams
params
);
PayVO
appPay
(
AppPayParams
params
);
/**
/**
* 支付
*
商户版
支付
*
*
* @param params 请求参数
* @param params 请求参数
* @return 结果
* @return 结果
...
@@ -58,35 +54,4 @@ public interface PayService {
...
@@ -58,35 +54,4 @@ public interface PayService {
*/
*/
void
payCallback
(
PayEvent
event
);
void
payCallback
(
PayEvent
event
);
/**
* 商户退款
*
* @param params 参数
* @return 结果
*/
RefundVO
merchantRefund
(
StudioMerchantRefundParams
params
);
/**
* 退款回调
*
* @param event 事件
*/
void
refundCallback
(
RefundEvent
event
);
/**
* 对账
*
* @param merchantId 商户ID
* @param settleDate 结算日
*/
void
checkSettle
(
Long
merchantId
,
Date
settleDate
);
/**
* 同步结算状态
*
* @param merchantId 商户ID
* @param settleDate 结算日
*/
void
syncSettle
(
Long
merchantId
,
Date
settleDate
);
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/RefundService.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
/**
* @author chengyubing
* @since 2024/5/7 16:37
*/
public
interface
RefundService
{
/**
* 商户退款
*
* @param params 参数
* @return 结果
*/
RefundVO
merchantRefund
(
StudioMerchantRefundParams
params
);
/**
* 退款回调
*
* @param event 事件
*/
void
refundCallback
(
RefundEvent
event
);
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/SettleService.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
;
import
java.util.Date
;
/**
* @author chengyubing
* @since 2024/5/7 16:32
*/
public
interface
SettleService
{
/**
* 对账
*
* @param merchantId 商户ID
* @param settleDate 结算日
*/
void
checkSettle
(
Long
merchantId
,
Date
settleDate
);
/**
* 同步结算状态
*
* @param merchantId 商户ID
* @param settleDate 结算日
*/
void
syncSettle
(
Long
merchantId
,
Date
settleDate
);
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/PayConvert.java
View file @
1751aced
...
@@ -2,6 +2,7 @@ package com.jiejing.fitness.finance.service.pay.convert;
...
@@ -2,6 +2,7 @@ package com.jiejing.fitness.finance.service.pay.convert;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alipay.api.request.AlipaySystemOauthTokenRequest
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.jiejing.common.exception.BizException
;
import
com.jiejing.common.exception.BizException
;
...
@@ -15,11 +16,16 @@ import com.jiejing.fitness.finance.repository.entity.StudioCashierRecord;
...
@@ -15,11 +16,16 @@ import com.jiejing.fitness.finance.repository.entity.StudioCashierRecord;
import
com.jiejing.fitness.finance.repository.entity.StudioCheckSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioCheckSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioMerchantApply
;
import
com.jiejing.fitness.finance.repository.entity.StudioMerchantApply
;
import
com.jiejing.fitness.finance.repository.entity.StudioSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioSettleRecord
;
import
com.jiejing.fitness.finance.service.config.PayChannelProperties
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
import
com.jiejing.fitness.finance.service.pay.enums.PayFailMessageReplaceEnums
;
import
com.jiejing.fitness.finance.service.pay.params.AppPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.NativePayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.utils.FeeUtil
;
import
com.jiejing.fitness.finance.service.utils.FeeUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.paycenter.common.enums.common.PayChannelEnums
;
import
com.jiejing.paycenter.common.model.vo.MerchantVO
;
import
com.jiejing.paycenter.common.model.vo.MerchantVO
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
...
@@ -184,45 +190,7 @@ public class PayConvert {
...
@@ -184,45 +190,7 @@ public class PayConvert {
return
convertTransState
(
PayStateEnums
.
getByCode
(
state
));
return
convertTransState
(
PayStateEnums
.
getByCode
(
state
));
}
}
public
static
StudioCashierRecord
convertRefundInit
(
StudioMerchantRefundParams
params
,
public
static
BrandCashierTransStateEnum
convertTransState
(
TransStateEnums
state
)
{
StudioCashierRecord
pay
,
BigDecimal
historyRefundActualAmount
)
{
StudioCashierRecord
record
=
BeanUtil
.
map
(
pay
,
StudioCashierRecord
.
class
);
record
.
setId
(
IdWorker
.
getId
());
record
.
setTransNo
(
record
.
getId
().
toString
());
record
.
setOrderNo
(
params
.
getOrderNo
());
record
.
setRelatedTransNo
(
params
.
getPayTransNo
());
record
.
setTransAmount
(
params
.
getTransAmount
());
record
.
setFeeRate
(
pay
.
getFeeRate
());
record
.
setFee
(
FeeUtil
.
calculateRefundFee
(
params
.
getTransAmount
(),
pay
.
getTransAmount
(),
pay
.
getActualAmount
(),
pay
.
getFee
(),
historyRefundActualAmount
));
record
.
setActualAmount
(
MoneyUtil
.
subtract
(
record
.
getTransAmount
(),
record
.
getFee
()));
record
.
setRemark
(
params
.
getRefundReason
());
record
.
setStudioId
(
params
.
getStudioId
());
record
.
setTransState
(
BrandCashierTransStateEnum
.
REFUND_INIT
.
getCode
());
record
.
setTradingTime
(
new
Date
());
record
.
setCreateTime
(
new
Date
());
record
.
setUpdateTime
(
new
Date
());
return
record
;
}
public
static
RefundPayRequest
convert
(
StudioMerchantRefundParams
params
,
StudioCashierRecord
record
)
{
RefundPayRequest
request
=
BeanUtil
.
map
(
params
,
RefundPayRequest
.
class
);
request
.
setTransNo
(
record
.
getTransNo
());
return
request
;
}
public
static
StudioCashierRecord
convertRefund
(
StudioCashierRecord
record
,
RefundVO
vo
)
{
return
StudioCashierRecord
.
builder
()
.
id
(
record
.
getId
())
.
transState
(
convertTransState
(
TransStateEnums
.
getByCode
(
vo
.
getRefundState
())).
getCode
())
.
failMessage
(
vo
.
getFailMessage
())
.
successTime
(
vo
.
getSuccessTime
())
.
updateTime
(
new
Date
())
.
build
();
}
private
static
BrandCashierTransStateEnum
convertTransState
(
TransStateEnums
state
)
{
switch
(
state
)
{
switch
(
state
)
{
case
SUCCESS:
case
SUCCESS:
return
BrandCashierTransStateEnum
.
REFUND_SUCCESS
;
return
BrandCashierTransStateEnum
.
REFUND_SUCCESS
;
...
@@ -235,55 +203,6 @@ public class PayConvert {
...
@@ -235,55 +203,6 @@ public class PayConvert {
}
}
}
}
public
static
StudioCashierRecord
convertRefund
(
StudioCashierRecord
record
,
RefundEvent
event
)
{
return
StudioCashierRecord
.
builder
()
.
id
(
record
.
getId
())
.
transState
(
convertTransState
(
TransStateEnums
.
getByCode
(
event
.
getRefundState
())).
getCode
())
.
failMessage
(
event
.
getFailMessage
())
.
successTime
(
event
.
getSuccessTime
())
.
updateTime
(
new
Date
())
.
build
();
}
public
static
List
<
StudioSettleRecord
>
convertStudioSettle
(
MerchantSettleRecord
record
,
Map
<
Long
,
BigDecimal
>
studioPayAmountMap
,
Map
<
Long
,
BigDecimal
>
studioRefundAmountMap
,
Map
<
Long
,
StudioVO
>
studioMap
)
{
// A场馆支付了100,B场馆支付了0,B场馆发起退款-》成功。结算记录-》
// A场馆支付了0,B场馆支付了0,B场馆发起退款-》失败
// A场馆支付了100,B场馆支付了0,B场馆发起退款-》成功,A场馆发起退款100-》失败
return
studioPayAmountMap
.
keySet
().
stream
().
map
(
studioId
->
StudioSettleRecord
.
builder
()
.
id
(
IdWorker
.
getId
())
.
parentId
(
record
.
getId
())
.
studioId
(
studioId
)
.
studioName
(
Optional
.
ofNullable
(
studioMap
.
get
(
studioId
)).
map
(
StudioVO:
:
getName
).
orElse
(
"-"
))
.
merchantId
(
record
.
getMerchantId
())
.
merchantNo
(
record
.
getMerchantNo
())
.
transState
(
record
.
getTransState
())
.
transAmount
(
MoneyUtil
.
subtract
(
studioPayAmountMap
.
getOrDefault
(
studioId
,
BigDecimal
.
ZERO
),
studioRefundAmountMap
.
getOrDefault
(
studioId
,
BigDecimal
.
ZERO
)))
.
settleDate
(
record
.
getSettleDate
())
.
cardNo
(
record
.
getCardNo
())
.
bankName
(
record
.
getBankName
())
.
failMsg
(
record
.
getFailMsg
())
.
salt
(
record
.
getSalt
())
.
createTime
(
record
.
getCreateTime
())
.
updateTime
(
record
.
getUpdateTime
())
.
build
()).
collect
(
Collectors
.
toList
());
}
public
static
StudioCheckSettleRecord
convertCheckSettle
(
StudioMerchantApply
apply
,
SettleVO
vo
,
BigDecimal
totalAmount
)
{
return
StudioCheckSettleRecord
.
builder
()
.
id
(
IdWorker
.
getId
())
.
merchantId
(
apply
.
getMerchantId
())
.
merchantNo
(
apply
.
getMerchantNo
())
.
checkState
(
TransStateEnums
.
FAIL
.
getCode
())
.
failMsg
(
"对账失败,乐动收银入账中金额【"
+
totalAmount
+
"】,汇付结算金额【"
+
vo
.
getTransAmount
()
+
"】"
)
.
settleDate
(
vo
.
getTransDate
())
.
createTime
(
new
Date
())
.
updateTime
(
new
Date
())
.
build
();
}
public
static
PayEvent
convertEvent
(
PayRequest
request
,
PayVO
vo
)
{
public
static
PayEvent
convertEvent
(
PayRequest
request
,
PayVO
vo
)
{
return
PayEvent
.
builder
()
return
PayEvent
.
builder
()
...
@@ -300,38 +219,56 @@ public class PayConvert {
...
@@ -300,38 +219,56 @@ public class PayConvert {
.
build
();
.
build
();
}
}
public
static
MerchantSettleRecord
convertMerchantSettle
(
StudioMerchantApply
apply
,
SettleVO
vo
)
{
public
static
PayRequest
convertNativePay
(
NativePayParams
params
,
PayChannelProperties
config
)
{
String
salt
=
AesUtil
.
getSalt
(
8
);
PayRequest
req
=
new
PayRequest
();
Date
now
=
new
Date
();
req
.
setChannelNo
(
getChannelNo
(
params
.
getChannel
(),
config
));
return
MerchantSettleRecord
.
builder
()
req
.
setTransNo
(
IdWorker
.
getIdStr
());
.
id
(
IdWorker
.
getId
())
req
.
setAmount
(
params
.
getAmount
());
.
merchantId
(
apply
.
getMerchantId
())
req
.
setPayType
(
PayTypeEnums
.
NATIVE
);
.
merchantNo
(
apply
.
getMerchantNo
())
req
.
setGoods
(
params
.
getGoods
());
.
transState
(
vo
.
getTransState
())
req
.
setOrderNo
(
params
.
getOrderNo
());
.
transAmount
(
vo
.
getTransAmount
())
req
.
setOrderType
(
params
.
getOrderType
().
getCode
());
.
settleDate
(
vo
.
getTransDate
())
req
.
setTimeExpire
(
params
.
getTimeExpire
());
.
cardNo
(
AesUtil
.
encrypt
(
salt
,
vo
.
getCardNo
()))
req
.
setTradingTime
(
new
Date
());
.
bankName
(
vo
.
getBankName
())
req
.
setExtra
(
params
.
getExtra
());
.
failMsg
(
vo
.
getFailMsg
())
return
req
;
.
salt
(
salt
)
.
createTime
(
now
)
.
updateTime
(
now
).
build
();
}
}
public
static
MerchantSettleRecord
convertMerchantSettle
(
MerchantSettleRecord
history
,
SettleVO
vo
)
{
public
static
PayRequest
convertAppPay
(
AppPayParams
params
,
PayChannelProperties
config
)
{
return
MerchantSettleRecord
.
builder
()
PayRequest
req
=
new
PayRequest
();
.
id
(
history
.
getId
())
req
.
setChannelNo
(
getChannelNo
(
params
.
getChannel
(),
config
));
.
transState
(
vo
.
getTransState
())
req
.
setTransNo
(
IdWorker
.
getIdStr
());
.
failMsg
(
vo
.
getFailMsg
())
req
.
setAmount
(
params
.
getAmount
());
.
updateTime
(
new
Date
()).
build
();
req
.
setPayType
(
PayTypeEnums
.
APP
);
req
.
setGoods
(
params
.
getGoods
());
req
.
setOrderNo
(
params
.
getOrderNo
());
req
.
setOrderType
(
params
.
getOrderType
().
getCode
());
req
.
setTimeExpire
(
params
.
getTimeExpire
());
req
.
setTradingTime
(
new
Date
());
req
.
setExtra
(
params
.
getExtra
());
return
req
;
}
}
public
static
StudioSettleRecord
convertStudioSettle
(
MerchantSettleRecord
history
,
SettleVO
vo
)
{
private
static
String
getChannelNo
(
PayChannelEnums
channel
,
PayChannelProperties
config
)
{
return
StudioSettleRecord
.
builder
()
switch
(
channel
)
{
.
parentId
(
history
.
getId
())
case
WX:
.
transState
(
vo
.
getTransState
())
return
config
.
getWxApp
();
.
failMsg
(
vo
.
getFailMsg
())
case
ALI:
.
updateTime
(
new
Date
()).
build
();
return
config
.
getAliApp
();
default
:
throw
new
BizException
(
FinanceErrorEnums
.
NOT_SUPPORT_TYPE
);
}
}
public
static
AlipaySystemOauthTokenRequest
convertAlipaySystemOauthTokenRequest
(
String
authCode
)
{
AlipaySystemOauthTokenRequest
aliRequest
=
new
AlipaySystemOauthTokenRequest
();
aliRequest
.
setCode
(
authCode
);
aliRequest
.
setGrantType
(
"authorization_code"
);
return
aliRequest
;
}
public
static
FinanceErrorEnums
replaceFailMessage
(
String
failMsg
)
{
return
PayFailMessageReplaceEnums
.
convertBySource
(
failMsg
);
}
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/RefundConvert.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
convert
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.jiejing.common.utils.convert.BeanUtil
;
import
com.jiejing.fitness.enums.finance.BrandCashierTransStateEnum
;
import
com.jiejing.fitness.finance.repository.entity.StudioCashierRecord
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.utils.FeeUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
import
java.math.BigDecimal
;
import
java.util.Date
;
/**
* @author chengyubing
* @since 2024/5/7 16:48
*/
public
class
RefundConvert
{
public
static
StudioCashierRecord
convertRefundInit
(
StudioMerchantRefundParams
params
,
StudioCashierRecord
pay
,
BigDecimal
historyRefundActualAmount
)
{
StudioCashierRecord
record
=
BeanUtil
.
map
(
pay
,
StudioCashierRecord
.
class
);
record
.
setId
(
IdWorker
.
getId
());
record
.
setTransNo
(
record
.
getId
().
toString
());
record
.
setOrderNo
(
params
.
getOrderNo
());
record
.
setRelatedTransNo
(
params
.
getPayTransNo
());
record
.
setTransAmount
(
params
.
getTransAmount
());
record
.
setFeeRate
(
pay
.
getFeeRate
());
record
.
setFee
(
FeeUtil
.
calculateRefundFee
(
params
.
getTransAmount
(),
pay
.
getTransAmount
(),
pay
.
getActualAmount
(),
pay
.
getFee
(),
historyRefundActualAmount
));
record
.
setActualAmount
(
MoneyUtil
.
subtract
(
record
.
getTransAmount
(),
record
.
getFee
()));
record
.
setRemark
(
params
.
getRefundReason
());
record
.
setStudioId
(
params
.
getStudioId
());
record
.
setTransState
(
BrandCashierTransStateEnum
.
REFUND_INIT
.
getCode
());
record
.
setTradingTime
(
new
Date
());
record
.
setCreateTime
(
new
Date
());
record
.
setUpdateTime
(
new
Date
());
return
record
;
}
public
static
RefundPayRequest
convert
(
StudioMerchantRefundParams
params
,
StudioCashierRecord
record
)
{
RefundPayRequest
request
=
BeanUtil
.
map
(
params
,
RefundPayRequest
.
class
);
request
.
setTransNo
(
record
.
getTransNo
());
return
request
;
}
public
static
StudioCashierRecord
convertRefund
(
StudioCashierRecord
record
,
RefundVO
vo
)
{
return
StudioCashierRecord
.
builder
()
.
id
(
record
.
getId
())
.
transState
(
PayConvert
.
convertTransState
(
TransStateEnums
.
getByCode
(
vo
.
getRefundState
())).
getCode
())
.
failMessage
(
vo
.
getFailMessage
())
.
successTime
(
vo
.
getSuccessTime
())
.
updateTime
(
new
Date
())
.
build
();
}
public
static
StudioCashierRecord
convertRefund
(
StudioCashierRecord
record
,
RefundEvent
event
)
{
return
StudioCashierRecord
.
builder
()
.
id
(
record
.
getId
())
.
transState
(
PayConvert
.
convertTransState
(
TransStateEnums
.
getByCode
(
event
.
getRefundState
())).
getCode
())
.
failMessage
(
event
.
getFailMessage
())
.
successTime
(
event
.
getSuccessTime
())
.
updateTime
(
new
Date
())
.
build
();
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/SettleConvert.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
convert
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.jiejing.common.utils.crypt.AesUtil
;
import
com.jiejing.fitness.finance.repository.entity.MerchantSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioCheckSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioMerchantApply
;
import
com.jiejing.fitness.finance.repository.entity.StudioSettleRecord
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.model.vo.SettleVO
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
java.math.BigDecimal
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.stream.Collectors
;
/**
* @author chengyubing
* @since 2024/5/7 16:48
*/
public
class
SettleConvert
{
public
static
MerchantSettleRecord
convertMerchantSettle
(
StudioMerchantApply
apply
,
SettleVO
vo
)
{
String
salt
=
AesUtil
.
getSalt
(
8
);
Date
now
=
new
Date
();
return
MerchantSettleRecord
.
builder
()
.
id
(
IdWorker
.
getId
())
.
merchantId
(
apply
.
getMerchantId
())
.
merchantNo
(
apply
.
getMerchantNo
())
.
transState
(
vo
.
getTransState
())
.
transAmount
(
vo
.
getTransAmount
())
.
settleDate
(
vo
.
getTransDate
())
.
cardNo
(
AesUtil
.
encrypt
(
salt
,
vo
.
getCardNo
()))
.
bankName
(
vo
.
getBankName
())
.
failMsg
(
vo
.
getFailMsg
())
.
salt
(
salt
)
.
createTime
(
now
)
.
updateTime
(
now
).
build
();
}
public
static
MerchantSettleRecord
convertMerchantSettle
(
MerchantSettleRecord
history
,
SettleVO
vo
)
{
return
MerchantSettleRecord
.
builder
()
.
id
(
history
.
getId
())
.
transState
(
vo
.
getTransState
())
.
failMsg
(
vo
.
getFailMsg
())
.
updateTime
(
new
Date
()).
build
();
}
public
static
StudioSettleRecord
convertStudioSettle
(
MerchantSettleRecord
history
,
SettleVO
vo
)
{
return
StudioSettleRecord
.
builder
()
.
parentId
(
history
.
getId
())
.
transState
(
vo
.
getTransState
())
.
failMsg
(
vo
.
getFailMsg
())
.
updateTime
(
new
Date
()).
build
();
}
public
static
List
<
StudioSettleRecord
>
convertStudioSettle
(
MerchantSettleRecord
record
,
Map
<
Long
,
BigDecimal
>
studioPayAmountMap
,
Map
<
Long
,
BigDecimal
>
studioRefundAmountMap
,
Map
<
Long
,
StudioVO
>
studioMap
)
{
// A场馆支付了100,B场馆支付了0,B场馆发起退款-》成功。结算记录-》
// A场馆支付了0,B场馆支付了0,B场馆发起退款-》失败
// A场馆支付了100,B场馆支付了0,B场馆发起退款-》成功,A场馆发起退款100-》失败
return
studioPayAmountMap
.
keySet
().
stream
().
map
(
studioId
->
StudioSettleRecord
.
builder
()
.
id
(
IdWorker
.
getId
())
.
parentId
(
record
.
getId
())
.
studioId
(
studioId
)
.
studioName
(
Optional
.
ofNullable
(
studioMap
.
get
(
studioId
)).
map
(
StudioVO:
:
getName
).
orElse
(
"-"
))
.
merchantId
(
record
.
getMerchantId
())
.
merchantNo
(
record
.
getMerchantNo
())
.
transState
(
record
.
getTransState
())
.
transAmount
(
MoneyUtil
.
subtract
(
studioPayAmountMap
.
getOrDefault
(
studioId
,
BigDecimal
.
ZERO
),
studioRefundAmountMap
.
getOrDefault
(
studioId
,
BigDecimal
.
ZERO
)))
.
settleDate
(
record
.
getSettleDate
())
.
cardNo
(
record
.
getCardNo
())
.
bankName
(
record
.
getBankName
())
.
failMsg
(
record
.
getFailMsg
())
.
salt
(
record
.
getSalt
())
.
createTime
(
record
.
getCreateTime
())
.
updateTime
(
record
.
getUpdateTime
())
.
build
()).
collect
(
Collectors
.
toList
());
}
public
static
StudioCheckSettleRecord
convertCheckSettle
(
StudioMerchantApply
apply
,
SettleVO
vo
,
BigDecimal
totalAmount
)
{
return
StudioCheckSettleRecord
.
builder
()
.
id
(
IdWorker
.
getId
())
.
merchantId
(
apply
.
getMerchantId
())
.
merchantNo
(
apply
.
getMerchantNo
())
.
checkState
(
TransStateEnums
.
FAIL
.
getCode
())
.
failMsg
(
"对账失败,乐动收银入账中金额【"
+
totalAmount
+
"】,汇付结算金额【"
+
vo
.
getTransAmount
()
+
"】"
)
.
settleDate
(
vo
.
getTransDate
())
.
createTime
(
new
Date
())
.
updateTime
(
new
Date
())
.
build
();
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/PayServiceImpl.java
View file @
1751aced
...
@@ -5,83 +5,60 @@ import static java.util.stream.Collectors.toList;
...
@@ -5,83 +5,60 @@ import static java.util.stream.Collectors.toList;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSON
;
import
com.alipay.api.AlipayApiException
;
import
com.alipay.api.AlipayApiException
;
import
com.alipay.api.DefaultAlipayClient
;
import
com.alipay.api.DefaultAlipayClient
;
import
com.alipay.api.request.AlipaySystemOauthTokenRequest
;
import
com.alipay.api.response.AlipaySystemOauthTokenResponse
;
import
com.alipay.api.response.AlipaySystemOauthTokenResponse
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.baomidou.mybatisplus.core.toolkit.IdWorker
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.jiejing.common.exception.BizException
;
import
com.jiejing.common.exception.BizException
;
import
com.jiejing.common.utils.collection.CollectionUtil
;
import
com.jiejing.common.utils.collection.CollectionUtil
;
import
com.jiejing.common.utils.time.TimeUtil
;
import
com.jiejing.fitness.enums.auth.AuthDomainEnum
;
import
com.jiejing.fitness.enums.auth.AuthDomainEnum
;
import
com.jiejing.fitness.enums.finance.BrandCashierTransStateEnum
;
import
com.jiejing.fitness.enums.finance.BrandCashierTransStateEnum
;
import
com.jiejing.fitness.enums.tenant.TenantTypeEnum
;
import
com.jiejing.fitness.enums.tenant.TenantTypeEnum
;
import
com.jiejing.fitness.finance.repository.entity.GlobalConfig
;
import
com.jiejing.fitness.finance.repository.entity.GlobalConfig
;
import
com.jiejing.fitness.finance.repository.entity.MerchantSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.PartyToMerchant
;
import
com.jiejing.fitness.finance.repository.entity.PartyToMerchant
;
import
com.jiejing.fitness.finance.repository.entity.StudioMerchantApply
;
import
com.jiejing.fitness.finance.repository.service.GlobalConfigRpService
;
import
com.jiejing.fitness.finance.repository.service.GlobalConfigRpService
;
import
com.jiejing.fitness.finance.repository.service.MerchantSettleRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.PartyToMerchantRpService
;
import
com.jiejing.fitness.finance.repository.service.PartyToMerchantRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioCheckSettleRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioMerchantApplyRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioSettleRecordRpService
;
import
com.jiejing.fitness.finance.service.config.AppUrlProperties
;
import
com.jiejing.fitness.finance.service.config.AppUrlProperties
;
import
com.jiejing.fitness.finance.service.config.PayChannelProperties
;
import
com.jiejing.fitness.finance.service.config.PayChannelProperties
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
import
com.jiejing.fitness.finance.service.enums.GlobalConfigEnums
;
import
com.jiejing.fitness.finance.service.enums.GlobalConfigEnums
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.PayService
;
import
com.jiejing.fitness.finance.service.pay.convert.PayConvert
;
import
com.jiejing.fitness.finance.service.pay.convert.PayConvert
;
import
com.jiejing.fitness.finance.service.pay.enums.PayFailMessageReplaceEnums
;
import
com.jiejing.fitness.finance.service.pay.params.AppPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.AppPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.pay.params.NativePayParams
;
import
com.jiejing.fitness.finance.service.pay.params.NativePayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantPayParams
;
import
com.jiejing.fitness.finance.service.rpc.MerchantRpcService
;
import
com.jiejing.fitness.finance.service.rpc.MerchantRpcService
;
import
com.jiejing.fitness.finance.service.rpc.PayRpcService
;
import
com.jiejing.fitness.finance.service.rpc.PayRpcService
;
import
com.jiejing.fitness.finance.service.rpc.PermissionRpcService
;
import
com.jiejing.fitness.finance.service.rpc.PermissionRpcService
;
import
com.jiejing.fitness.finance.service.rpc.StudioRpcService
;
import
com.jiejing.fitness.finance.service.rpc.StudioRpcService
;
import
com.jiejing.fitness.finance.service.utils.DingUtil
;
import
com.jiejing.fitness.finance.service.utils.FeeUtil
;
import
com.jiejing.fitness.finance.service.utils.FeeUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.message.enums.MsgChannelEnum
;
import
com.jiejing.message.enums.MsgChannelEnum
;
import
com.jiejing.message.event.SendCommonMsgEvent
;
import
com.jiejing.message.event.SendCommonMsgEvent
;
import
com.jiejing.paycenter.common.enums.common.PayChannelEnums
;
import
com.jiejing.paycenter.common.enums.common.PayChannelEnums
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.enums.pay.PayStateEnums
;
import
com.jiejing.paycenter.common.enums.pay.PayStateEnums
;
import
com.jiejing.paycenter.common.enums.pay.PayTypeEnums
;
import
com.jiejing.paycenter.common.model.vo.MerchantVO
;
import
com.jiejing.paycenter.common.model.vo.MerchantVO
;
import
com.jiejing.paycenter.api.pay.request.PayRequest
;
import
com.jiejing.paycenter.api.pay.request.PayRequest
;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.PayVO
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.model.vo.SettleVO
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
com.jiejing.wechat.WeChatAuthService
;
import
com.jiejing.wechat.WeChatAuthService
;
import
com.jiejing.wechat.vo.weChat.BaseAuthInfoVO
;
import
com.jiejing.wechat.vo.weChat.BaseAuthInfoVO
;
import
com.xiaomai.event.EventAgent
;
import
com.xiaomai.event.EventAgent
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.time.temporal.ChronoUnit
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.Optional
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.Consumer
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
lombok.Data
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.tuple.Pair
;
import
org.apache.commons.lang3.tuple.Pair
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.domain.Page
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.support.TransactionTemplate
;
import
org.springframework.transaction.support.TransactionTemplate
;
...
@@ -95,9 +72,6 @@ public class PayServiceImpl implements PayService {
...
@@ -95,9 +72,6 @@ public class PayServiceImpl implements PayService {
private
static
final
BigDecimal
MAX_AMOUNT
=
new
BigDecimal
(
"10000000"
);
private
static
final
BigDecimal
MAX_AMOUNT
=
new
BigDecimal
(
"10000000"
);
@Value
(
"${spring.profiles.active}"
)
private
String
env
;
@Resource
@Resource
private
PayChannelProperties
config
;
private
PayChannelProperties
config
;
...
@@ -120,15 +94,6 @@ public class PayServiceImpl implements PayService {
...
@@ -120,15 +94,6 @@ public class PayServiceImpl implements PayService {
private
MerchantRpcService
merchantRpcService
;
private
MerchantRpcService
merchantRpcService
;
@Resource
@Resource
private
StudioSettleRecordRpService
studioSettleRecordRpService
;
@Resource
private
StudioMerchantApplyRpService
studioMerchantApplyRpService
;
@Resource
private
StudioCheckSettleRecordRpService
studioCheckSettleRecordRpService
;
@Resource
private
WeChatAuthService
weChatAuthService
;
private
WeChatAuthService
weChatAuthService
;
@Resource
@Resource
...
@@ -140,9 +105,6 @@ public class PayServiceImpl implements PayService {
...
@@ -140,9 +105,6 @@ public class PayServiceImpl implements PayService {
@Resource
@Resource
private
PermissionRpcService
permissionRpcService
;
private
PermissionRpcService
permissionRpcService
;
@Resource
private
MerchantSettleRecordRpService
merchantSettleRecordRpService
;
@Resource
(
name
=
"financeThreadPool"
)
@Resource
(
name
=
"financeThreadPool"
)
private
Executor
executor
;
private
Executor
executor
;
...
@@ -166,7 +128,8 @@ public class PayServiceImpl implements PayService {
...
@@ -166,7 +128,8 @@ public class PayServiceImpl implements PayService {
.
map
(
BaseAuthInfoVO:
:
getOpenId
).
orElse
(
null
);
.
map
(
BaseAuthInfoVO:
:
getOpenId
).
orElse
(
null
);
case
ALI:
case
ALI:
try
{
try
{
AlipaySystemOauthTokenResponse
response
=
aliClientMap
.
get
(
appId
).
execute
(
convert
(
authCode
));
AlipaySystemOauthTokenResponse
response
=
aliClientMap
.
get
(
appId
)
.
execute
(
PayConvert
.
convertAlipaySystemOauthTokenRequest
(
authCode
));
log
.
info
(
"get ali openId response {}, {}, {}"
,
appId
,
authCode
,
JSON
.
toJSONString
(
response
));
log
.
info
(
"get ali openId response {}, {}, {}"
,
appId
,
authCode
,
JSON
.
toJSONString
(
response
));
return
response
.
getOpenId
();
return
response
.
getOpenId
();
}
catch
(
AlipayApiException
e
)
{
}
catch
(
AlipayApiException
e
)
{
...
@@ -177,22 +140,14 @@ public class PayServiceImpl implements PayService {
...
@@ -177,22 +140,14 @@ public class PayServiceImpl implements PayService {
}
}
}
}
public
AlipaySystemOauthTokenRequest
convert
(
String
authCode
)
{
AlipaySystemOauthTokenRequest
aliRequest
=
new
AlipaySystemOauthTokenRequest
();
aliRequest
.
setCode
(
authCode
);
aliRequest
.
setGrantType
(
"authorization_code"
);
return
aliRequest
;
}
@Override
@Override
public
PayVO
nativePay
(
NativePayParams
params
)
{
public
PayVO
nativePay
(
NativePayParams
params
)
{
return
payRpcService
.
pay
(
convertNativePay
(
params
));
return
payRpcService
.
pay
(
PayConvert
.
convertNativePay
(
params
,
config
));
}
}
@Override
@Override
public
PayVO
appPay
(
AppPayParams
params
)
{
public
PayVO
appPay
(
AppPayParams
params
)
{
return
payRpcService
.
pay
(
convertAppPay
(
params
));
return
payRpcService
.
pay
(
PayConvert
.
convertAppPay
(
params
,
config
));
}
}
@Override
@Override
...
@@ -211,7 +166,7 @@ public class PayServiceImpl implements PayService {
...
@@ -211,7 +166,7 @@ public class PayServiceImpl implements PayService {
this
.
payCallback
(
PayConvert
.
convertEvent
(
request
,
vo
));
this
.
payCallback
(
PayConvert
.
convertEvent
(
request
,
vo
));
if
(
PayStateEnums
.
FAILED
==
PayStateEnums
.
getByCode
(
vo
.
getPayState
()))
{
if
(
PayStateEnums
.
FAILED
==
PayStateEnums
.
getByCode
(
vo
.
getPayState
()))
{
throw
new
BizException
(
replaceFailMessage
(
vo
.
getFailMsg
()));
throw
new
BizException
(
PayConvert
.
replaceFailMessage
(
vo
.
getFailMsg
()));
}
}
return
vo
;
return
vo
;
}
}
...
@@ -252,262 +207,6 @@ public class PayServiceImpl implements PayService {
...
@@ -252,262 +207,6 @@ public class PayServiceImpl implements PayService {
}
}
@Override
public
RefundVO
merchantRefund
(
StudioMerchantRefundParams
params
)
{
StudioCashierRecord
refund
=
transactionTemplate
.
execute
(
action
->
{
Long
payId
=
Long
.
parseLong
(
params
.
getPayTransNo
());
StudioCashierRecord
pay
=
studioCashierRecordRpService
.
getById
(
payId
)
.
orElseThrow
(()
->
new
BizException
(
FinanceErrorEnums
.
NOT_EXIST
));
BigDecimal
historyRefundActualAmount
=
studioCashierRecordRpService
.
sumRefundActualAmountByPayTransNo
(
params
.
getPayTransNo
());
StudioCashierRecord
record
=
PayConvert
.
convertRefundInit
(
params
,
pay
,
historyRefundActualAmount
);
studioCashierRecordRpService
.
insert
(
record
);
return
record
;
});
RefundPayRequest
request
=
PayConvert
.
convert
(
params
,
refund
);
RefundVO
vo
=
payRpcService
.
refund
(
request
);
StudioCashierRecord
toModify
=
PayConvert
.
convertRefund
(
refund
,
vo
);
studioCashierRecordRpService
.
updateById
(
toModify
);
return
vo
;
}
@Override
public
void
refundCallback
(
RefundEvent
event
)
{
StudioCashierRecord
record
=
studioCashierRecordRpService
.
getById
(
Long
.
parseLong
(
event
.
getTransNo
()))
.
orElse
(
null
);
if
(
null
==
record
)
{
return
;
}
StudioCashierRecord
toModify
=
PayConvert
.
convertRefund
(
record
,
event
);
studioCashierRecordRpService
.
updateById
(
toModify
);
}
@Override
public
void
checkSettle
(
Long
merchantId
,
Date
settleDate
)
{
Date
endDate
=
null
==
settleDate
?
TimeUtil
.
local
().
startOfDay
(
new
Date
())
:
settleDate
;
AtomicInteger
failCount
=
new
AtomicInteger
(
0
);
this
.
pageAndConsumer
(
merchantId
,
200
,
apply
->
{
// 同步历史处理中的结算记录
Date
startDate
=
this
.
syncHistorySettle
(
apply
.
getMerchantId
(),
endDate
);
MerchantSettleRecord
exist
=
merchantSettleRecordRpService
.
getByMerchantIdAndSettleDate
(
apply
.
getMerchantId
(),
endDate
);
if
(
null
!=
exist
)
{
return
;
}
// 对账
SettleVO
vo
=
payRpcService
.
syncSettle
(
apply
.
getMerchantId
(),
endDate
);
BigDecimal
totalPayAmount
=
studioCashierRecordRpService
.
sumMerchantPaySuccess
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
BigDecimal
totalRefundAmount
=
studioCashierRecordRpService
.
sumMerchantRefundSuccess
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
// 没有钱包,退款金额只能从入账中扣,因此收款的钱必须大于等于退款的钱
BigDecimal
totalAmount
=
MoneyUtil
.
subtract
(
totalPayAmount
,
totalRefundAmount
);
log
.
info
(
"settle vo is {}, local total amount is {}, total pay amount is {}, total refund amount is {}"
,
JSON
.
toJSONString
(
vo
),
totalAmount
,
totalPayAmount
,
totalRefundAmount
);
if
(
BigDecimal
.
ZERO
.
compareTo
(
vo
.
getTransAmount
())
==
0
&&
BigDecimal
.
ZERO
.
compareTo
(
totalAmount
)
==
0
)
{
// 没有交易
return
;
}
if
(
vo
.
getTransAmount
().
compareTo
(
totalAmount
)
==
0
)
{
// 对账成功
Map
<
Long
,
BigDecimal
>
studioPayAmountMap
=
studioCashierRecordRpService
.
sumMerchantPaySuccessGroupByStudioId
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
Map
<
Long
,
BigDecimal
>
studioRefundAmountMap
=
studioCashierRecordRpService
.
sumMerchantRefundSuccessGroupByStudioId
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
Map
<
Long
,
StudioVO
>
studioMap
=
studioRpcService
.
mapStudio
(
Lists
.
newArrayList
(
studioPayAmountMap
.
keySet
()));
transactionTemplate
.
executeWithoutResult
(
action
->
{
MerchantSettleRecord
record
=
PayConvert
.
convertMerchantSettle
(
apply
,
vo
);
merchantSettleRecordRpService
.
insert
(
record
);
studioSettleRecordRpService
.
insertAll
(
PayConvert
.
convertStudioSettle
(
record
,
studioPayAmountMap
,
studioRefundAmountMap
,
studioMap
));
});
if
(
TransStateEnums
.
SUCCESS
==
TransStateEnums
.
getByCode
(
vo
.
getTransState
()))
{
// 结算成功,则更新收银流水状态为记录为入账成功
this
.
updatePayIn
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
}
}
else
{
// 对账失败
failCount
.
incrementAndGet
();
studioCheckSettleRecordRpService
.
insert
(
PayConvert
.
convertCheckSettle
(
apply
,
vo
,
totalAmount
));
}
});
// 钉钉消息
if
(
failCount
.
get
()
>
0
)
{
DingUtil
.
sendCheckSettleFail
(
env
,
failCount
.
get
());
}
else
{
DingUtil
.
sendCheckSettleSuccess
(
env
);
}
}
@Override
public
void
syncSettle
(
Long
merchantId
,
Date
settleDate
)
{
Date
endDate
=
null
==
settleDate
?
TimeUtil
.
local
().
startOfDay
(
new
Date
())
:
settleDate
;
this
.
pageAndConsumer
(
merchantId
,
200
,
apply
->
this
.
syncHistorySettle
(
apply
.
getMerchantId
(),
endDate
));
}
private
Date
syncHistorySettle
(
Long
merchantId
,
Date
endDate
)
{
Date
startDate
=
TimeUtil
.
local
().
plus
(
endDate
,
-
15
,
ChronoUnit
.
DAYS
);
List
<
MerchantSettleRecord
>
list
=
merchantSettleRecordRpService
.
listInitAndProcessByMerchantIdAndBeforeOrEqualEndDate
(
merchantId
,
endDate
);
if
(
CollectionUtil
.
isEmpty
(
list
))
{
return
startDate
;
}
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
MerchantSettleRecord
history
=
list
.
get
(
i
);
SettleVO
vo
=
payRpcService
.
syncSettle
(
merchantId
,
history
.
getSettleDate
());
if
(
vo
==
null
)
{
if
(
i
==
0
)
{
return
TimeUtil
.
local
().
plus
(
history
.
getSettleDate
(),
-
15
,
ChronoUnit
.
DAYS
);
}
else
{
return
list
.
get
(
i
-
1
).
getSettleDate
();
}
}
TransStateEnums
state
=
TransStateEnums
.
getByCode
(
vo
.
getTransState
());
if
(
TransStateEnums
.
INIT
==
state
||
TransStateEnums
.
PROCESS
==
state
)
{
if
(
i
==
0
)
{
return
TimeUtil
.
local
().
plus
(
history
.
getSettleDate
(),
-
15
,
ChronoUnit
.
DAYS
);
}
else
{
return
list
.
get
(
i
-
1
).
getSettleDate
();
}
}
transactionTemplate
.
executeWithoutResult
(
action
->
{
merchantSettleRecordRpService
.
updateById
(
PayConvert
.
convertMerchantSettle
(
history
,
vo
));
studioSettleRecordRpService
.
updateByParentId
(
PayConvert
.
convertStudioSettle
(
history
,
vo
));
});
if
(
TransStateEnums
.
SUCCESS
==
state
)
{
this
.
updatePayIn
(
merchantId
,
null
,
history
.
getSettleDate
());
}
startDate
=
history
.
getSettleDate
();
}
return
startDate
;
}
private
void
updatePayIn
(
Long
merchantId
,
Date
startTime
,
Date
endTime
)
{
Integer
current
=
0
;
Integer
size
=
500
;
do
{
Page
<
StudioCashierRecord
>
page
=
studioCashierRecordRpService
.
pageMerchantPaySuccess
(
merchantId
,
startTime
,
endTime
,
current
,
size
);
if
(
CollectionUtil
.
isEmpty
(
page
.
getContent
()))
{
break
;
}
try
{
List
<
Long
>
ids
=
page
.
getContent
().
stream
().
map
(
StudioCashierRecord:
:
getId
).
collect
(
toList
());
studioCashierRecordRpService
.
updateByIds
(
StudioCashierRecord
.
builder
().
transState
(
BrandCashierTransStateEnum
.
PAY_IN
.
getCode
())
.
inTime
(
endTime
)
.
updateTime
(
new
Date
()).
build
(),
ids
);
}
finally
{
current
++;
}
if
(!
page
.
hasNext
())
{
break
;
}
}
while
(
true
);
}
public
void
pageAndConsumer
(
Long
merchantId
,
Integer
batch
,
Consumer
<
StudioMerchantApply
>
consumer
)
{
Long
minId
=
0L
;
log
.
info
(
"consumer merchant apply start"
);
do
{
List
<
StudioMerchantApply
>
list
=
studioMerchantApplyRpService
.
listByMinId
(
minId
,
merchantId
,
batch
);
if
(
CollectionUtil
.
isEmpty
(
list
))
{
break
;
}
try
{
list
.
forEach
(
apply
->
{
try
{
log
.
info
(
"start consumer merchant apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
());
consumer
.
accept
(
apply
);
log
.
info
(
"end consumer merchant apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
());
}
catch
(
Exception
e
)
{
log
.
error
(
"consumer apply fail apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
(),
e
);
}
});
}
finally
{
minId
=
list
.
get
(
list
.
size
()
-
1
).
getId
();
}
}
while
(
true
);
log
.
info
(
"consumer merchant apply finished"
);
}
private
String
getChannelNo
(
NativePayParams
params
)
{
switch
(
params
.
getChannel
())
{
case
WX:
return
config
.
getWxNative
();
case
ALI:
return
config
.
getAliNative
();
default
:
throw
new
BizException
(
FinanceErrorEnums
.
NOT_SUPPORT_TYPE
);
}
}
private
String
getChannelNo
(
AppPayParams
params
)
{
switch
(
params
.
getChannel
())
{
case
WX:
return
config
.
getWxApp
();
case
ALI:
return
config
.
getAliApp
();
default
:
throw
new
BizException
(
FinanceErrorEnums
.
NOT_SUPPORT_TYPE
);
}
}
private
PayRequest
convertNativePay
(
NativePayParams
params
)
{
PayRequest
req
=
new
PayRequest
();
req
.
setChannelNo
(
getChannelNo
(
params
));
req
.
setTransNo
(
IdWorker
.
getIdStr
());
req
.
setAmount
(
params
.
getAmount
());
req
.
setPayType
(
PayTypeEnums
.
NATIVE
);
req
.
setGoods
(
params
.
getGoods
());
req
.
setOrderNo
(
params
.
getOrderNo
());
req
.
setOrderType
(
params
.
getOrderType
().
getCode
());
req
.
setTimeExpire
(
params
.
getTimeExpire
());
req
.
setTradingTime
(
new
Date
());
req
.
setExtra
(
params
.
getExtra
());
return
req
;
}
private
PayRequest
convertAppPay
(
AppPayParams
params
)
{
PayRequest
req
=
new
PayRequest
();
req
.
setChannelNo
(
getChannelNo
(
params
));
req
.
setTransNo
(
IdWorker
.
getIdStr
());
req
.
setAmount
(
params
.
getAmount
());
req
.
setPayType
(
PayTypeEnums
.
APP
);
req
.
setGoods
(
params
.
getGoods
());
req
.
setOrderNo
(
params
.
getOrderNo
());
req
.
setOrderType
(
params
.
getOrderType
().
getCode
());
req
.
setTimeExpire
(
params
.
getTimeExpire
());
req
.
setTradingTime
(
new
Date
());
req
.
setExtra
(
params
.
getExtra
());
return
req
;
}
private
List
<
Long
>
getAdminIds
(
Long
studioId
)
{
private
List
<
Long
>
getAdminIds
(
Long
studioId
)
{
List
<
Long
>
userIds
=
this
.
getUserIds
(
studioId
);
List
<
Long
>
userIds
=
this
.
getUserIds
(
studioId
);
if
(
CollectionUtil
.
isEmpty
(
userIds
))
{
if
(
CollectionUtil
.
isEmpty
(
userIds
))
{
...
@@ -586,9 +285,6 @@ public class PayServiceImpl implements PayService {
...
@@ -586,9 +285,6 @@ public class PayServiceImpl implements PayService {
return
Pair
.
of
(
relation
,
studio
);
return
Pair
.
of
(
relation
,
studio
);
}
}
private
FinanceErrorEnums
replaceFailMessage
(
String
failMsg
)
{
return
PayFailMessageReplaceEnums
.
convertBySource
(
failMsg
);
}
@Data
@Data
private
static
class
AliInfo
{
private
static
class
AliInfo
{
...
...
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/RefundServiceImpl.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
impl
;
import
com.jiejing.common.exception.BizException
;
import
com.jiejing.fitness.finance.repository.entity.StudioCashierRecord
;
import
com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
import
com.jiejing.fitness.finance.service.pay.RefundService
;
import
com.jiejing.fitness.finance.service.pay.convert.RefundConvert
;
import
com.jiejing.fitness.finance.service.pay.params.StudioMerchantRefundParams
;
import
com.jiejing.fitness.finance.service.rpc.PayRpcService
;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.common.event.RefundEvent
;
import
com.jiejing.paycenter.common.model.vo.RefundVO
;
import
java.math.BigDecimal
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.support.TransactionTemplate
;
/**
* @author chengyubing
* @since 2024/5/7 16:37
*/
@Slf4j
@Service
public
class
RefundServiceImpl
implements
RefundService
{
@Resource
private
PayRpcService
payRpcService
;
@Resource
private
StudioCashierRecordRpService
studioCashierRecordRpService
;
@Resource
private
TransactionTemplate
transactionTemplate
;
@Override
public
RefundVO
merchantRefund
(
StudioMerchantRefundParams
params
)
{
StudioCashierRecord
refund
=
transactionTemplate
.
execute
(
action
->
{
Long
payId
=
Long
.
parseLong
(
params
.
getPayTransNo
());
StudioCashierRecord
pay
=
studioCashierRecordRpService
.
getById
(
payId
)
.
orElseThrow
(()
->
new
BizException
(
FinanceErrorEnums
.
NOT_EXIST
));
BigDecimal
historyRefundActualAmount
=
studioCashierRecordRpService
.
sumRefundActualAmountByPayTransNo
(
params
.
getPayTransNo
());
StudioCashierRecord
record
=
RefundConvert
.
convertRefundInit
(
params
,
pay
,
historyRefundActualAmount
);
studioCashierRecordRpService
.
insert
(
record
);
return
record
;
});
RefundPayRequest
request
=
RefundConvert
.
convert
(
params
,
refund
);
RefundVO
vo
=
payRpcService
.
refund
(
request
);
StudioCashierRecord
toModify
=
RefundConvert
.
convertRefund
(
refund
,
vo
);
studioCashierRecordRpService
.
updateById
(
toModify
);
return
vo
;
}
@Override
public
void
refundCallback
(
RefundEvent
event
)
{
StudioCashierRecord
record
=
studioCashierRecordRpService
.
getById
(
Long
.
parseLong
(
event
.
getTransNo
()))
.
orElse
(
null
);
if
(
null
==
record
)
{
return
;
}
StudioCashierRecord
toModify
=
RefundConvert
.
convertRefund
(
record
,
event
);
studioCashierRecordRpService
.
updateById
(
toModify
);
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/SettleServiceImpl.java
0 → 100644
View file @
1751aced
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
impl
;
import
static
java
.
math
.
BigDecimal
.
ZERO
;
import
static
java
.
util
.
stream
.
Collectors
.
toList
;
import
com.alibaba.fastjson.JSON
;
import
com.google.common.collect.Lists
;
import
com.jiejing.common.utils.collection.CollectionUtil
;
import
com.jiejing.common.utils.time.TimeUtil
;
import
com.jiejing.fitness.enums.finance.BrandCashierTransStateEnum
;
import
com.jiejing.fitness.finance.repository.entity.MerchantSettleRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.StudioMerchantApply
;
import
com.jiejing.fitness.finance.repository.service.MerchantSettleRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioCashierRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioCheckSettleRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioMerchantApplyRpService
;
import
com.jiejing.fitness.finance.repository.service.StudioSettleRecordRpService
;
import
com.jiejing.fitness.finance.service.pay.SettleService
;
import
com.jiejing.fitness.finance.service.pay.convert.SettleConvert
;
import
com.jiejing.fitness.finance.service.rpc.PayRpcService
;
import
com.jiejing.fitness.finance.service.rpc.StudioRpcService
;
import
com.jiejing.fitness.finance.service.utils.DingUtil
;
import
com.jiejing.fitness.finance.service.utils.MoneyUtil
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.model.vo.SettleVO
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
java.math.BigDecimal
;
import
java.time.temporal.ChronoUnit
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.Consumer
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.domain.Page
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.support.TransactionTemplate
;
/**
* @author chengyubing
* @since 2024/5/7 16:33
*/
@Slf4j
@Service
public
class
SettleServiceImpl
implements
SettleService
{
@Value
(
"${spring.profiles.active}"
)
private
String
env
;
@Resource
private
PayRpcService
payRpcService
;
@Resource
private
StudioRpcService
studioRpcService
;
@Resource
private
StudioCashierRecordRpService
studioCashierRecordRpService
;
@Resource
private
StudioSettleRecordRpService
studioSettleRecordRpService
;
@Resource
private
StudioMerchantApplyRpService
studioMerchantApplyRpService
;
@Resource
private
StudioCheckSettleRecordRpService
studioCheckSettleRecordRpService
;
@Resource
private
TransactionTemplate
transactionTemplate
;
@Resource
private
MerchantSettleRecordRpService
merchantSettleRecordRpService
;
@Override
public
void
checkSettle
(
Long
merchantId
,
Date
settleDate
)
{
Date
endDate
=
null
==
settleDate
?
TimeUtil
.
local
().
startOfDay
(
new
Date
())
:
settleDate
;
AtomicInteger
failCount
=
new
AtomicInteger
(
0
);
this
.
pageAndConsumer
(
merchantId
,
200
,
apply
->
{
// 同步历史处理中的结算记录
Date
startDate
=
this
.
syncHistorySettle
(
apply
.
getMerchantId
(),
endDate
);
// 重复处理,直接return
if
(
this
.
repeat
(
apply
,
endDate
))
{
return
;
}
// 获取三方结算记录
SettleVO
vo
=
payRpcService
.
syncSettle
(
apply
.
getMerchantId
(),
endDate
);
// 获取本地待结算金额
BigDecimal
totalAmount
=
this
.
getWaitSettleAmount
(
apply
,
startDate
,
endDate
);
if
(
ZERO
.
compareTo
(
vo
.
getTransAmount
())
==
0
&&
ZERO
.
compareTo
(
totalAmount
)
==
0
)
{
return
;
}
if
(
vo
.
getTransAmount
().
compareTo
(
totalAmount
)
==
0
)
{
// 对账成功
this
.
doCheckSettleSuccess
(
vo
,
apply
,
startDate
,
endDate
);
}
else
{
// 对账失败
this
.
doCheckSettleFail
(
failCount
,
vo
,
apply
,
totalAmount
);
}
});
// 钉钉消息
this
.
doAfterCheckSettle
(
failCount
);
}
@Override
public
void
syncSettle
(
Long
merchantId
,
Date
settleDate
)
{
Date
endDate
=
null
==
settleDate
?
TimeUtil
.
local
().
startOfDay
(
new
Date
())
:
settleDate
;
this
.
pageAndConsumer
(
merchantId
,
200
,
apply
->
this
.
syncHistorySettle
(
apply
.
getMerchantId
(),
endDate
));
}
private
Date
syncHistorySettle
(
Long
merchantId
,
Date
endDate
)
{
Date
startDate
=
TimeUtil
.
local
().
plus
(
endDate
,
-
15
,
ChronoUnit
.
DAYS
);
List
<
MerchantSettleRecord
>
list
=
merchantSettleRecordRpService
.
listInitAndProcessByMerchantIdAndBeforeOrEqualEndDate
(
merchantId
,
endDate
);
if
(
CollectionUtil
.
isEmpty
(
list
))
{
return
startDate
;
}
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
MerchantSettleRecord
history
=
list
.
get
(
i
);
SettleVO
vo
=
payRpcService
.
syncSettle
(
merchantId
,
history
.
getSettleDate
());
if
(
vo
==
null
)
{
if
(
i
==
0
)
{
return
TimeUtil
.
local
().
plus
(
history
.
getSettleDate
(),
-
15
,
ChronoUnit
.
DAYS
);
}
else
{
return
list
.
get
(
i
-
1
).
getSettleDate
();
}
}
TransStateEnums
state
=
TransStateEnums
.
getByCode
(
vo
.
getTransState
());
if
(
TransStateEnums
.
INIT
==
state
||
TransStateEnums
.
PROCESS
==
state
)
{
if
(
i
==
0
)
{
return
TimeUtil
.
local
().
plus
(
history
.
getSettleDate
(),
-
15
,
ChronoUnit
.
DAYS
);
}
else
{
return
list
.
get
(
i
-
1
).
getSettleDate
();
}
}
transactionTemplate
.
executeWithoutResult
(
action
->
{
merchantSettleRecordRpService
.
updateById
(
SettleConvert
.
convertMerchantSettle
(
history
,
vo
));
studioSettleRecordRpService
.
updateByParentId
(
SettleConvert
.
convertStudioSettle
(
history
,
vo
));
});
if
(
TransStateEnums
.
SUCCESS
==
state
)
{
this
.
updatePayIn
(
merchantId
,
null
,
history
.
getSettleDate
());
}
startDate
=
history
.
getSettleDate
();
}
return
startDate
;
}
private
void
updatePayIn
(
Long
merchantId
,
Date
startTime
,
Date
endTime
)
{
Integer
current
=
0
;
Integer
size
=
500
;
do
{
Page
<
StudioCashierRecord
>
page
=
studioCashierRecordRpService
.
pageMerchantPaySuccess
(
merchantId
,
startTime
,
endTime
,
current
,
size
);
if
(
CollectionUtil
.
isEmpty
(
page
.
getContent
()))
{
break
;
}
try
{
List
<
Long
>
ids
=
page
.
getContent
().
stream
().
map
(
StudioCashierRecord:
:
getId
).
collect
(
toList
());
studioCashierRecordRpService
.
updateByIds
(
StudioCashierRecord
.
builder
().
transState
(
BrandCashierTransStateEnum
.
PAY_IN
.
getCode
())
.
inTime
(
endTime
).
updateTime
(
new
Date
()).
build
(),
ids
);
}
finally
{
current
++;
}
if
(!
page
.
hasNext
())
{
break
;
}
}
while
(
true
);
}
public
void
pageAndConsumer
(
Long
merchantId
,
Integer
batch
,
Consumer
<
StudioMerchantApply
>
consumer
)
{
Long
minId
=
0L
;
log
.
info
(
"consumer merchant apply start"
);
do
{
List
<
StudioMerchantApply
>
list
=
studioMerchantApplyRpService
.
listByMinId
(
minId
,
merchantId
,
batch
);
if
(
CollectionUtil
.
isEmpty
(
list
))
{
break
;
}
try
{
list
.
forEach
(
apply
->
{
try
{
log
.
info
(
"start consumer merchant apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
());
consumer
.
accept
(
apply
);
log
.
info
(
"end consumer merchant apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
());
}
catch
(
Exception
e
)
{
log
.
error
(
"consumer apply fail apply {}, {}"
,
apply
.
getMerchantId
(),
apply
.
getMerchantNo
(),
e
);
}
});
}
finally
{
minId
=
list
.
get
(
list
.
size
()
-
1
).
getId
();
}
}
while
(
true
);
log
.
info
(
"consumer merchant apply finished"
);
}
/**
* 计算待结算金额。对于给定的商户申请,在指定日期范围内,计算其成功支付金额减去成功退款金额的差额作为待结算金额。
*
* @param apply 商户申请信息,用于获取商户ID。
* @param startDate 计算范围的开始日期。
* @param endDate 计算范围的结束日期。
* @return BigDecimal类型的待结算金额。
*/
private
BigDecimal
getWaitSettleAmount
(
StudioMerchantApply
apply
,
Date
startDate
,
Date
endDate
)
{
// 计算指定日期范围内商户的成功支付总额
BigDecimal
totalPayAmount
=
studioCashierRecordRpService
.
sumMerchantPaySuccess
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
// 计算指定日期范围内商户的成功退款总额
BigDecimal
totalRefundAmount
=
studioCashierRecordRpService
.
sumMerchantRefundSuccess
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
// 没有钱包,退款金额只能从入账中扣,因此收款的钱必须大于等于退款的钱
BigDecimal
totalAmount
=
MoneyUtil
.
subtract
(
totalPayAmount
,
totalRefundAmount
);
log
.
info
(
"merchant {} local total amount is {}, total pay amount is {}, total refund amount is {}"
,
apply
.
getMerchantId
(),
totalAmount
,
totalPayAmount
,
totalRefundAmount
);
return
totalAmount
;
}
private
void
doCheckSettleSuccess
(
SettleVO
vo
,
StudioMerchantApply
apply
,
Date
startDate
,
Date
endDate
)
{
// 对账成功
Map
<
Long
,
BigDecimal
>
studioPayAmountMap
=
studioCashierRecordRpService
.
sumMerchantPaySuccessGroupByStudioId
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
Map
<
Long
,
BigDecimal
>
studioRefundAmountMap
=
studioCashierRecordRpService
.
sumMerchantRefundSuccessGroupByStudioId
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
Map
<
Long
,
StudioVO
>
studioMap
=
studioRpcService
.
mapStudio
(
Lists
.
newArrayList
(
studioPayAmountMap
.
keySet
()));
transactionTemplate
.
executeWithoutResult
(
action
->
{
MerchantSettleRecord
record
=
SettleConvert
.
convertMerchantSettle
(
apply
,
vo
);
merchantSettleRecordRpService
.
insert
(
record
);
studioSettleRecordRpService
.
insertAll
(
SettleConvert
.
convertStudioSettle
(
record
,
studioPayAmountMap
,
studioRefundAmountMap
,
studioMap
));
});
if
(
TransStateEnums
.
SUCCESS
==
TransStateEnums
.
getByCode
(
vo
.
getTransState
()))
{
// 结算成功,则更新收银流水状态为记录为入账成功
this
.
updatePayIn
(
apply
.
getMerchantId
(),
startDate
,
endDate
);
}
}
private
boolean
repeat
(
StudioMerchantApply
apply
,
Date
endDate
)
{
MerchantSettleRecord
exist
=
merchantSettleRecordRpService
.
getByMerchantIdAndSettleDate
(
apply
.
getMerchantId
(),
endDate
);
if
(
null
!=
exist
)
{
return
true
;
}
return
false
;
}
/**
* 对账失败处理
*/
private
void
doCheckSettleFail
(
AtomicInteger
failCount
,
SettleVO
vo
,
StudioMerchantApply
apply
,
BigDecimal
totalAmount
)
{
failCount
.
incrementAndGet
();
studioCheckSettleRecordRpService
.
insert
(
SettleConvert
.
convertCheckSettle
(
apply
,
vo
,
totalAmount
));
}
private
void
doAfterCheckSettle
(
AtomicInteger
failCount
)
{
if
(
failCount
.
get
()
>
0
)
{
DingUtil
.
sendCheckSettleFail
(
env
,
failCount
.
get
());
}
else
{
DingUtil
.
sendCheckSettleSuccess
(
env
);
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/rpc/PayRpcService.java
View file @
1751aced
...
@@ -57,8 +57,10 @@ public class PayRpcService {
...
@@ -57,8 +57,10 @@ public class PayRpcService {
.
settleDate
(
settleDate
)
.
settleDate
(
settleDate
)
.
build
());
.
build
());
result
.
assertSuccess
();
result
.
assertSuccess
();
return
Optional
.
ofNullable
(
result
.
getResult
())
SettleVO
vo
=
Optional
.
ofNullable
(
result
.
getResult
())
.
orElse
(
SettleVO
.
builder
().
transAmount
(
BigDecimal
.
ZERO
).
build
());
.
orElse
(
SettleVO
.
builder
().
transAmount
(
BigDecimal
.
ZERO
).
build
());
log
.
info
(
"merchant {} settle vo is {}"
,
merchantId
,
JSON
.
toJSONString
(
vo
));
return
vo
;
}
}
public
BigDecimal
getFeeRate
(
PayRequest
request
)
{
public
BigDecimal
getFeeRate
(
PayRequest
request
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment