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
a8af2435
Commit
a8af2435
authored
Feb 28, 2024
by
程裕兵
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:refund
parent
f3bb7333
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
233 additions
and
77 deletions
+233
-77
api/src/main/java/com/jiejing/fitness/finance/api/enums/BrandCashierTransStateEnums.java
+5
-4
repository/src/main/java/com/jiejing/fitness/finance/repository/mapper/BrandCashierRecordMapper.java
+4
-0
repository/src/main/java/com/jiejing/fitness/finance/repository/mapper/BrandCashierRecordMapper.xml
+6
-0
repository/src/main/java/com/jiejing/fitness/finance/repository/service/BrandCashierRecordRpService.java
+8
-1
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/PayConvert.java
+60
-9
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/PayServiceImpl.java
+19
-10
service/src/main/java/com/jiejing/fitness/finance/service/pay/params/BrandMerchantRefundParams.java
+8
-48
service/src/main/java/com/jiejing/fitness/finance/service/rpc/PayRpcService.java
+8
-3
service/src/main/java/com/jiejing/fitness/finance/service/utils/FeeUtil.java
+101
-1
service/src/main/java/com/jiejing/fitness/finance/service/utils/MoneyUtil.java
+14
-1
No files found.
api/src/main/java/com/jiejing/fitness/finance/api/enums/BrandCashierTransStateEnums.java
View file @
a8af2435
...
@@ -18,11 +18,12 @@ public enum BrandCashierTransStateEnums {
...
@@ -18,11 +18,12 @@ public enum BrandCashierTransStateEnums {
PAY_INIT
(
0
,
"支付初始态"
),
PAY_INIT
(
0
,
"支付初始态"
),
PAYING
(
1
,
"支付中"
),
PAYING
(
1
,
"支付中"
),
PAY_FAIL
(
2
,
"支付失败"
),
PAY_FAIL
(
2
,
"支付失败"
),
PAY_SUCCESS
(
3
,
"
入账中(支付成功
)"
),
PAY_SUCCESS
(
3
,
"
支付成功(入账中
)"
),
PAY_IN
(
4
,
"入账成功"
),
PAY_IN
(
4
,
"入账成功"
),
REFUNDING
(
5
,
"退款中"
),
REFUND_INIT
(
5
,
"退款初始态"
),
REFUND_SUCCESS
(
6
,
"退款成功"
),
REFUNDING
(
6
,
"退款中"
),
REFUND_FAIL
(
7
,
"退款失败"
),
REFUND_SUCCESS
(
7
,
"退款成功"
),
REFUND_FAIL
(
8
,
"退款失败"
),
;
;
@EnumValue
@EnumValue
...
...
repository/src/main/java/com/jiejing/fitness/finance/repository/mapper/BrandCashierRecordMapper.java
View file @
a8af2435
...
@@ -16,6 +16,8 @@ package com.jiejing.fitness.finance.repository.mapper;
...
@@ -16,6 +16,8 @@ package com.jiejing.fitness.finance.repository.mapper;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.mbp.inject.XBaseMapper
;
import
com.jiejing.mbp.inject.XBaseMapper
;
import
java.math.BigDecimal
;
import
org.apache.ibatis.annotations.Param
;
/**
/**
* <p>
* <p>
...
@@ -26,4 +28,6 @@ import com.jiejing.mbp.inject.XBaseMapper;
...
@@ -26,4 +28,6 @@ import com.jiejing.mbp.inject.XBaseMapper;
*/
*/
public
interface
BrandCashierRecordMapper
extends
XBaseMapper
<
BrandCashierRecord
>
{
public
interface
BrandCashierRecordMapper
extends
XBaseMapper
<
BrandCashierRecord
>
{
BigDecimal
sumRefundActualAmountByPayTransNo
(
@Param
(
"payTransNo"
)
String
payTransNo
);
}
}
repository/src/main/java/com/jiejing/fitness/finance/repository/mapper/BrandCashierRecordMapper.xml
View file @
a8af2435
...
@@ -19,5 +19,11 @@
...
@@ -19,5 +19,11 @@
<sql
id=
"Base_Column_List"
>
<sql
id=
"Base_Column_List"
>
id, trans_no, order_no, order_type, trans_type, brand_id, studio_id, merchant_id, merchant_no, channel_no, sub_channel, trans_amount, fee_rate, fee, actual_amount, trans_state, buyer_name, buyer_phone, goods, remark, exist_related_trans, related_trans_no, third_trans_no, fail_message, trading_time, success_time, in_time, create_time, update_time
id, trans_no, order_no, order_type, trans_type, brand_id, studio_id, merchant_id, merchant_no, channel_no, sub_channel, trans_amount, fee_rate, fee, actual_amount, trans_state, buyer_name, buyer_phone, goods, remark, exist_related_trans, related_trans_no, third_trans_no, fail_message, trading_time, success_time, in_time, create_time, update_time
</sql>
</sql>
<select
id=
"sumRefundActualAmountByPayTransNo"
resultType=
"java.math.BigDecimal"
>
select sum(actual_amount)
from brand_cashier_record
where related_trans_no = #{payTransNo}
and trans_state in (6, 7)
</select>
</mapper>
</mapper>
repository/src/main/java/com/jiejing/fitness/finance/repository/service/BrandCashierRecordRpService.java
View file @
a8af2435
...
@@ -17,6 +17,8 @@ package com.jiejing.fitness.finance.repository.service;
...
@@ -17,6 +17,8 @@ package com.jiejing.fitness.finance.repository.service;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.fitness.finance.repository.mapper.BrandCashierRecordMapper
;
import
com.jiejing.fitness.finance.repository.mapper.BrandCashierRecordMapper
;
import
com.jiejing.mbp.MapperRepoService
;
import
com.jiejing.mbp.MapperRepoService
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
/**
/**
...
@@ -27,6 +29,11 @@ import org.springframework.stereotype.Service;
...
@@ -27,6 +29,11 @@ import org.springframework.stereotype.Service;
* @author chengyubing, created on 2024-02-27
* @author chengyubing, created on 2024-02-27
*/
*/
@Service
@Service
public
class
BrandCashierRecordRpService
extends
MapperRepoService
<
Long
,
BrandCashierRecord
,
BrandCashierRecordMapper
>
{
public
class
BrandCashierRecordRpService
extends
MapperRepoService
<
Long
,
BrandCashierRecord
,
BrandCashierRecordMapper
>
{
public
BigDecimal
sumRefundActualAmountByPayTransNo
(
String
payTransNo
)
{
return
this
.
baseMapper
.
sumRefundActualAmountByPayTransNo
(
payTransNo
);
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/convert/PayConvert.java
View file @
a8af2435
...
@@ -17,6 +17,8 @@ import com.jiejing.fitness.finance.service.utils.FeeUtil;
...
@@ -17,6 +17,8 @@ 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.api.merchant.vo.MerchantVO
;
import
com.jiejing.paycenter.api.merchant.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.api.pay.vo.RefundVO
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.enums.common.TransStateEnums
;
import
com.jiejing.paycenter.common.enums.merchant.SubChannelEnums
;
import
com.jiejing.paycenter.common.enums.merchant.SubChannelEnums
;
import
com.jiejing.paycenter.common.enums.merchant.SubChannelOpenTypeEnums
;
import
com.jiejing.paycenter.common.enums.merchant.SubChannelOpenTypeEnums
;
...
@@ -42,18 +44,17 @@ public class PayConvert {
...
@@ -42,18 +44,17 @@ public class PayConvert {
private
static
final
List
<
String
>
WX_AUTH_CODE_PREFIX
=
Lists
.
newArrayList
(
"10"
,
"11"
,
"12"
,
"13"
,
"14"
,
private
static
final
List
<
String
>
WX_AUTH_CODE_PREFIX
=
Lists
.
newArrayList
(
"10"
,
"11"
,
"12"
,
"13"
,
"14"
,
"15"
);
"15"
);
public
static
PayRequest
convert
(
BrandMerchantPayParams
params
,
BrandCashierRecord
record
,
public
static
PayRequest
convert
(
BrandMerchantPayParams
params
,
BrandCashierRecord
record
)
{
MerchantVO
merchant
)
{
PayRequest
request
=
BeanUtil
.
map
(
params
,
PayRequest
.
class
);
PayRequest
request
=
BeanUtil
.
map
(
params
,
PayRequest
.
class
);
request
.
setTransNo
(
record
.
getTransNo
());
request
.
setTransNo
(
record
.
getTransNo
());
request
.
setMerchantId
(
merchant
.
ge
tId
());
request
.
setMerchantId
(
record
.
getMerchan
tId
());
request
.
setExtra
(
Optional
.
ofNullable
(
params
.
getExtra
()).
orElse
(
new
JSONObject
())
request
.
setExtra
(
Optional
.
ofNullable
(
params
.
getExtra
()).
orElse
(
new
JSONObject
())
.
fluentPut
(
"studioId"
,
params
.
getStudioId
())
.
fluentPut
(
"studioId"
,
record
.
getStudioId
())
.
fluentPut
(
"buyerName"
,
params
.
getBuyerName
())
.
fluentPut
(
"buyerName"
,
record
.
getBuyerName
())
.
fluentPut
(
"buyerPhone"
,
params
.
getBuyerPhone
())
.
fluentPut
(
"buyerPhone"
,
record
.
getBuyerPhone
())
.
fluentPut
(
"remark"
,
params
.
getRemark
())
.
fluentPut
(
"remark"
,
record
.
getRemark
())
);
);
request
.
setTransTime
(
new
Dat
e
());
request
.
setTransTime
(
record
.
getTradingTim
e
());
return
request
;
return
request
;
}
}
...
@@ -157,8 +158,58 @@ public class PayConvert {
...
@@ -157,8 +158,58 @@ public class PayConvert {
case
FAILED:
case
FAILED:
return
BrandCashierTransStateEnums
.
PAY_FAIL
;
return
BrandCashierTransStateEnums
.
PAY_FAIL
;
default
:
default
:
return
null
;
return
BrandCashierTransStateEnums
.
PAYING
;
}
}
}
}
public
static
BrandCashierRecord
convertRefundInit
(
BrandMerchantRefundParams
params
,
BrandCashierRecord
pay
,
BigDecimal
historyRefundActualAmount
)
{
BrandCashierRecord
record
=
BeanUtil
.
map
(
pay
,
BrandCashierRecord
.
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
(
BrandCashierTransStateEnums
.
REFUND_INIT
);
record
.
setTradingTime
(
new
Date
());
record
.
setCreateTime
(
new
Date
());
record
.
setUpdateTime
(
new
Date
());
return
record
;
}
public
static
RefundPayRequest
convert
(
BrandMerchantRefundParams
params
,
BrandCashierRecord
record
)
{
RefundPayRequest
request
=
BeanUtil
.
map
(
params
,
RefundPayRequest
.
class
);
request
.
setTransNo
(
record
.
getTransNo
());
return
request
;
}
public
static
BrandCashierRecord
convertRefund
(
BrandCashierRecord
record
,
RefundVO
vo
)
{
return
BrandCashierRecord
.
builder
()
.
id
(
record
.
getId
())
.
transState
(
convertTransState
(
vo
.
getRefundState
()))
.
failMessage
(
vo
.
getFailMessage
())
.
successTime
(
vo
.
getSuccessTime
())
.
updateTime
(
new
Date
())
.
build
();
}
private
static
BrandCashierTransStateEnums
convertTransState
(
TransStateEnums
state
)
{
switch
(
state
)
{
case
SUCCESS:
return
BrandCashierTransStateEnums
.
REFUND_SUCCESS
;
case
FAIL:
return
BrandCashierTransStateEnums
.
REFUND_FAIL
;
case
PROCESS:
case
INIT:
default
:
return
BrandCashierTransStateEnums
.
REFUNDING
;
}
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/impl/PayServiceImpl.java
View file @
a8af2435
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
impl
;
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
impl
;
import
com.jiejing.common.exception.BizException
;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.BrandCashierRecord
;
import
com.jiejing.fitness.finance.repository.entity.BrandToMerchant
;
import
com.jiejing.fitness.finance.repository.entity.BrandToMerchant
;
import
com.jiejing.fitness.finance.repository.service.BrandCashierRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.BrandCashierRecordRpService
;
import
com.jiejing.fitness.finance.repository.service.BrandToMerchantRpService
;
import
com.jiejing.fitness.finance.repository.service.BrandToMerchantRpService
;
import
com.jiejing.fitness.finance.service.enums.FinanceErrorEnums
;
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.params.BrandMerchantPayParams
;
import
com.jiejing.fitness.finance.service.pay.params.BrandMerchantPayParams
;
...
@@ -16,8 +18,11 @@ import com.jiejing.paycenter.api.pay.request.PayRequest;
...
@@ -16,8 +18,11 @@ import com.jiejing.paycenter.api.pay.request.PayRequest;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.api.pay.vo.PayVO
;
import
com.jiejing.paycenter.api.pay.vo.PayVO
;
import
com.jiejing.paycenter.api.pay.vo.RefundVO
;
import
com.jiejing.paycenter.api.pay.vo.RefundVO
;
import
com.jiejing.paycenter.common.enums.pay.PayStateEnums
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.paycenter.common.event.PayEvent
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
com.jiejing.studio.api.studio.vo.StudioVO
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -55,7 +60,7 @@ public class PayServiceImpl implements PayService {
...
@@ -55,7 +60,7 @@ public class PayServiceImpl implements PayService {
BrandCashierRecord
record
=
PayConvert
.
convertPayInit
(
params
,
relation
,
merchant
);
BrandCashierRecord
record
=
PayConvert
.
convertPayInit
(
params
,
relation
,
merchant
);
brandCashierRecordRpService
.
insert
(
record
);
brandCashierRecordRpService
.
insert
(
record
);
PayRequest
request
=
PayConvert
.
convert
(
params
,
record
,
merchant
);
PayRequest
request
=
PayConvert
.
convert
(
params
,
record
);
return
payRpcService
.
pay
(
request
);
return
payRpcService
.
pay
(
request
);
}
}
...
@@ -73,17 +78,21 @@ public class PayServiceImpl implements PayService {
...
@@ -73,17 +78,21 @@ public class PayServiceImpl implements PayService {
@Override
@Override
public
RefundVO
merchantRefund
(
BrandMerchantRefundParams
params
)
{
public
RefundVO
merchantRefund
(
BrandMerchantRefundParams
params
)
{
StudioVO
studio
=
studioRpcService
.
getStudio
(
params
.
getStudioId
());
BrandCashierRecord
pay
=
brandCashierRecordRpService
.
getById
(
Long
.
parseLong
(
params
.
getPayTransNo
()))
BrandToMerchant
relation
=
brandToMerchantRpService
.
getByBrandId
(
studio
.
getBrandId
(
));
.
orElseThrow
(()
->
new
BizException
(
FinanceErrorEnums
.
NOT_EXIST
));
MerchantVO
merchant
=
merchantRpcService
.
getByMerchantId
(
relation
.
getMerchantId
());
BigDecimal
historyRefundActualAmount
=
brandCashierRecordRpService
.
sumRefundActualAmountByPayTransNo
(
params
.
getPayTransNo
());
// BrandCashierRecord record = PayConvert.convertRefundInit(params, relation, merchant);
BrandCashierRecord
record
=
PayConvert
.
convertRefundInit
(
params
,
pay
,
historyRefundActualAmount
);
// brandCashierRecordRpService.insert(record);
brandCashierRecordRpService
.
insert
(
record
);
//
// RefundPayRequest request = PayConvert.convert(params, record, merchant);
RefundPayRequest
request
=
PayConvert
.
convert
(
params
,
record
);
// return payRpcService.refund(request);
RefundVO
vo
=
payRpcService
.
refund
(
request
);
return
null
;
BrandCashierRecord
toModify
=
PayConvert
.
convertRefund
(
record
,
vo
);
brandCashierRecordRpService
.
updateById
(
toModify
);
return
vo
;
}
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/pay/params/BrandMerchantRefundParams.java
View file @
a8af2435
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
params
;
package
com
.
jiejing
.
fitness
.
finance
.
service
.
pay
.
params
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jiejing.paycenter.common.enums.merchant.SubChannelEnums
;
import
com.jiejing.paycenter.common.enums.pay.PayTypeEnums
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.NotBlank
;
import
javax.validation.constraints.NotNull
;
import
javax.validation.constraints.NotNull
;
import
javax.validation.constraints.Size
;
import
lombok.AllArgsConstructor
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.Data
;
...
@@ -33,52 +29,16 @@ public class BrandMerchantRefundParams {
...
@@ -33,52 +29,16 @@ public class BrandMerchantRefundParams {
@NotNull
(
message
=
"支付总金额不能为空"
)
@NotNull
(
message
=
"支付总金额不能为空"
)
private
BigDecimal
transAmount
;
private
BigDecimal
transAmount
;
@ApiModelProperty
(
name
=
"
业务订
单号"
,
required
=
true
)
@ApiModelProperty
(
name
=
"
上层业务退款
单号"
,
required
=
true
)
@NotBlank
(
message
=
"
业务订
单号不能为空"
)
@NotBlank
(
message
=
"
上层业务退款
单号不能为空"
)
private
String
orderNo
;
private
String
orderNo
;
@ApiModelProperty
(
name
=
"
业务订单类型
"
,
required
=
true
)
@ApiModelProperty
(
name
=
"
退款请求对应的支付流水号
"
,
required
=
true
)
@Not
Null
(
message
=
"业务订单类型
不能为空"
)
@Not
Blank
(
message
=
"退款请求对应的支付流水号
不能为空"
)
private
Integer
orderType
;
private
String
payTransNo
;
@ApiModelProperty
(
name
=
"支付类型"
,
required
=
true
)
@ApiModelProperty
(
name
=
"退款原因"
,
required
=
true
)
@NotNull
(
message
=
"支付类型不能为空"
)
@NotBlank
(
message
=
"退款原因不能为空"
)
private
PayTypeEnums
payType
;
private
String
refundReason
;
@ApiModelProperty
(
name
=
"正扫:三方支付账户ID"
,
notes
=
"微信的openId,支付宝的userId,JS、MINI、NATIVE支付必传"
)
private
String
openId
;
@ApiModelProperty
(
name
=
"反扫:支付授权码"
,
notes
=
"扫码设备读出的条形码或者二维码信息,BARCODE支付必传"
)
private
String
authCode
;
@ApiModelProperty
(
name
=
"支付子渠道"
,
notes
=
"聚合支付时需要"
)
private
SubChannelEnums
subChannel
;
@ApiModelProperty
(
name
=
"商品名称"
,
required
=
true
)
@NotBlank
(
message
=
"商品名称不能为空"
)
private
String
goods
;
@ApiModelProperty
(
name
=
"付款人姓名"
,
required
=
true
)
@NotBlank
(
message
=
"付款人姓名不能为空"
)
@Size
(
max
=
30
)
private
String
buyerName
;
@ApiModelProperty
(
name
=
"付款人手机号"
,
required
=
true
)
@NotBlank
(
message
=
"付款人手机号不能为空"
)
@Size
(
max
=
11
)
private
String
buyerPhone
;
@ApiModelProperty
(
name
=
"备注"
)
private
String
remark
;
@ApiModelProperty
(
name
=
"appId"
,
notes
=
"指定本次使用的appId"
)
private
String
appId
;
@ApiModelProperty
(
name
=
"过期时间(单位:秒)"
,
required
=
true
)
@NotNull
(
message
=
"过期时间不能为空"
)
private
Integer
timeExpire
;
@ApiModelProperty
(
name
=
"业务扩展信息"
)
private
JSONObject
extra
;
}
}
service/src/main/java/com/jiejing/fitness/finance/service/rpc/PayRpcService.java
View file @
a8af2435
...
@@ -6,6 +6,7 @@ import com.jiejing.paycenter.api.pay.request.PayRequest;
...
@@ -6,6 +6,7 @@ import com.jiejing.paycenter.api.pay.request.PayRequest;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.api.pay.request.RefundPayRequest
;
import
com.jiejing.paycenter.api.pay.vo.PayVO
;
import
com.jiejing.paycenter.api.pay.vo.PayVO
;
import
com.jiejing.paycenter.api.pay.vo.RefundVO
;
import
com.jiejing.paycenter.api.pay.vo.RefundVO
;
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
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -31,9 +32,13 @@ public class PayRpcService {
...
@@ -31,9 +32,13 @@ public class PayRpcService {
}
}
public
RefundVO
refund
(
RefundPayRequest
request
)
{
public
RefundVO
refund
(
RefundPayRequest
request
)
{
JsonResult
<
RefundVO
>
result
=
payApi
.
refund
(
request
);
try
{
result
.
assertSuccess
();
JsonResult
<
RefundVO
>
result
=
payApi
.
refund
(
request
);
return
result
.
getResult
();
result
.
assertSuccess
();
return
result
.
getResult
();
}
catch
(
Exception
e
)
{
return
RefundVO
.
builder
().
refundState
(
TransStateEnums
.
FAIL
).
failMessage
(
e
.
getMessage
()).
build
();
}
}
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/utils/FeeUtil.java
View file @
a8af2435
...
@@ -2,6 +2,7 @@ package com.jiejing.fitness.finance.service.utils;
...
@@ -2,6 +2,7 @@ package com.jiejing.fitness.finance.service.utils;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.math.RoundingMode
;
import
java.util.Objects
;
/**
/**
* @author chengyubing
* @author chengyubing
...
@@ -10,7 +11,7 @@ import java.math.RoundingMode;
...
@@ -10,7 +11,7 @@ import java.math.RoundingMode;
public
class
FeeUtil
{
public
class
FeeUtil
{
/**
/**
* 计算支付手续费,保留小数点后两位,四舍五入
*
【支付】
计算支付手续费,保留小数点后两位,四舍五入
*
*
* @param feeRate 费率(%)
* @param feeRate 费率(%)
* @param amount 支付金额
* @param amount 支付金额
...
@@ -22,4 +23,103 @@ public class FeeUtil {
...
@@ -22,4 +23,103 @@ public class FeeUtil {
amount
));
amount
));
}
}
/**
* 【退款】计算退款手续费
*
* <p>实退手续费计算公式:退款手续费=向下取整(退款金额*原交易手续费金额/原交易金额)</p>
*
* @param refundTransAmount 退款申请金额
* @param payTransAmount 原支付交易金额
* @param payActualAmount 用户实收金额
* @param payFee 平台实收手续费
* @param historyRefundActualAmount 历史实退金额
* @return 本次退款应退手续费
*/
public
static
BigDecimal
calculateRefundFee
(
BigDecimal
refundTransAmount
,
BigDecimal
payTransAmount
,
BigDecimal
payActualAmount
,
BigDecimal
payFee
,
BigDecimal
historyRefundActualAmount
)
{
// 机构剩余实收金额
BigDecimal
leftPayActualAmount
=
MoneyUtil
.
subtract
(
payActualAmount
,
historyRefundActualAmount
);
// 试算手续费
BigDecimal
trialFee
=
MoneyUtil
.
divide
(
refundTransAmount
.
multiply
(
payFee
),
payTransAmount
,
0
,
RoundingMode
.
FLOOR
);
// 试算实退金额
BigDecimal
trialActualAmount
=
MoneyUtil
.
subtract
(
refundTransAmount
,
trialFee
);
// 实退手续费
return
leftPayActualAmount
.
compareTo
(
trialActualAmount
)
>=
0
?
trialFee
:
MoneyUtil
.
add
(
trialFee
,
MoneyUtil
.
subtract
(
trialActualAmount
,
leftPayActualAmount
));
}
/**
* 计算补贴回退金额(向上取整ceil)
*
* @param refundTransAmount 退款申请金额
* @param payTransAmount 原支付交易金额
* @param subsidyAmount 补贴金额
* @param historyBackAmount 历史补贴回退金额
* @return 补贴回退金额
*/
public
static
BigDecimal
calculateSubsidyBackAmount
(
BigDecimal
refundTransAmount
,
BigDecimal
payTransAmount
,
BigDecimal
subsidyAmount
,
BigDecimal
historyBackAmount
)
{
if
(
Objects
.
isNull
(
subsidyAmount
))
{
return
BigDecimal
.
ZERO
;
}
// 剩余可回退补贴金额
BigDecimal
leftSubsidyBackAmount
=
MoneyUtil
.
subtract
(
subsidyAmount
,
historyBackAmount
);
// 试算补贴回退金额
BigDecimal
trialAmount
=
MoneyUtil
.
divide
(
refundTransAmount
.
multiply
(
subsidyAmount
),
payTransAmount
,
0
,
RoundingMode
.
CEILING
);
return
leftSubsidyBackAmount
.
compareTo
(
trialAmount
)
>=
0
?
trialAmount
:
leftSubsidyBackAmount
;
}
public
static
BigDecimal
calculateAdvanceAmount
(
BigDecimal
refundAmount
,
BigDecimal
qyqbhTransitBalance
,
BigDecimal
yxyjhTransitBalance
)
{
BigDecimal
transitBalance
=
MoneyUtil
.
subtract
(
qyqbhTransitBalance
,
yxyjhTransitBalance
);
if
(
refundAmount
.
compareTo
(
transitBalance
)
<=
0
)
{
// 若:退款金额 <= 业务钱包入账中余额,则无需佣金垫付记录记账
return
null
;
}
// 若:退款金额 > 业务钱包入账中余额,则添加佣金垫付记录记账
// 垫付金额 = (退款金额 - 业务入帐中金额) > 佣金入账中 ? 佣金入账中 : (退款金额 - 入帐中金额)
BigDecimal
advanceAmount
=
MoneyUtil
.
subtract
(
refundAmount
,
transitBalance
);
if
(
advanceAmount
.
compareTo
(
yxyjhTransitBalance
)
>
0
)
{
advanceAmount
=
yxyjhTransitBalance
;
}
return
advanceAmount
;
}
public
static
void
main
(
String
[]
args
)
{
// 1. 首次退款
// BigDecimal refundTransAmount = new BigDecimal("498");
// BigDecimal payTransAmount = new BigDecimal("500");
// BigDecimal payActualAmount = new BigDecimal("498");
// BigDecimal payFee = new BigDecimal("2");
// BigDecimal historyRefundActualAmount = new BigDecimal("0");
// 预计输出:1
// 实退金额:497, 实退手续费:1。剩余可退金额:2(剩余实退金额:1,剩余实退手续费:1),历史实退金额:497,历史实退手续费:1
// 2. 二次退款
// BigDecimal refundTransAmount = new BigDecimal("1");
// BigDecimal payTransAmount = new BigDecimal("500");
// BigDecimal payActualAmount = new BigDecimal("498");
// BigDecimal payFee = new BigDecimal("2");
// BigDecimal historyRefundActualAmount = new BigDecimal("497");
// 预计输出:0
// 实退金额:1,实退手续费:0。剩余可退金额:1(剩余实退金额:0,剩余实退手续费:1),历史实退金额:498,历史实退手续费:1
// 3. 三次退款
BigDecimal
refundTransAmount
=
new
BigDecimal
(
"40"
);
BigDecimal
payTransAmount
=
new
BigDecimal
(
"10000"
);
BigDecimal
payActualAmount
=
new
BigDecimal
(
"9943"
);
BigDecimal
payFee
=
new
BigDecimal
(
"57"
);
BigDecimal
historyRefundActualAmount
=
new
BigDecimal
(
"9904"
);
// 预计输出:1
// 实退金额:0,实退手续费:1。剩余可退金额:0,历史实退金额:498,历史实退手续费:2
System
.
out
.
println
(
FeeUtil
.
calculateRefundFee
(
refundTransAmount
,
payTransAmount
,
payActualAmount
,
payFee
,
historyRefundActualAmount
));
}
}
}
service/src/main/java/com/jiejing/fitness/finance/service/utils/MoneyUtil.java
View file @
a8af2435
...
@@ -110,7 +110,7 @@ public class MoneyUtil {
...
@@ -110,7 +110,7 @@ public class MoneyUtil {
* @param v2 加数
* @param v2 加数
* @return 累加值
* @return 累加值
*/
*/
p
rivate
static
BigDecimal
add
(
BigDecimal
v1
,
BigDecimal
v2
)
{
p
ublic
static
BigDecimal
add
(
BigDecimal
v1
,
BigDecimal
v2
)
{
return
v1
.
add
(
v2
);
return
v1
.
add
(
v2
);
}
}
...
@@ -254,6 +254,19 @@ public class MoneyUtil {
...
@@ -254,6 +254,19 @@ public class MoneyUtil {
}
}
/**
/**
* 两数相除,进位规则自定义,小数点位数自定义
*
* @param v1 被除数
* @param v2 除数
* @param scale 小数点后保留位数
* @param roundingMode 进位规则
* @return 相除值
*/
public
static
BigDecimal
divide
(
BigDecimal
v1
,
BigDecimal
v2
,
int
scale
,
RoundingMode
roundingMode
)
{
return
v1
.
divide
(
v2
,
scale
,
roundingMode
);
}
/**
* 针对浮点数进行四舍五入,返回整型
* 针对浮点数进行四舍五入,返回整型
*
*
* @param v 浮点数
* @param v 浮点数
...
...
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