Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Jeepay
Commits
43e2669d
Commit
43e2669d
authored
Feb 17, 2023
by
zhuxiao
Browse files
新增查询转账单状态,对接支付宝、微信转账查询接口
parent
a4e4c990
Changes
5
Hide whitespace changes
Inline
Side-by-side
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/ITransferService.java
View file @
43e2669d
...
...
@@ -41,4 +41,7 @@ public interface ITransferService {
/** 调起退款接口,并响应数据; 内部处理普通商户和服务商模式 **/
ChannelRetMsg
transfer
(
TransferOrderRQ
bizRQ
,
TransferOrder
refundOrder
,
MchAppConfigContext
mchAppConfigContext
)
throws
Exception
;
/** 调起转账查询接口 **/
ChannelRetMsg
query
(
TransferOrder
transferOrder
,
MchAppConfigContext
mchAppConfigContext
);
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/AlipayTransferService.java
View file @
43e2669d
...
...
@@ -15,9 +15,12 @@
*/
package
com.jeequan.jeepay.pay.channel.alipay
;
import
com.alipay.api.domain.AlipayFundTransCommonQueryModel
;
import
com.alipay.api.domain.AlipayFundTransUniTransferModel
;
import
com.alipay.api.domain.Participant
;
import
com.alipay.api.request.AlipayFundTransCommonQueryRequest
;
import
com.alipay.api.request.AlipayFundTransUniTransferRequest
;
import
com.alipay.api.response.AlipayFundTransCommonQueryResponse
;
import
com.alipay.api.response.AlipayFundTransUniTransferResponse
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.TransferOrder
;
...
...
@@ -98,8 +101,17 @@ public class AlipayTransferService implements ITransferService {
// 调用成功
if
(
response
.
isSuccess
()){
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
);
channelRetMsg
.
setChannelOrderId
(
response
.
getOrderId
());
if
(
"SUCCESS"
.
equals
(
response
.
getStatus
()))
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
);
channelRetMsg
.
setChannelOrderId
(
response
.
getOrderId
());
}
else
if
(
"FAIL"
.
equals
(
response
.
getStatus
()))
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
channelRetMsg
.
setChannelErrCode
(
AlipayKit
.
appendErrCode
(
response
.
getCode
(),
response
.
getSubCode
()));
channelRetMsg
.
setChannelErrMsg
(
AlipayKit
.
appendErrMsg
(
response
.
getMsg
(),
response
.
getSubMsg
()));
}
else
{
return
ChannelRetMsg
.
waiting
();
}
}
else
{
//若 系统繁忙, 无法确认结果
...
...
@@ -115,4 +127,38 @@ public class AlipayTransferService implements ITransferService {
return
channelRetMsg
;
}
@Override
public
ChannelRetMsg
query
(
TransferOrder
transferOrder
,
MchAppConfigContext
mchAppConfigContext
)
{
AlipayFundTransCommonQueryRequest
request
=
new
AlipayFundTransCommonQueryRequest
();
AlipayFundTransCommonQueryModel
model
=
new
AlipayFundTransCommonQueryModel
();
model
.
setProductCode
(
TransferOrder
.
ENTRY_BANK_CARD
.
equals
(
transferOrder
.
getEntryType
())
?
"TRANS_BANKCARD_NO_PWD"
:
"TRANS_ACCOUNT_NO_PWD"
);
model
.
setBizScene
(
"DIRECT_TRANSFER"
);
model
.
setOutBizNo
(
transferOrder
.
getTransferId
());
// 商户转账唯一订单号
AlipayKit
.
putApiIsvInfo
(
mchAppConfigContext
,
request
,
model
);
request
.
setBizModel
(
model
);
// 调起支付宝接口
AlipayFundTransCommonQueryResponse
response
=
configContextQueryService
.
getAlipayClientWrapper
(
mchAppConfigContext
).
execute
(
request
);
if
(
response
.
isSuccess
())
{
// SUCCESS,明确成功
if
(
"SUCCESS"
.
equalsIgnoreCase
(
response
.
getStatus
())){
return
ChannelRetMsg
.
confirmSuccess
(
response
.
getOrderId
());
}
// REFUND:退票(适用于"单笔转账到银行卡"); FAIL:失败(适用于"单笔转账到银行卡")
else
if
(
"REFUND"
.
equalsIgnoreCase
(
response
.
getStatus
())
||
"FAIL"
.
equalsIgnoreCase
(
response
.
getStatus
())){
return
ChannelRetMsg
.
confirmFail
(
response
.
getErrorCode
(),
response
.
getFailReason
());
}
else
{
return
ChannelRetMsg
.
waiting
();
}
}
else
{
// 如果查询单号对应的数据不存在,那么数据不存在的原因可能是:(1)付款还在处理中;(2)付款处理失败导致付款订单没有落地,务必再次查询确认此次付款的结果。
if
(
"ORDER_NOT_EXIST"
.
equalsIgnoreCase
(
response
.
getSubCode
())){
return
ChannelRetMsg
.
waiting
();
}
return
ChannelRetMsg
.
confirmFail
(
AlipayKit
.
appendErrCode
(
response
.
getCode
(),
response
.
getSubCode
()),
AlipayKit
.
appendErrMsg
(
response
.
getMsg
(),
response
.
getSubMsg
()));
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/WxpayTransferService.java
View file @
43e2669d
...
...
@@ -15,8 +15,11 @@
*/
package
com.jeequan.jeepay.pay.channel.wxpay
;
import
com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest
;
import
com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult
;
import
com.github.binarywang.wxpay.bean.entpay.EntPayRequest
;
import
com.github.binarywang.wxpay.bean.entpay.EntPayResult
;
import
com.github.binarywang.wxpay.bean.transfer.TransferBatchDetailResult
;
import
com.github.binarywang.wxpay.bean.transfer.TransferBatchesRequest
;
import
com.github.binarywang.wxpay.bean.transfer.TransferBatchesResult
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
...
...
@@ -110,13 +113,8 @@ public class WxpayTransferService implements ITransferService {
}
EntPayResult
entPayResult
=
wxServiceWrapper
.
getWxPayService
().
getEntPayService
().
entPay
(
request
);
return
ChannelRetMsg
.
waiting
();
// SUCCESS/FAIL,注意:当状态为FAIL时,存在业务结果未明确的情况。如果状态为FAIL,请务必关注错误代码(err_code字段),通过查询接口确认此次付款的结果。
if
(
"SUCCESS"
.
equalsIgnoreCase
(
entPayResult
.
getResultCode
())){
return
ChannelRetMsg
.
confirmSuccess
(
entPayResult
.
getPaymentNo
());
}
else
{
return
ChannelRetMsg
.
waiting
();
}
}
else
if
(
CS
.
PAY_IF_VERSION
.
WX_V3
.
equals
(
wxServiceWrapper
.
getApiVersion
()))
{
TransferBatchesRequest
request
=
new
TransferBatchesRequest
();
request
.
setAppid
(
wxServiceWrapper
.
getWxPayService
().
getConfig
().
getAppId
());
...
...
@@ -137,7 +135,7 @@ public class WxpayTransferService implements ITransferService {
request
.
setTransferDetailList
(
list
);
TransferBatchesResult
transferBatchesResult
=
wxServiceWrapper
.
getWxPayService
().
getTransferService
().
transferBatches
(
request
);
return
ChannelRetMsg
.
confirmSuccess
(
transferBatchesResult
.
getBatchId
()
);
return
ChannelRetMsg
.
waiting
(
);
}
else
{
return
ChannelRetMsg
.
sysError
(
"请选择微信V2或V3模式"
);
}
...
...
@@ -159,4 +157,56 @@ public class WxpayTransferService implements ITransferService {
}
}
@Override
public
ChannelRetMsg
query
(
TransferOrder
transferOrder
,
MchAppConfigContext
mchAppConfigContext
)
{
try
{
WxServiceWrapper
wxServiceWrapper
=
configContextQueryService
.
getWxServiceWrapper
(
mchAppConfigContext
);
if
(
CS
.
PAY_IF_VERSION
.
WX_V2
.
equals
(
wxServiceWrapper
.
getApiVersion
()))
{
//V2
EntPayQueryResult
entPayQueryResult
=
wxServiceWrapper
.
getWxPayService
().
getEntPayService
().
queryEntPay
(
transferOrder
.
getTransferId
());
// SUCCESS,明确成功
if
(
"SUCCESS"
.
equalsIgnoreCase
(
entPayQueryResult
.
getStatus
())){
return
ChannelRetMsg
.
confirmSuccess
(
entPayQueryResult
.
getDetailId
());
}
else
if
(
"FAILED"
.
equalsIgnoreCase
(
entPayQueryResult
.
getStatus
())){
// FAILED,明确失败
return
ChannelRetMsg
.
confirmFail
(
entPayQueryResult
.
getStatus
(),
entPayQueryResult
.
getReason
());
}
else
{
return
ChannelRetMsg
.
waiting
();
}
}
else
if
(
CS
.
PAY_IF_VERSION
.
WX_V3
.
equals
(
wxServiceWrapper
.
getApiVersion
()))
{
TransferBatchDetailResult
transferBatchDetailResult
=
wxServiceWrapper
.
getWxPayService
().
getTransferService
().
transferBatchesOutBatchNoDetail
(
transferOrder
.
getTransferId
(),
transferOrder
.
getTransferId
());
// SUCCESS,明确成功
if
(
"SUCCESS"
.
equalsIgnoreCase
(
transferBatchDetailResult
.
getDetailStatus
())){
return
ChannelRetMsg
.
confirmSuccess
(
transferBatchDetailResult
.
getDetailId
());
}
else
if
(
"FAIL"
.
equalsIgnoreCase
(
transferBatchDetailResult
.
getDetailStatus
())){
// FAIL,明确失败
return
ChannelRetMsg
.
confirmFail
(
transferBatchDetailResult
.
getDetailStatus
(),
transferBatchDetailResult
.
getFailReason
());
}
else
{
return
ChannelRetMsg
.
waiting
();
}
}
else
{
return
ChannelRetMsg
.
sysError
(
"请选择微信V2或V3模式"
);
}
}
catch
(
WxPayException
e
)
{
// 如果查询单号对应的数据不存在,那么数据不存在的原因可能是:(1)付款还在处理中;(2)付款处理失败导致付款订单没有落地,务必再次查询确认此次付款的结果。
if
(
"NOT_FOUND"
.
equalsIgnoreCase
(
e
.
getErrCode
())){
return
ChannelRetMsg
.
waiting
();
}
return
ChannelRetMsg
.
confirmFail
(
null
,
WxpayKit
.
appendErrCode
(
e
.
getReturnMsg
(),
e
.
getErrCode
()),
WxpayKit
.
appendErrMsg
(
e
.
getReturnMsg
(),
StringUtils
.
defaultIfEmpty
(
e
.
getErrCodeDes
(),
e
.
getCustomErrorMsg
())));
}
catch
(
Exception
e
)
{
log
.
error
(
"转账状态查询异常:"
,
e
);
return
ChannelRetMsg
.
waiting
();
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/service/TransferOrderReissueService.java
0 → 100644
View file @
43e2669d
/*
* 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.service
;
import
com.jeequan.jeepay.core.entity.TransferOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.core.utils.SpringBeansUtil
;
import
com.jeequan.jeepay.pay.channel.ITransferService
;
import
com.jeequan.jeepay.pay.model.MchAppConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.service.impl.TransferOrderService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
/*
* 转账补单服务实现类
*
* @author zx
* @site https://www.jeequan.com
* @date 2022/12/29 17:47
*/
@Service
@Slf4j
public
class
TransferOrderReissueService
{
@Autowired
private
ConfigContextQueryService
configContextQueryService
;
@Autowired
private
TransferOrderService
transferOrderService
;
@Autowired
private
PayMchNotifyService
payMchNotifyService
;
/** 处理转账订单 **/
public
ChannelRetMsg
processOrder
(
TransferOrder
transferOrder
){
try
{
String
transferId
=
transferOrder
.
getTransferId
();
// 查询转账接口是否存在
ITransferService
transferService
=
SpringBeansUtil
.
getBean
(
transferOrder
.
getIfCode
()
+
"TransferService"
,
ITransferService
.
class
);
// 支付通道转账接口实现不存在
if
(
transferService
==
null
){
log
.
error
(
"{} interface not exists!"
,
transferOrder
.
getIfCode
());
return
null
;
}
// 查询出商户应用的配置信息
MchAppConfigContext
mchAppConfigContext
=
configContextQueryService
.
queryMchInfoAndAppInfo
(
transferOrder
.
getMchNo
(),
transferOrder
.
getAppId
());
ChannelRetMsg
channelRetMsg
=
transferService
.
query
(
transferOrder
,
mchAppConfigContext
);
if
(
channelRetMsg
==
null
){
log
.
error
(
"channelRetMsg is null"
);
return
null
;
}
log
.
info
(
"补单[{}]查询结果为:{}"
,
transferId
,
channelRetMsg
);
// 查询成功
if
(
channelRetMsg
.
getChannelState
()
==
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
)
{
// 转账成功
transferOrderService
.
updateIng2Success
(
transferId
,
channelRetMsg
.
getChannelOrderId
());
payMchNotifyService
.
transferOrderNotify
(
transferOrderService
.
getById
(
transferId
));
}
else
if
(
channelRetMsg
.
getChannelState
()
==
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
){
// 转账失败
transferOrderService
.
updateIng2Fail
(
transferId
,
channelRetMsg
.
getChannelOrderId
(),
channelRetMsg
.
getChannelUserId
(),
channelRetMsg
.
getChannelErrCode
());
payMchNotifyService
.
transferOrderNotify
(
transferOrderService
.
getById
(
transferId
));
}
return
channelRetMsg
;
}
catch
(
Exception
e
)
{
//继续下一次迭代查询
log
.
error
(
"error transferId = {}"
,
transferOrder
.
getTransferId
(),
e
);
return
null
;
}
}
/**
* 处理返回的渠道信息,并更新订单状态
* TransferOrder将对部分信息进行 赋值操作。
* **/
public
void
processChannelMsg
(
ChannelRetMsg
channelRetMsg
,
TransferOrder
transferOrder
){
//对象为空 || 上游返回状态为空, 则无需操作
if
(
channelRetMsg
==
null
||
channelRetMsg
.
getChannelState
()
==
null
){
return
;
}
//明确成功
if
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
==
channelRetMsg
.
getChannelState
())
{
this
.
updateInitOrderStateThrowException
(
TransferOrder
.
STATE_SUCCESS
,
transferOrder
,
channelRetMsg
);
payMchNotifyService
.
transferOrderNotify
(
transferOrderService
.
getById
(
transferOrder
.
getTransferId
()));
//明确失败
}
else
if
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
==
channelRetMsg
.
getChannelState
())
{
this
.
updateInitOrderStateThrowException
(
TransferOrder
.
STATE_FAIL
,
transferOrder
,
channelRetMsg
);
payMchNotifyService
.
transferOrderNotify
(
transferOrderService
.
getById
(
transferOrder
.
getTransferId
()));
// 上游处理中 || 未知 || 上游接口返回异常 订单为支付中状态
}
else
if
(
ChannelRetMsg
.
ChannelState
.
WAITING
==
channelRetMsg
.
getChannelState
()
||
ChannelRetMsg
.
ChannelState
.
UNKNOWN
==
channelRetMsg
.
getChannelState
()
||
ChannelRetMsg
.
ChannelState
.
API_RET_ERROR
==
channelRetMsg
.
getChannelState
()
){
this
.
updateInitOrderStateThrowException
(
TransferOrder
.
STATE_ING
,
transferOrder
,
channelRetMsg
);
// 系统异常: 订单不再处理。 为: 生成状态
}
else
if
(
ChannelRetMsg
.
ChannelState
.
SYS_ERROR
==
channelRetMsg
.
getChannelState
()){
}
else
{
throw
new
BizException
(
"ChannelState 返回异常!"
);
}
}
/** 更新转账单状态 --》 转账单生成--》 其他状态 (向外抛出异常) **/
private
void
updateInitOrderStateThrowException
(
byte
orderState
,
TransferOrder
transferOrder
,
ChannelRetMsg
channelRetMsg
){
transferOrder
.
setState
(
orderState
);
transferOrder
.
setChannelOrderNo
(
channelRetMsg
.
getChannelOrderId
());
transferOrder
.
setErrCode
(
channelRetMsg
.
getChannelErrCode
());
transferOrder
.
setErrMsg
(
channelRetMsg
.
getChannelErrMsg
());
boolean
isSuccess
=
transferOrderService
.
updateInit2Ing
(
transferOrder
.
getTransferId
());
if
(!
isSuccess
){
throw
new
BizException
(
"更新转账单异常!"
);
}
isSuccess
=
transferOrderService
.
updateIng2SuccessOrFail
(
transferOrder
.
getTransferId
(),
transferOrder
.
getState
(),
channelRetMsg
.
getChannelOrderId
(),
channelRetMsg
.
getChannelErrCode
(),
channelRetMsg
.
getChannelErrMsg
());
if
(!
isSuccess
){
throw
new
BizException
(
"更新转账订单异常!"
);
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/task/TransferOrderReissueTask.java
0 → 100644
View file @
43e2669d
/*
* 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.task
;
import
cn.hutool.core.date.DateUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.jeequan.jeepay.core.entity.TransferOrder
;
import
com.jeequan.jeepay.pay.service.TransferOrderReissueService
;
import
com.jeequan.jeepay.service.impl.TransferOrderService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Component
;
import
java.util.Date
;
/*
* 转账补单定时任务
*
* @author zx
* @site https://www.jeequan.com
* @date 2022/12/29 17:47
*/
@Slf4j
@Component
public
class
TransferOrderReissueTask
{
private
static
final
int
QUERY_PAGE_SIZE
=
100
;
//每次查询数量
@Autowired
private
TransferOrderService
transferOrderService
;
@Autowired
private
TransferOrderReissueService
transferOrderReissueService
;
@Scheduled
(
cron
=
"0 0/1 * * * ?"
)
// 每分钟执行一次
public
void
start
()
{
//查询条件:
LambdaQueryWrapper
<
TransferOrder
>
lambdaQueryWrapper
=
TransferOrder
.
gw
()
.
eq
(
TransferOrder:
:
getState
,
TransferOrder
.
STATE_ING
)
// 转账中
.
ge
(
TransferOrder:
:
getCreatedAt
,
DateUtil
.
offsetDay
(
new
Date
(),
-
1
));
// 只查询一天内的转账单;
int
currentPageIndex
=
1
;
//当前页码
while
(
true
){
try
{
IPage
<
TransferOrder
>
iPage
=
transferOrderService
.
page
(
new
Page
(
currentPageIndex
,
QUERY_PAGE_SIZE
),
lambdaQueryWrapper
);
if
(
iPage
==
null
||
iPage
.
getRecords
().
isEmpty
()){
//本次查询无结果, 不再继续查询;
break
;
}
for
(
TransferOrder
transferOrder:
iPage
.
getRecords
()){
transferOrderReissueService
.
processOrder
(
transferOrder
);
}
//已经到达页码最大量,无需再次查询
if
(
iPage
.
getPages
()
<=
currentPageIndex
){
break
;
}
currentPageIndex
++;
}
catch
(
Exception
e
)
{
//出现异常,直接退出,避免死循环。
log
.
error
(
"error"
,
e
);
break
;
}
}
}
}
Write
Preview
Supports
Markdown
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