Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
计全科技
jeepay
提交
7e119aa2
jeepay
项目概览
计全科技
/
jeepay
通知
10
Star
3
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
6
Wiki
分析
仓库
DevOps
项目成员
Pages
jeepay
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
6
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7e119aa2
编写于
6月 17, 2021
作者:
terrfly
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
完善退款申请api;
上级
36f9aa52
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
372 addition
and
45 deletion
+372
-45
docs/sql/init.sql
docs/sql/init.sql
+1
-0
jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayOrder.java
...rc/main/java/com/jeequan/jeepay/core/entity/PayOrder.java
+8
-0
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/AbstractRefundService.java
...com/jeequan/jeepay/pay/channel/AbstractRefundService.java
+43
-0
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/IRefundService.java
...n/java/com/jeequan/jeepay/pay/channel/IRefundService.java
+42
-0
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/AlipayKit.java
...java/com/jeequan/jeepay/pay/channel/alipay/AlipayKit.java
+1
-1
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/AlipayRefundService.java
...eequan/jeepay/pay/channel/alipay/AlipayRefundService.java
+86
-0
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/ctrl/refund/RefundOrderController.java
...jeequan/jeepay/pay/ctrl/refund/RefundOrderController.java
+80
-43
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/exception/ChannelException.java
...va/com/jeequan/jeepay/pay/exception/ChannelException.java
+1
-1
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/msg/ChannelRetMsg.java
...n/java/com/jeequan/jeepay/pay/rqrs/msg/ChannelRetMsg.java
+5
-0
jeepay-service/src/main/java/com/jeequan/jeepay/service/impl/RefundOrderService.java
...a/com/jeequan/jeepay/service/impl/RefundOrderService.java
+77
-0
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.java
...ava/com/jeequan/jeepay/service/mapper/PayOrderMapper.java
+4
-0
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.xml
...java/com/jeequan/jeepay/service/mapper/PayOrderMapper.xml
+16
-0
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/RefundOrderMapper.java
.../com/jeequan/jeepay/service/mapper/RefundOrderMapper.java
+3
-0
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/RefundOrderMapper.xml
...a/com/jeequan/jeepay/service/mapper/RefundOrderMapper.xml
+5
-0
未找到文件。
docs/sql/init.sql
浏览文件 @
7e119aa2
...
...
@@ -282,6 +282,7 @@ CREATE TABLE `t_pay_order` (
`channel_extra`
VARCHAR
(
512
)
DEFAULT
NULL
COMMENT
'特定渠道发起额外参数'
,
`channel_user`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'渠道用户标识,如微信openId,支付宝账号'
,
`channel_order_no`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'渠道订单号'
,
`refund_state`
TINYINT
(
6
)
NOT
NULL
DEFAULT
'0'
COMMENT
'退款状态: 0-未发生实际退款, 1-部分退款, 2-全额退款'
,
`refund_times`
INT
NOT
NULL
DEFAULT
0
COMMENT
'退款次数'
,
`refund_amount`
BIGINT
(
20
)
NOT
NULL
DEFAULT
0
COMMENT
'退款总金额,单位分'
,
`division_flag`
TINYINT
(
6
)
DEFAULT
0
COMMENT
'订单分账标志:0-否 1-是'
,
...
...
jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayOrder.java
浏览文件 @
7e119aa2
...
...
@@ -55,6 +55,9 @@ public class PayOrder extends BaseModel implements Serializable {
public
static
final
byte
STATE_REFUND
=
5
;
//已退款
public
static
final
byte
STATE_CLOSED
=
6
;
//订单关闭
public
static
final
byte
REFUND_STATE_NONE
=
0
;
//未发生实际退款
public
static
final
byte
REFUND_STATE_SUB
=
1
;
//部分退款
public
static
final
byte
REFUND_STATE_ALL
=
2
;
//全额退款
/**
* 支付订单号
...
...
@@ -152,6 +155,11 @@ public class PayOrder extends BaseModel implements Serializable {
*/
private
String
channelOrderNo
;
/**
* 退款状态: 0-未发生实际退款, 1-部分退款, 2-全额退款
*/
private
Byte
refundState
;
/**
* 退款次数
*/
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/AbstractRefundService.java
0 → 100644
浏览文件 @
7e119aa2
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.channel
;
import
com.jeequan.jeepay.pay.util.ChannelCertConfigKitBean
;
import
com.jeequan.jeepay.service.impl.SysConfigService
;
import
org.springframework.beans.factory.annotation.Autowired
;
/*
* 退款接口抽象类
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:37
*/
public
abstract
class
AbstractRefundService
implements
IRefundService
{
@Autowired
protected
SysConfigService
sysConfigService
;
@Autowired
protected
ChannelCertConfigKitBean
channelCertConfigKitBean
;
protected
String
getNotifyUrl
(){
return
sysConfigService
.
getDBApplicationConfig
().
getPaySiteUrl
()
+
"/api/refund/notify/"
+
getIfCode
();
}
protected
String
getNotifyUrl
(
String
payOrderId
){
return
sysConfigService
.
getDBApplicationConfig
().
getPaySiteUrl
()
+
"/api/refund/notify/"
+
getIfCode
()
+
"/"
+
payOrderId
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/IRefundService.java
0 → 100644
浏览文件 @
7e119aa2
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.channel
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.entity.RefundOrder
;
import
com.jeequan.jeepay.pay.model.MchAppConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ
;
/*
* 调起上游渠道侧退款接口
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:35
*/
public
interface
IRefundService
{
/* 获取到接口code **/
String
getIfCode
();
/** 前置检查如参数等信息是否符合要求, 返回错误信息或直接抛出异常即可 */
String
preCheck
(
RefundOrderRQ
bizRQ
,
RefundOrder
refundOrder
,
PayOrder
payOrder
);
/** 调起退款接口,并响应数据; 内部处理普通商户和服务商模式 **/
ChannelRetMsg
refund
(
RefundOrderRQ
bizRQ
,
RefundOrder
refundOrder
,
PayOrder
payOrder
,
MchAppConfigContext
mchAppConfigContext
)
throws
Exception
;
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/AlipayKit.java
浏览文件 @
7e119aa2
...
...
@@ -55,7 +55,7 @@ public class AlipayKit {
else
if
(
req
instanceof
AlipayTradePrecreateRequest
)
((
AlipayTradePrecreateRequest
)
req
).
putOtherTextParam
(
"app_auth_token"
,
isvsubMchParams
.
getAppAuthToken
());
else
if
(
req
instanceof
AlipayTradeWapPayRequest
)
((
AlipayTradeWapPayRequest
)
req
).
putOtherTextParam
(
"app_auth_token"
,
isvsubMchParams
.
getAppAuthToken
());
else
if
(
req
instanceof
AlipayTradeQueryRequest
)
((
AlipayTradeQueryRequest
)
req
).
putOtherTextParam
(
"app_auth_token"
,
isvsubMchParams
.
getAppAuthToken
());
else
if
(
req
instanceof
AlipayTradeRefundRequest
)
((
AlipayTradeRefundRequest
)
req
).
putOtherTextParam
(
"app_auth_token"
,
isvsubMchParams
.
getAppAuthToken
());
// 服务商信息
ExtendParams
extendParams
=
new
ExtendParams
();
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/AlipayRefundService.java
0 → 100644
浏览文件 @
7e119aa2
/*
* Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.channel.alipay
;
import
com.alipay.api.domain.AlipayTradeRefundModel
;
import
com.alipay.api.request.AlipayTradeRefundRequest
;
import
com.alipay.api.response.AlipayTradeRefundResponse
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.entity.RefundOrder
;
import
com.jeequan.jeepay.core.utils.AmountUtil
;
import
com.jeequan.jeepay.pay.channel.AbstractRefundService
;
import
com.jeequan.jeepay.pay.model.MchAppConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ
;
import
org.springframework.stereotype.Service
;
/*
* 退款接口: 支付宝官方
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/17 9:38
*/
@Service
public
class
AlipayRefundService
extends
AbstractRefundService
{
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
ALIPAY
;
}
@Override
public
String
preCheck
(
RefundOrderRQ
bizRQ
,
RefundOrder
refundOrder
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
ChannelRetMsg
refund
(
RefundOrderRQ
bizRQ
,
RefundOrder
refundOrder
,
PayOrder
payOrder
,
MchAppConfigContext
mchAppConfigContext
)
throws
Exception
{
AlipayTradeRefundRequest
request
=
new
AlipayTradeRefundRequest
();
AlipayTradeRefundModel
model
=
new
AlipayTradeRefundModel
();
model
.
setOutTradeNo
(
refundOrder
.
getPayOrderId
());
model
.
setTradeNo
(
refundOrder
.
getChannelPayOrderNo
());
model
.
setOutRequestNo
(
refundOrder
.
getRefundOrderId
());
model
.
setRefundAmount
(
AmountUtil
.
convertCent2Dollar
(
refundOrder
.
getRefundAmount
().
toString
()));
model
.
setRefundReason
(
refundOrder
.
getRefundReason
());
request
.
setBizModel
(
model
);
//统一放置 isv接口必传信息
AlipayKit
.
putApiIsvInfo
(
mchAppConfigContext
,
request
,
model
);
AlipayTradeRefundResponse
response
=
mchAppConfigContext
.
getAlipayClientWrapper
().
execute
(
request
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
channelRetMsg
.
setChannelAttach
(
response
.
getBody
());
channelRetMsg
.
setChannelOrderId
(
response
.
getTradeNo
());
// 调用成功
if
(
response
.
isSuccess
()){
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
);
}
else
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
channelRetMsg
.
setChannelErrCode
(
response
.
getSubCode
());
channelRetMsg
.
setChannelErrMsg
(
response
.
getSubMsg
());
}
return
channelRetMsg
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/ctrl/refund/RefundOrderController.java
浏览文件 @
7e119aa2
...
...
@@ -15,14 +15,18 @@
*/
package
com.jeequan.jeepay.pay.ctrl.refund
;
import
com.jeequan.jeepay.core.entity.*
;
import
com.jeequan.jeepay.core.entity.MchApp
;
import
com.jeequan.jeepay.core.entity.MchInfo
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.entity.RefundOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.core.model.ApiRes
;
import
com.jeequan.jeepay.core.utils.SeqKit
;
import
com.jeequan.jeepay.core.utils.SpringBeansUtil
;
import
com.jeequan.jeepay.core.utils.StringKit
;
import
com.jeequan.jeepay.pay.channel.I
Payment
Service
;
import
com.jeequan.jeepay.pay.channel.I
Refund
Service
;
import
com.jeequan.jeepay.pay.ctrl.ApiController
;
import
com.jeequan.jeepay.pay.exception.ChannelException
;
import
com.jeequan.jeepay.pay.model.MchAppConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.rqrs.refund.RefundOrderRQ
;
...
...
@@ -57,10 +61,14 @@ public class RefundOrderController extends ApiController {
@PostMapping
(
"/api/refund/refundOrder"
)
public
ApiRes
refundOrder
(){
RefundOrder
refundOrder
=
null
;
//获取参数 & 验签
RefundOrderRQ
rq
=
getRQByWithMchSign
(
RefundOrderRQ
.
class
);
try
{
//获取参数 & 验签
RefundOrderRQ
rq
=
getRQByWithMchSign
(
RefundOrderRQ
.
class
);
if
(
StringUtils
.
isAllEmpty
(
rq
.
getMchOrderNo
(),
rq
.
getPayOrderId
())){
throw
new
BizException
(
"mchOrderNo 和 payOrderId不能同时为空"
);
...
...
@@ -68,13 +76,39 @@ public class RefundOrderController extends ApiController {
PayOrder
payOrder
=
payOrderService
.
queryMchOrder
(
rq
.
getMchNo
(),
rq
.
getPayOrderId
(),
rq
.
getMchOrderNo
());
if
(
payOrder
==
null
){
throw
new
BizException
(
"订单不存在"
);
throw
new
BizException
(
"退款订单不存在"
);
}
if
(
payOrder
.
getState
()
!=
PayOrder
.
STATE_SUCCESS
){
throw
new
BizException
(
"订单状态不正确, 无法完成退款"
);
}
if
(
payOrder
.
getRefundState
()
==
PayOrder
.
REFUND_STATE_ALL
||
payOrder
.
getRefundAmount
()
>=
payOrder
.
getAmount
()){
throw
new
BizException
(
"订单已全额退款,本次申请失败"
);
}
if
(
payOrder
.
getRefundAmount
()
+
rq
.
getRefundAmount
()
>
payOrder
.
getAmount
()){
throw
new
BizException
(
"申请金额超出订单可退款余额,请检查退款金额"
);
}
if
(
refundOrderService
.
count
(
RefundOrder
.
gw
().
eq
(
RefundOrder:
:
getPayOrderId
,
payOrder
.
getPayOrderId
()).
eq
(
RefundOrder:
:
getState
,
RefundOrder
.
STATE_ING
))
>
0
){
throw
new
BizException
(
"支付订单具有在途退款申请,请稍后再试"
);
}
//全部退款金额 (退款订单表)
Long
sumSuccessRefundAmount
=
refundOrderService
.
getBaseMapper
().
sumSuccessRefundAmount
(
payOrder
.
getPayOrderId
());
if
(
sumSuccessRefundAmount
>=
payOrder
.
getAmount
()){
throw
new
BizException
(
"退款单已完成全部订单退款,本次申请失败"
);
}
if
(
sumSuccessRefundAmount
+
rq
.
getRefundAmount
()
>
payOrder
.
getAmount
()){
throw
new
BizException
(
"申请金额超出订单可退款余额,请检查退款金额"
);
}
String
mchNo
=
rq
.
getMchNo
();
String
appId
=
rq
.
getAppId
();
//
只有新订单模式,进行校验
//
校验退款单号是否重复
if
(
refundOrderService
.
count
(
RefundOrder
.
gw
().
eq
(
RefundOrder:
:
getMchNo
,
mchNo
).
eq
(
RefundOrder:
:
getMchRefundNo
,
rq
.
getMchRefundNo
()))
>
0
){
throw
new
BizException
(
"商户退款订单号["
+
rq
.
getMchRefundNo
()+
"]已存在"
);
}
...
...
@@ -93,33 +127,44 @@ public class RefundOrderController extends ApiController {
MchApp
mchApp
=
mchAppConfigContext
.
getMchApp
();
//获取支付接口
// 接口代码 TODO
IPaymentService
paymentService
=
SpringBeansUtil
.
getBean
(
payOrder
.
getIfCode
()
+
"PaymentService"
,
IPaymentService
.
class
);
if
(
paymentService
==
null
){
//获取退款接口
IRefundService
refundService
=
SpringBeansUtil
.
getBean
(
payOrder
.
getIfCode
()
+
"RefundService"
,
IRefundService
.
class
);
if
(
refundService
==
null
){
throw
new
BizException
(
"当前通道不支持退款!"
);
}
refundOrder
=
genRefundOrder
(
rq
,
payOrder
,
mchInfo
,
mchApp
);
RefundOrder
refundOrder
=
genRefundOrder
(
rq
,
payOrder
,
mchInfo
,
mchApp
);
//订单入库 订单状态: 生成状态 此时没有和任何上游渠道产生交互。
//退款单入库 退款单状态:生成状态 此时没有和任何上游渠道产生交互。
refundOrderService
.
save
(
refundOrder
);
//调起上游支付接口
// bizRS = (UnifiedOrderRS) paymentService.pay(bizRQ, payOrder, mchAppConfigContext);
// 调起退款接口
ChannelRetMsg
channelRetMsg
=
null
;
ChannelRetMsg
channelRetMsg
=
refundService
.
refund
(
rq
,
refundOrder
,
payOrder
,
mchAppConfigContext
);
//处理退款单状态
this
.
processChannelMsg
(
channelRetMsg
,
refundOrder
);
RefundOrderRS
bizRes
=
RefundOrderRS
.
buildByRefundOrder
(
refundOrder
);
return
ApiRes
.
okWithSign
(
bizRes
,
configContextService
.
getMchAppConfigContext
(
rq
.
getMchNo
(),
rq
.
getAppId
()).
getMchApp
().
getAppSecret
());
}
catch
(
BizException
e
)
{
return
ApiRes
.
customFail
(
e
.
getMessage
());
}
catch
(
ChannelException
e
)
{
//处理上游返回数据
this
.
processChannelMsg
(
e
.
getChannelRetMsg
(),
refundOrder
);
if
(
e
.
getChannelRetMsg
().
getChannelState
()
==
ChannelRetMsg
.
ChannelState
.
SYS_ERROR
){
return
ApiRes
.
customFail
(
e
.
getMessage
());
}
RefundOrderRS
bizRes
=
RefundOrderRS
.
buildByRefundOrder
(
refundOrder
);
return
ApiRes
.
okWithSign
(
bizRes
,
configContextService
.
getMchAppConfigContext
(
rq
.
getMchNo
(),
rq
.
getAppId
()).
getMchApp
().
getAppSecret
());
}
catch
(
Exception
e
)
{
log
.
error
(
"系统异常:{}"
,
e
);
return
ApiRes
.
customFail
(
"系统异常"
);
...
...
@@ -160,38 +205,36 @@ public class RefundOrderController extends ApiController {
}
/** 处理返回的渠道信息,并更新
订
单状态
/** 处理返回的渠道信息,并更新
退款
单状态
* payOrder将对部分信息进行 赋值操作。
* **/
private
void
processChannelMsg
(
ChannelRetMsg
channelRetMsg
,
PayOrder
pay
Order
){
private
void
processChannelMsg
(
ChannelRetMsg
channelRetMsg
,
RefundOrder
refund
Order
){
//对象为空 || 上游返回状态为空, 则无需操作
if
(
channelRetMsg
==
null
||
channelRetMsg
.
getChannelState
()
==
null
){
return
;
}
String
payOrderId
=
payOrder
.
getPayOrderId
();
//明确成功
if
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
==
channelRetMsg
.
getChannelState
())
{
this
.
updateInitOrderStateThrowException
(
PayOrder
.
STATE_SUCCESS
,
pay
Order
,
channelRetMsg
);
this
.
updateInitOrderStateThrowException
(
RefundOrder
.
STATE_SUCCESS
,
refund
Order
,
channelRetMsg
);
// payMchNotifyService.payOrderNotify(payOrder);
//明确失败
}
else
if
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
==
channelRetMsg
.
getChannelState
())
{
this
.
updateInitOrderStateThrowException
(
PayOrder
.
STATE_FAIL
,
pay
Order
,
channelRetMsg
);
this
.
updateInitOrderStateThrowException
(
RefundOrder
.
STATE_FAIL
,
refund
Order
,
channelRetMsg
);
// 上游处理中 || 未知 || 上游接口返回异常
订单为支付
中状态
// 上游处理中 || 未知 || 上游接口返回异常
退款单为退款
中状态
}
else
if
(
ChannelRetMsg
.
ChannelState
.
WAITING
==
channelRetMsg
.
getChannelState
()
||
ChannelRetMsg
.
ChannelState
.
UNKNOWN
==
channelRetMsg
.
getChannelState
()
||
ChannelRetMsg
.
ChannelState
.
API_RET_ERROR
==
channelRetMsg
.
getChannelState
()
){
this
.
updateInitOrderStateThrowException
(
PayOrder
.
STATE_ING
,
pay
Order
,
channelRetMsg
);
this
.
updateInitOrderStateThrowException
(
RefundOrder
.
STATE_ING
,
refund
Order
,
channelRetMsg
);
// 系统异常:
订
单不再处理。 为: 生成状态
// 系统异常:
退款
单不再处理。 为: 生成状态
}
else
if
(
ChannelRetMsg
.
ChannelState
.
SYS_ERROR
==
channelRetMsg
.
getChannelState
()){
}
else
{
...
...
@@ -199,34 +242,28 @@ public class RefundOrderController extends ApiController {
throw
new
BizException
(
"ChannelState 返回异常!"
);
}
//判断是否需要轮询查单
if
(
channelRetMsg
.
isNeedQuery
()){
// mqChannelOrderQueryQueue.send(MqQueue4ChannelOrderQuery.buildMsg(payOrderId, 1), 5 * 1000);
}
}
/** 更新
订单状态 --》 订
单生成--》 其他状态 (向外抛出异常) **/
private
void
updateInitOrderStateThrowException
(
byte
orderState
,
PayOrder
pay
Order
,
ChannelRetMsg
channelRetMsg
){
/** 更新
退款单状态 --》 退款
单生成--》 其他状态 (向外抛出异常) **/
private
void
updateInitOrderStateThrowException
(
byte
orderState
,
RefundOrder
refund
Order
,
ChannelRetMsg
channelRetMsg
){
pay
Order
.
setState
(
orderState
);
pay
Order
.
setChannelOrderNo
(
channelRetMsg
.
getChannelOrderId
());
payOrder
.
set
ErrCode
(
channelRetMsg
.
getChannelErrCode
());
payOrder
.
set
ErrMsg
(
channelRetMsg
.
getChannelErrMsg
());
refund
Order
.
setState
(
orderState
);
refund
Order
.
setChannelOrderNo
(
channelRetMsg
.
getChannelOrderId
());
refundOrder
.
setChannel
ErrCode
(
channelRetMsg
.
getChannelErrCode
());
refundOrder
.
setChannel
ErrMsg
(
channelRetMsg
.
getChannelErrMsg
());
boolean
isSuccess
=
payOrderService
.
updateInit2Ing
(
payOrder
.
getPayOrderId
(),
payOrder
.
getIfCode
(),
payOrder
.
getWayCode
());
boolean
isSuccess
=
refundOrderService
.
updateInit2Ing
(
refundOrder
.
getRefundOrderId
());
if
(!
isSuccess
){
throw
new
BizException
(
"更新
订
单异常!"
);
throw
new
BizException
(
"更新
退款
单异常!"
);
}
isSuccess
=
payOrderService
.
updateIng2SuccessOrFail
(
payOrder
.
getPayOrderId
(),
pay
Order
.
getState
(),
isSuccess
=
refundOrderService
.
updateIng2SuccessOrFail
(
refundOrder
.
getRefundOrderId
(),
refund
Order
.
getState
(),
channelRetMsg
.
getChannelOrderId
(),
channelRetMsg
.
getChannelErrCode
(),
channelRetMsg
.
getChannelErrMsg
());
if
(!
isSuccess
){
throw
new
BizException
(
"更新
订
单异常!"
);
throw
new
BizException
(
"更新
退款
单异常!"
);
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/exception/ChannelException.java
浏览文件 @
7e119aa2
...
...
@@ -41,7 +41,7 @@ public class ChannelException extends RuntimeException{
/** 未知状态 **/
public
static
ChannelException
unknown
(
String
channelErrMsg
){
return
new
ChannelException
(
ChannelRetMsg
.
sysError
(
channelErrMsg
));
return
new
ChannelException
(
ChannelRetMsg
.
unknown
(
channelErrMsg
));
}
/** 系统内异常 **/
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/msg/ChannelRetMsg.java
浏览文件 @
7e119aa2
...
...
@@ -113,6 +113,11 @@ public class ChannelRetMsg implements Serializable {
return
new
ChannelRetMsg
(
ChannelState
.
UNKNOWN
,
null
,
null
,
null
);
}
/** 状态未知的情况 **/
public
static
ChannelRetMsg
unknown
(
String
channelErrMsg
){
return
new
ChannelRetMsg
(
ChannelState
.
UNKNOWN
,
null
,
null
,
channelErrMsg
);
}
}
...
...
jeepay-service/src/main/java/com/jeequan/jeepay/service/impl/RefundOrderService.java
浏览文件 @
7e119aa2
...
...
@@ -15,10 +15,17 @@
*/
package
com.jeequan.jeepay.service.impl
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.jeequan.jeepay.core.entity.RefundOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.service.mapper.PayOrderMapper
;
import
com.jeequan.jeepay.service.mapper.RefundOrderMapper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.Date
;
/**
* <p>
...
...
@@ -31,4 +38,74 @@ import org.springframework.stereotype.Service;
@Service
public
class
RefundOrderService
extends
ServiceImpl
<
RefundOrderMapper
,
RefundOrder
>
{
@Autowired
private
PayOrderMapper
payOrderMapper
;
/** 更新退款单状态 【退款单生成】 --》 【退款中】 **/
public
boolean
updateInit2Ing
(
String
refundOrderId
){
RefundOrder
updateRecord
=
new
RefundOrder
();
updateRecord
.
setState
(
RefundOrder
.
STATE_ING
);
return
update
(
updateRecord
,
new
LambdaUpdateWrapper
<
RefundOrder
>()
.
eq
(
RefundOrder:
:
getRefundOrderId
,
refundOrderId
).
eq
(
RefundOrder:
:
getState
,
RefundOrder
.
STATE_INIT
));
}
/** 更新退款单状态 【退款中】 --》 【退款成功】 **/
@Transactional
public
boolean
updateIng2Success
(
String
refundOrderId
,
String
channelOrderNo
){
RefundOrder
updateRecord
=
new
RefundOrder
();
updateRecord
.
setState
(
RefundOrder
.
STATE_SUCCESS
);
updateRecord
.
setChannelOrderNo
(
channelOrderNo
);
updateRecord
.
setSuccessTime
(
new
Date
());
//1. 更新退款订单表数据
if
(!
update
(
updateRecord
,
new
LambdaUpdateWrapper
<
RefundOrder
>()
.
eq
(
RefundOrder:
:
getRefundOrderId
,
refundOrderId
).
eq
(
RefundOrder:
:
getState
,
RefundOrder
.
STATE_ING
))
){
return
false
;
}
//2. 更新订单表数据
RefundOrder
refundOrder
=
getOne
(
RefundOrder
.
gw
().
select
(
RefundOrder:
:
getPayOrderId
,
RefundOrder:
:
getRefundAmount
).
eq
(
RefundOrder:
:
getRefundOrderId
,
refundOrderId
));
int
updateCount
=
payOrderMapper
.
updateRefundAmountAndCount
(
refundOrder
.
getPayOrderId
(),
refundOrder
.
getRefundAmount
());
if
(
updateCount
<=
0
){
throw
new
BizException
(
"更新订单数据异常"
);
}
return
true
;
}
/** 更新退款单状态 【退款中】 --》 【退款失败】 **/
@Transactional
public
boolean
updateIng2Fail
(
String
refundOrderId
,
String
channelOrderNo
,
String
channelErrCode
,
String
channelErrMsg
){
RefundOrder
updateRecord
=
new
RefundOrder
();
updateRecord
.
setState
(
RefundOrder
.
STATE_FAIL
);
updateRecord
.
setChannelErrCode
(
channelErrCode
);
updateRecord
.
setChannelErrMsg
(
channelErrMsg
);
updateRecord
.
setChannelOrderNo
(
channelOrderNo
);
return
update
(
updateRecord
,
new
LambdaUpdateWrapper
<
RefundOrder
>()
.
eq
(
RefundOrder:
:
getRefundOrderId
,
refundOrderId
).
eq
(
RefundOrder:
:
getState
,
RefundOrder
.
STATE_ING
));
}
/** 更新退款单状态 【退款中】 --》 【退款成功/退款失败】 **/
@Transactional
public
boolean
updateIng2SuccessOrFail
(
String
refundOrderId
,
Byte
updateState
,
String
channelOrderNo
,
String
channelErrCode
,
String
channelErrMsg
){
if
(
updateState
==
RefundOrder
.
STATE_ING
){
return
true
;
}
else
if
(
updateState
==
RefundOrder
.
STATE_SUCCESS
){
return
updateIng2Success
(
refundOrderId
,
channelOrderNo
);
}
else
if
(
updateState
==
RefundOrder
.
STATE_FAIL
){
return
updateIng2Fail
(
refundOrderId
,
channelOrderNo
,
channelErrCode
,
channelErrMsg
);
}
return
false
;
}
}
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.java
浏览文件 @
7e119aa2
...
...
@@ -17,6 +17,7 @@ package com.jeequan.jeepay.service.mapper;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -38,4 +39,7 @@ public interface PayOrderMapper extends BaseMapper<PayOrder> {
Map
selectTotalCount
(
Map
param
);
List
<
Map
>
selectOrderCount
(
Map
param
);
/** 更新订单退款金额和次数 **/
int
updateRefundAmountAndCount
(
@Param
(
"payOrderId"
)
String
payOrderId
,
@Param
(
"currentRefundAmount"
)
Long
currentRefundAmount
);
}
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.xml
浏览文件 @
7e119aa2
...
...
@@ -23,6 +23,7 @@
<result
column=
"channel_extra"
property=
"channelExtra"
/>
<result
column=
"channel_user"
property=
"channelUser"
/>
<result
column=
"channel_order_no"
property=
"channelOrderNo"
/>
<result
column=
"refund_state"
property=
"refundState"
/>
<result
column=
"refund_times"
property=
"refundTimes"
/>
<result
column=
"refund_amount"
property=
"refundAmount"
/>
<result
column=
"division_flag"
property=
"divisionFlag"
/>
...
...
@@ -86,4 +87,19 @@
GROUP BY groupDate
ORDER BY groupDate desc
</select>
<!-- 更新订单退款金额和次数 -->
<update
id=
"updateRefundAmountAndCount"
>
update t_pay_order
set refund_times = refund_times + 1,
<!-- 退款次数 +1 -->
refund_state = CASE WHEN refund_amount + #{currentRefundAmount} >= amount THEN 2 ELSE 1 END,
<!-- 更新是否已全额退款。 此更新需在refund_amount更新之前,否则需要去掉累加逻辑 -->
refund_amount = refund_amount + #{currentRefundAmount}
<!-- 退款金额累加 -->
where
pay_order_id = #{payOrderId} and `state` = 2
<!-- 订单号 & 成功状态的可退款 -->
and refund_amount + #{currentRefundAmount}
<
= amount
<!-- 已退款金额 + 本次退款金额 小于等于订单金额 -->
and refund_state in (0, 1)
<!-- 只有未发生退款和部分退款可退 -->
</update>
</mapper>
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/RefundOrderMapper.java
浏览文件 @
7e119aa2
...
...
@@ -28,4 +28,7 @@ import com.jeequan.jeepay.core.entity.RefundOrder;
*/
public
interface
RefundOrderMapper
extends
BaseMapper
<
RefundOrder
>
{
/** 查询全部退成功金额 **/
Long
sumSuccessRefundAmount
(
String
payOrderId
);
}
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/RefundOrderMapper.xml
浏览文件 @
7e119aa2
...
...
@@ -32,4 +32,9 @@
<result
column=
"updated_at"
property=
"updatedAt"
/>
</resultMap>
<select
id=
"sumSuccessRefundAmount"
resultType=
"Long"
>
select ifnull(sum(refund_amount), 0) from t_refund_order
where pay_order_id = #{payOrderId} and state = 2
</select>
</mapper>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录