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
cf2a0c61
Commit
cf2a0c61
authored
Jul 05, 2021
by
dingzhiwei
Browse files
Merge branch 'dev'
parents
387e9627
0ec9d1c0
Changes
59
Show whitespace changes
Inline
Side-by-side
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/WxpayPayOrderQueryService.java
View file @
cf2a0c61
...
...
@@ -22,6 +22,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvsubMchParams
;
import
com.jeequan.jeepay.pay.channel.IPayOrderQueryService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
...
...
@@ -76,7 +77,17 @@ public class WxpayPayOrderQueryService implements IPayOrderQueryService {
}
else
if
(
CS
.
PAY_IF_VERSION
.
WX_V3
.
equals
(
mchAppConfigContext
.
getWxServiceWrapper
().
getApiVersion
()))
{
//V3
JSONObject
resultJSON
=
WxpayV3Util
.
queryOrderV3
(
payOrder
.
getPayOrderId
(),
mchAppConfigContext
.
getWxServiceWrapper
().
getWxPayService
().
getConfig
());
String
reqUrl
;
String
query
;
if
(
mchAppConfigContext
.
isIsvsubMch
()){
// 特约商户
WxpayIsvsubMchParams
isvsubMchParams
=
mchAppConfigContext
.
getIsvsubMchParamsByIfCode
(
CS
.
IF_CODE
.
WXPAY
,
WxpayIsvsubMchParams
.
class
);
reqUrl
=
String
.
format
(
"/v3/pay/partner/transactions/out-trade-no/%s"
,
payOrder
.
getPayOrderId
());
query
=
String
.
format
(
"?sp_mchid=%s&sub_mchid=%s"
,
mchAppConfigContext
.
getWxServiceWrapper
().
getWxPayService
().
getConfig
().
getMchId
(),
isvsubMchParams
.
getSubMchId
());
}
else
{
reqUrl
=
String
.
format
(
"/v3/pay/transactions/out-trade-no/%s"
,
payOrder
.
getPayOrderId
());
query
=
String
.
format
(
"?mchid=%s"
,
mchAppConfigContext
.
getWxServiceWrapper
().
getWxPayService
().
getConfig
().
getMchId
());
}
JSONObject
resultJSON
=
WxpayV3Util
.
queryOrderV3
(
reqUrl
+
query
,
mchAppConfigContext
.
getWxServiceWrapper
().
getWxPayService
().
getConfig
());
String
channelState
=
resultJSON
.
getString
(
"trade_state"
);
if
(
"SUCCESS"
.
equals
(
channelState
))
{
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/kits/WxpayV3Util.java
View file @
cf2a0c61
...
...
@@ -76,9 +76,8 @@ public class WxpayV3Util {
return
JSON
.
parseObject
(
response
);
}
public
static
JSONObject
queryOrderV3
(
String
payOrderId
,
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
String
url
=
String
.
format
(
"%s/v3/pay/transactions/out-trade-no/%s"
,
PAY_BASE_URL
,
payOrderId
);
String
response
=
getV3
(
url
,
wxPayConfig
);
public
static
JSONObject
queryOrderV3
(
String
url
,
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
String
response
=
getV3
(
PAY_BASE_URL
+
url
,
wxPayConfig
);
return
JSON
.
parseObject
(
response
);
}
...
...
@@ -170,7 +169,7 @@ public class WxpayV3Util {
throw
wxPayException
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"\n【异常信息】:{}"
,
url
,
e
.
getMessage
());
log
.
error
(
"\n【异常信息】:{}
,e={}
"
,
url
,
e
.
getMessage
());
throw
(
e
instanceof
WxPayException
)
?
(
WxPayException
)
e
:
new
WxPayException
(
e
.
getMessage
(),
e
);
}
finally
{
httpGet
.
releaseConnection
();
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/ctrl/payorder/AbstractPayOrderController.java
View file @
cf2a0c61
...
...
@@ -23,6 +23,7 @@ import com.jeequan.jeepay.core.entity.MchPayPassage;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.core.model.ApiRes
;
import
com.jeequan.jeepay.core.mq.MqCommonService
;
import
com.jeequan.jeepay.core.utils.SeqKit
;
import
com.jeequan.jeepay.core.utils.SpringBeansUtil
;
import
com.jeequan.jeepay.core.utils.StringKit
;
...
...
@@ -31,7 +32,7 @@ import com.jeequan.jeepay.pay.ctrl.ApiController;
import
com.jeequan.jeepay.pay.exception.ChannelException
;
import
com.jeequan.jeepay.pay.model.IsvConfigContext
;
import
com.jeequan.jeepay.pay.model.MchAppConfigContext
;
import
com.jeequan.jeepay.pay.mq.
queue.MqQueue4ChannelOrderQuery
;
import
com.jeequan.jeepay.pay.mq.
receive.MqReceiveCommon
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRS
;
...
...
@@ -63,7 +64,9 @@ public abstract class AbstractPayOrderController extends ApiController {
@Autowired
private
ConfigContextService
configContextService
;
@Autowired
private
PayMchNotifyService
payMchNotifyService
;
@Autowired
private
SysConfigService
sysConfigService
;
@Autowired
private
MqQueue4ChannelOrderQuery
mqChannelOrderQueryQueue
;
@Autowired
private
MqCommonService
mqCommonService
;
@Autowired
private
MqReceiveCommon
receiveCommon
;
/** 统一下单 (新建订单模式) **/
protected
ApiRes
unifiedOrder
(
String
wayCode
,
UnifiedOrderRQ
bizRQ
){
...
...
@@ -323,7 +326,7 @@ public abstract class AbstractPayOrderController extends ApiController {
//判断是否需要轮询查单
if
(
channelRetMsg
.
isNeedQuery
()){
mqC
hannelOrderQueryQueue
.
send
(
MqQueue4ChannelOrderQuery
.
buildMsg
(
payOrderId
,
1
),
5
*
1000
);
mqC
ommonService
.
send
(
receiveCommon
.
buildMsg
(
payOrderId
,
1
),
5
*
1000
,
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
);
}
}
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
queue/MqQueue4PayOrderMchNotify
.java
→
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
ActiveMqMessage
.java
View file @
cf2a0c61
...
...
@@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.mq
.queue
;
package
com.jeequan.jeepay.pay.mq
;
import
cn.hutool.http.HttpException
;
import
cn.hutool.http.HttpUtil
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.
entity.MchNotifyRecord
;
import
com.jeequan.jeepay.core.
mq.MqCommonService
;
import
com.jeequan.jeepay.pay.mq.config.MqThreadExecutor
;
import
com.jeequan.jeepay.service.impl.MchNotifyRecordService
;
import
com.jeequan.jeepay.service.impl.PayOrderService
;
import
com.jeequan.jeepay.pay.mq.receive.MqReceiveCommon
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.activemq.ScheduledMessage
;
import
org.apache.activemq.command.ActiveMQQueue
;
...
...
@@ -29,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.context.annotation.Profile
;
import
org.springframework.jms.annotation.JmsListener
;
import
org.springframework.jms.core.JmsTemplate
;
import
org.springframework.scheduling.annotation.Async
;
...
...
@@ -38,41 +36,82 @@ import javax.jms.Queue;
import
javax.jms.TextMessage
;
/*
* 商户订单回调MQ通知
* 上游渠道订单轮询查单
* 如:微信的条码支付,没有回调接口, 需要轮询查单完成交易结果通知。
*
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/8 17:3
4
* @date 2021/6/8 17:3
0
*/
@Slf4j
@Component
public
class
MqQueue4PayOrderMchNotify
{
@Profile
(
CS
.
MQTYPE
.
ACTIVE_MQ
)
public
class
ActiveMqMessage
extends
MqCommonService
{
@Bean
(
"mqQueue4PayOrderMchNotifyInner"
)
@Autowired
private
JmsTemplate
jmsTemplate
;
@Lazy
@Autowired
private
MqReceiveCommon
mqReceiveCommon
;
@Bean
(
"activeChannelOrderQuery"
)
public
Queue
mqQueue4ChannelOrderQuery
(){
return
new
ActiveMQQueue
(
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
);
}
@Lazy
@Autowired
@Qualifier
(
"activeChannelOrderQuery"
)
private
Queue
mqQueue4ChannelOrderQuery
;
@Bean
(
"activePayOrderMchNotifyInner"
)
public
Queue
mqQueue4PayOrderMchNotifyInner
(){
return
new
ActiveMQQueue
(
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
);
}
@Lazy
@Autowired
@Qualifier
(
"
mqQueue4
PayOrderMchNotifyInner"
)
@Qualifier
(
"
active
PayOrderMchNotifyInner"
)
private
Queue
mqQueue4PayOrderMchNotifyInner
;
@Autowired
private
JmsTemplate
jmsTemplate
;
@Autowired
private
MchNotifyRecordService
mchNotifyRecordService
;
@Autowired
private
PayOrderService
payOrderService
;
public
MqQueue4PayOrderMchNotify
(){
super
();
/**
* 发送消息
* @param msg
* @param sendType
*/
@Override
public
void
send
(
String
msg
,
String
sendType
)
{
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
))
{
channelOrderQuery
(
msg
);
}
else
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
))
{
payOrderMchNotify
(
msg
);
}
}
/** 发送MQ消息 **/
public
void
send
(
String
msg
)
{
this
.
jmsTemplate
.
convertAndSend
(
mqQueue4PayOrderMchNotifyInner
,
msg
);
/**
* 发送延迟消息
* @param msg
* @param delay
* @param sendType
*/
@Override
public
void
send
(
String
msg
,
long
delay
,
String
sendType
)
{
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
))
{
channelOrderQueryFixed
(
msg
,
delay
);
}
else
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
))
{
payOrderMchNotifyFixed
(
msg
,
delay
);
}
}
/** 发送MQ消息 **/
public
void
send
(
String
msg
,
long
delay
)
{
jmsTemplate
.
send
(
mqQueue4PayOrderMchNotifyInner
,
session
->
{
/** 发送订单查询消息 **/
public
void
channelOrderQuery
(
String
msg
)
{
this
.
jmsTemplate
.
convertAndSend
(
mqQueue4ChannelOrderQuery
,
msg
);
}
/** 发送订单查询延迟消息 **/
public
void
channelOrderQueryFixed
(
String
msg
,
long
delay
)
{
jmsTemplate
.
send
(
mqQueue4ChannelOrderQuery
,
session
->
{
TextMessage
tm
=
session
.
createTextMessage
(
msg
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_DELAY
,
delay
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_PERIOD
,
1
*
1000
);
...
...
@@ -81,61 +120,34 @@ public class MqQueue4PayOrderMchNotify {
});
}
/** 接收 更新系统配置项的消息 **/
@Async
(
MqThreadExecutor
.
EXECUTOR_PAYORDER_MCH_NOTIFY
)
@JmsListener
(
destination
=
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
)
public
void
receive
(
String
msg
)
{
log
.
info
(
"接收商户通知MQ, msg={}"
,
msg
);
Long
notifyId
=
Long
.
parseLong
(
msg
);
MchNotifyRecord
record
=
mchNotifyRecordService
.
getById
(
notifyId
);
if
(
record
==
null
||
record
.
getState
()
!=
MchNotifyRecord
.
STATE_ING
){
log
.
info
(
"查询通知记录不存在或状态不是通知中"
);
return
;
}
if
(
record
.
getNotifyCount
()
>=
record
.
getNotifyCountLimit
()
){
log
.
info
(
"已达到最大发送次数"
);
return
;
}
//1. (发送结果最多6次)
Integer
currentCount
=
record
.
getNotifyCount
()
+
1
;
String
notifyUrl
=
record
.
getNotifyUrl
();
String
res
=
""
;
try
{
res
=
HttpUtil
.
createPost
(
notifyUrl
).
timeout
(
20000
).
execute
().
body
();
}
catch
(
HttpException
e
)
{
log
.
error
(
"http error"
,
e
);
/** 发送订单回调消息 **/
public
void
payOrderMchNotify
(
String
msg
)
{
this
.
jmsTemplate
.
convertAndSend
(
mqQueue4PayOrderMchNotifyInner
,
msg
);
}
if
(
currentCount
==
1
){
//第一次通知: 更新为已通知
payOrderService
.
updateNotifySent
(
record
.
getOrderId
());
/** 发送订单回调延迟消息 **/
public
void
payOrderMchNotifyFixed
(
String
msg
,
long
delay
)
{
jmsTemplate
.
send
(
mqQueue4PayOrderMchNotifyInner
,
session
->
{
TextMessage
tm
=
session
.
createTextMessage
(
msg
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_DELAY
,
delay
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_PERIOD
,
1
*
1000
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_REPEAT
,
1
);
return
tm
;
});
}
//通知成功
if
(
"SUCCESS"
.
equalsIgnoreCase
(
res
)){
mchNotifyRecordService
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_SUCCESS
,
res
);
return
;
}
/
/通知次数 >= 最大通知次数时, 更新响应结果为异常, 不在继续延迟发送消息
if
(
currentCount
>=
record
.
getNotifyCountLimit
()
){
mchNotifyReco
rd
S
er
vice
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_FAIL
,
res
);
return
;
/
** 接收 查单消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
)
public
void
receiveChannelO
rder
Query
(
String
msg
)
{
mqReceiveCommon
.
channelOrderQuery
(
msg
)
;
}
// 继续发送MQ 延迟发送
mchNotifyRecordService
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_ING
,
res
);
// 通知延时次数
// 1 2 3 4 5 6
// 0 30 60 90 120 150
send
(
msg
,
currentCount
*
30
*
1000
);
/** 接收 支付订单商户回调消息 **/
@Async
(
MqThreadExecutor
.
EXECUTOR_PAYORDER_MCH_NOTIFY
)
@JmsListener
(
destination
=
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
)
public
void
receivePayOrderMchNotify
(
String
msg
)
{
mqReceiveCommon
.
payOrderMchNotify
(
msg
);
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/RabbitMqMessage.java
0 → 100644
View file @
cf2a0c61
/*
* 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.mq
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.mq.MqCommonService
;
import
com.jeequan.jeepay.pay.mq.receive.MqReceiveCommon
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.amqp.rabbit.annotation.RabbitListener
;
import
org.springframework.amqp.rabbit.core.RabbitTemplate
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.context.annotation.Profile
;
import
org.springframework.stereotype.Component
;
/**
* RabbitMQ
* 上游渠道订单轮询查单
* 如:微信的条码支付,没有回调接口, 需要轮询查单完成交易结果通知。
*
*
* @author xiaoyu
* @site https://www.jeepay.vip
* @date 2021/6/25 17:10
*/
@Slf4j
@Component
@Profile
(
CS
.
MQTYPE
.
RABBIT_MQ
)
public
class
RabbitMqMessage
extends
MqCommonService
{
@Autowired
private
RabbitTemplate
rabbitTemplate
;
@Lazy
@Autowired
private
MqReceiveCommon
mqReceiveCommon
;
@Override
public
void
send
(
String
msg
,
String
sendType
)
{
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
))
{
channelOrderQuery
(
msg
);
}
else
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
))
{
payOrderMchNotify
(
msg
);
}
}
@Override
public
void
send
(
String
msg
,
long
delay
,
String
sendType
)
{
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
))
{
channelOrderQueryFixed
(
msg
,
delay
);
}
else
if
(
sendType
.
equals
(
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
))
{
payOrderMchNotifyFixed
(
msg
,
delay
);
}
}
/** 发送订单查询消息 **/
public
void
channelOrderQuery
(
String
msg
)
{
rabbitTemplate
.
convertAndSend
(
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
,
msg
);
}
/** 发送订单查询延迟消息 **/
public
void
channelOrderQueryFixed
(
String
msg
,
long
delay
)
{
rabbitTemplate
.
convertAndSend
(
CS
.
DELAYED_EXCHANGE
,
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
,
msg
,
a
->{
a
.
getMessageProperties
().
setDelay
(
Math
.
toIntExact
(
delay
));
return
a
;
});
}
/** 发送订单回调消息 **/
public
void
payOrderMchNotify
(
String
msg
)
{
rabbitTemplate
.
convertAndSend
(
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
,
msg
);
}
/** 发送订单回调延迟消息 **/
public
void
payOrderMchNotifyFixed
(
String
msg
,
long
delay
)
{
rabbitTemplate
.
convertAndSend
(
CS
.
DELAYED_EXCHANGE
,
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
,
msg
,
a
->{
a
.
getMessageProperties
().
setDelay
(
Math
.
toIntExact
(
delay
));
return
a
;
});
}
/** 接收 查单消息 **/
@RabbitListener
(
queues
=
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
)
public
void
receiveChannelOrderQuery
(
String
msg
)
{
mqReceiveCommon
.
channelOrderQuery
(
msg
);
}
/** 接收 支付订单商户回调消息 **/
@RabbitListener
(
queues
=
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
)
public
void
receivePayOrderMchNotify
(
String
msg
)
{
mqReceiveCommon
.
payOrderMchNotify
(
msg
);
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/topic/MqTopic
4ModifyMchInfo
.java
→
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
activemq/
topic/MqTopic
Receive
.java
View file @
cf2a0c61
...
...
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.mq.topic
;
package
com.jeequan.jeepay.pay.mq.
activemq.
topic
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.pay.
service.ConfigContextService
;
import
com.jeequan.jeepay.pay.
mq.receive.MqReceiveCommon
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Profile
;
import
org.springframework.jms.annotation.JmsListener
;
import
org.springframework.stereotype.Component
;
/*
*
更改商户信
息
*
接收mq消
息
*
* @author terrfly
* @site https://www.jeepay.vip
...
...
@@ -32,9 +32,16 @@ import org.springframework.stereotype.Component;
*/
@Slf4j
@Component
public
class
MqTopic4ModifyMchInfo
{
@Profile
(
CS
.
MQTYPE
.
ACTIVE_MQ
)
public
class
MqTopicReceive
{
@Autowired
private
ConfigContextService
configContextService
;
@Autowired
private
MqReceiveCommon
mqReceiveCommon
;
/** 接收 更新服务商信息的消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_ISV_INFO
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receiveModifyIsvInfo
(
String
isvNo
)
{
mqReceiveCommon
.
modifyIsvInfo
(
isvNo
);
}
/** 接收 [商户配置信息] 的消息
* 已知推送节点:
...
...
@@ -42,10 +49,8 @@ public class MqTopic4ModifyMchInfo{
* 2. 删除商户时
* **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_MCH_INFO
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receive
(
String
mchNo
)
{
log
.
info
(
"接收 [商户配置信息] 的消息, msg={}"
,
mchNo
);
configContextService
.
initMchInfoConfigContext
(
mchNo
);
public
void
receiveModifyMchInfo
(
String
mchNo
)
{
mqReceiveCommon
.
modifyMchInfo
(
mchNo
);
}
/** 接收 [商户应用支付参数配置信息] 的消息
...
...
@@ -54,11 +59,14 @@ public class MqTopic4ModifyMchInfo{
* 2. 删除商户应用配置
* **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_MCH_APP
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receiveMchApp
(
String
mchNoAndAppId
)
{
public
void
receiveModifyMchApp
(
String
mchNoAndAppId
)
{
mqReceiveCommon
.
modifyMchApp
(
mchNoAndAppId
);
}
log
.
info
(
"接收 [商户应用支付参数配置信息] 的消息, msg={}"
,
mchNoAndAppId
);
JSONObject
jsonObject
=
(
JSONObject
)
JSONObject
.
parse
(
mchNoAndAppId
);
configContextService
.
initMchAppConfigContext
(
jsonObject
.
getString
(
"mchNo"
),
jsonObject
.
getString
(
"appId"
));
/** 接收 更新系统配置项的消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_SYS_CONFIG
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receiveModifySysConfig
(
String
msg
)
{
mqReceiveCommon
.
initDbConfig
(
msg
);
}
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
topic
/JMSConfig.java
→
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
config
/JMSConfig.java
View file @
cf2a0c61
...
...
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.mq.
topic
;
package
com.jeequan.jeepay.pay.mq.
config
;
import
com.jeequan.jeepay.core.constants.CS
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Profile
;
import
org.springframework.jms.config.DefaultJmsListenerContainerFactory
;
import
org.springframework.jms.config.JmsListenerContainerFactory
;
import
org.springframework.stereotype.Component
;
...
...
@@ -30,6 +32,7 @@ import javax.jms.ConnectionFactory;
* @date 2021/6/8 17:31
*/
@Component
@Profile
(
CS
.
MQTYPE
.
ACTIVE_MQ
)
public
class
JMSConfig
{
/** 新增jmsListenerContainer, 用于接收topic类型的消息 **/
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/config/RabbitMqConfig.java
0 → 100644
View file @
cf2a0c61
/*
* 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.mq.config
;
import
com.jeequan.jeepay.core.constants.CS
;
import
org.springframework.amqp.core.*
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Profile
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* RabbitMq
* 延迟消息队列绑定交换机
* @author xiaoyu
* @site https://www.jeepay.vip
* @date 2021/6/25 17:10
*/
@Configuration
@Profile
(
CS
.
MQTYPE
.
RABBIT_MQ
)
public
class
RabbitMqConfig
{
@Bean
(
"channelOrderQuery"
)
public
Queue
channelOrderQuery
()
{
return
new
Queue
(
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
,
true
);
}
@Bean
(
"payOrderMchNotify"
)
public
Queue
payOrderMchNotify
()
{
return
new
Queue
(
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
,
true
);
}
//创建 custom 交换机
@Bean
CustomExchange
customExchange
()
{
Map
<
String
,
Object
>
args
=
new
HashMap
<>();
args
.
put
(
"x-delayed-type"
,
"direct"
);
return
new
CustomExchange
(
CS
.
DELAYED_EXCHANGE
,
"x-delayed-message"
,
true
,
false
,
args
);
}
//绑定 将队列和交换机绑定, 并设置用于匹配键:QUEUE_CHANNEL_ORDER_QUERY
@Bean
Binding
bindingChannelOrderQuery
(
@Qualifier
(
"channelOrderQuery"
)
Queue
channelOrderQuery
)
{
return
BindingBuilder
.
bind
(
channelOrderQuery
).
to
(
customExchange
()).
with
(
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
).
noargs
();
}
//绑定 将队列和交换机绑定, 并设置用于匹配键:QUEUE_PAYORDER_MCH_NOTIFY
@Bean
Binding
bindingPayOrderNotify
(
@Qualifier
(
"payOrderMchNotify"
)
Queue
payOrderMchNotify
)
{
return
BindingBuilder
.
bind
(
payOrderMchNotify
).
to
(
customExchange
()).
with
(
CS
.
MQ
.
QUEUE_PAYORDER_MCH_NOTIFY
).
noargs
();
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/queue/MqQueue4ChannelOrderQuery.java
deleted
100644 → 0
View file @
387e9627
/*
* 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.mq.queue
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.service.ChannelOrderReissueService
;
import
com.jeequan.jeepay.service.impl.PayOrderService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.activemq.ScheduledMessage
;
import
org.apache.activemq.command.ActiveMQQueue
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.jms.annotation.JmsListener
;
import
org.springframework.jms.core.JmsTemplate
;
import
org.springframework.stereotype.Component
;
import
javax.jms.TextMessage
;
/*
* 上游渠道订单轮询查单
* 如:微信的条码支付,没有回调接口, 需要轮询查单完成交易结果通知。
*
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/8 17:30
*/
@Slf4j
@Component
public
class
MqQueue4ChannelOrderQuery
extends
ActiveMQQueue
{
@Autowired
private
JmsTemplate
jmsTemplate
;
@Autowired
private
PayOrderService
payOrderService
;
@Autowired
private
ChannelOrderReissueService
channelOrderReissueService
;
public
static
final
String
buildMsg
(
String
payOrderId
,
int
count
){
return
payOrderId
+
","
+
count
;
}
/** 构造函数 */
public
MqQueue4ChannelOrderQuery
(){
super
(
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
);
}
/** 发送MQ消息 **/
public
void
send
(
String
msg
)
{
this
.
jmsTemplate
.
convertAndSend
(
this
,
msg
);
}
/** 发送MQ消息 **/
public
void
send
(
String
msg
,
long
delay
)
{
jmsTemplate
.
send
(
this
,
session
->
{
TextMessage
tm
=
session
.
createTextMessage
(
msg
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_DELAY
,
delay
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_PERIOD
,
1
*
1000
);
tm
.
setLongProperty
(
ScheduledMessage
.
AMQ_SCHEDULED_REPEAT
,
1
);
return
tm
;
});
}
/** 接收 更新系统配置项的消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
QUEUE_CHANNEL_ORDER_QUERY
)
public
void
receive
(
String
msg
)
{
String
[]
arr
=
msg
.
split
(
","
);
String
payOrderId
=
arr
[
0
];
int
currentCount
=
Integer
.
parseInt
(
arr
[
1
]);
log
.
info
(
"接收轮询查单通知MQ, payOrderId={}, count={}"
,
payOrderId
,
currentCount
);
currentCount
++
;
PayOrder
payOrder
=
payOrderService
.
getById
(
payOrderId
);
if
(
payOrder
==
null
)
{
log
.
warn
(
"查询支付订单为空,payOrderId={}"
,
payOrderId
);
return
;
}
if
(
payOrder
.
getState
()
!=
PayOrder
.
STATE_ING
)
{
log
.
warn
(
"订单状态不是支付中,不需查询渠道.payOrderId={}"
,
payOrderId
);
return
;
}
ChannelRetMsg
channelRetMsg
=
channelOrderReissueService
.
processPayOrder
(
payOrder
);
//返回null 可能为接口报错等, 需要再次轮询
if
(
channelRetMsg
==
null
||
channelRetMsg
.
getChannelState
()
==
null
||
channelRetMsg
.
getChannelState
().
equals
(
ChannelRetMsg
.
ChannelState
.
WAITING
)){
//最多查询6次
if
(
currentCount
<=
6
){
send
(
buildMsg
(
payOrderId
,
currentCount
),
5
*
1000
);
//延迟5s再次查询
}
else
{
//TODO 调用【撤销订单】接口
}
}
else
{
//其他状态, 不需要再次轮询。
}
return
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
topic/MqTopic4ModifyIsvInfo
.java
→
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/
rabbitmq/RabbitMqDirectReceive
.java
View file @
cf2a0c61
...
...
@@ -13,36 +13,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.jeequan.jeepay.pay.mq.
topic
;
package
com.jeequan.jeepay.pay.mq.
rabbitmq
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.pay.
service.ConfigContextService
;
import
com.jeequan.jeepay.pay.
mq.receive.MqReceiveCommon
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.amqp.rabbit.annotation.Exchange
;
import
org.springframework.amqp.rabbit.annotation.Queue
;
import
org.springframework.amqp.rabbit.annotation.QueueBinding
;
import
org.springframework.amqp.rabbit.annotation.RabbitListener
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.
jms
.annotation.
JmsListener
;
import
org.springframework.
context
.annotation.
Profile
;
import
org.springframework.stereotype.Component
;
/*
*
更改ISV信
息
/*
*
*
接收mq消
息
*
* @author
terrfly
* @author
xiaoyu
* @site https://www.jeepay.vip
* @date 2021/6/
8
17:
3
1
* @date 2021/6/
25
17:1
0
*/
@Slf4j
@Component
public
class
MqTopic4ModifyIsvInfo
{
@Profile
(
CS
.
MQTYPE
.
RABBIT_MQ
)
public
class
RabbitMqDirectReceive
{
@Autowired
private
ConfigContextService
configContextService
;
@Autowired
private
MqReceiveCommon
mqReceiveCommon
;
/** 接收 更新系统配置项的消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_ISV_INFO
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receive
(
String
isvNo
)
{
/** 接收 更新服务商信息的消息 **/
@RabbitListener
(
queues
=
CS
.
MQ
.
TOPIC_MODIFY_ISV_INFO
)
public
void
receiveModifyIsvInfo
(
String
isvNo
)
{
mqReceiveCommon
.
modifyIsvInfo
(
isvNo
);
}
/** 接收 [商户配置信息] 的消息
* 已知推送节点:
* 1. 更新商户基本资料和状态
* 2. 删除商户时
* **/
@RabbitListener
(
queues
=
CS
.
MQ
.
TOPIC_MODIFY_MCH_INFO
)
public
void
receiveModifyMchInfo
(
String
mchNo
)
{
mqReceiveCommon
.
modifyMchInfo
(
mchNo
);
}
log
.
info
(
"重置ISV信息, msg={}"
,
isvNo
);
configContextService
.
initIsvConfigContext
(
isvNo
);
/** 接收 [商户应用支付参数配置信息] 的消息
* 已知推送节点:
* 1. 更新商户应用配置
* 2. 删除商户应用配置
* **/
@RabbitListener
(
queues
=
CS
.
MQ
.
TOPIC_MODIFY_MCH_APP
)
public
void
receiveModifyMchApp
(
String
mchNoAndAppId
)
{
mqReceiveCommon
.
modifyMchApp
(
mchNoAndAppId
);
}
/** 接收 更新系统配置项的消息 **/
@RabbitListener
(
bindings
=
{
@QueueBinding
(
value
=
@Queue
(),
exchange
=
@Exchange
(
name
=
CS
.
FANOUT_EXCHANGE_SYS_CONFIG
,
type
=
"fanout"
))})
public
void
receiveModifySysConfig
(
String
msg
)
{
mqReceiveCommon
.
initDbConfig
(
msg
);
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/receive/MqReceiveCommon.java
0 → 100644
View file @
cf2a0c61
/*
* 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.mq.receive
;
import
cn.hutool.http.HttpException
;
import
cn.hutool.http.HttpUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.MchNotifyRecord
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.mq.MqCommonService
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.service.ChannelOrderReissueService
;
import
com.jeequan.jeepay.pay.service.ConfigContextService
;
import
com.jeequan.jeepay.service.impl.MchNotifyRecordService
;
import
com.jeequan.jeepay.service.impl.PayOrderService
;
import
com.jeequan.jeepay.service.impl.SysConfigService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.stereotype.Service
;
/**
* 处理公共接收消息方法
*
* @author xiaoyu
* @site https://www.jeepay.vip
* @date 2021/6/25 17:10
*/
@Slf4j
@Service
public
class
MqReceiveCommon
{
@Autowired
private
SysConfigService
sysConfigService
;
@Autowired
private
ConfigContextService
configContextService
;
@Autowired
private
PayOrderService
payOrderService
;
@Autowired
private
ChannelOrderReissueService
channelOrderReissueService
;
@Autowired
private
MchNotifyRecordService
mchNotifyRecordService
;
@Autowired
private
MqCommonService
mqCommonService
;
/** 接收 [商户配置信息] 的消息 **/
public
void
modifyMchInfo
(
String
mchNo
)
{
log
.
info
(
"接收 [商户配置信息] 的消息, msg={}"
,
mchNo
);
configContextService
.
initMchInfoConfigContext
(
mchNo
);
}
/** 接收 [商户应用支付参数配置信息] 的消息 **/
public
void
modifyMchApp
(
String
mchNoAndAppId
)
{
log
.
info
(
"接收 [商户应用支付参数配置信息] 的消息, msg={}"
,
mchNoAndAppId
);
JSONObject
jsonObject
=
(
JSONObject
)
JSONObject
.
parse
(
mchNoAndAppId
);
configContextService
.
initMchAppConfigContext
(
jsonObject
.
getString
(
"mchNo"
),
jsonObject
.
getString
(
"appId"
));
}
/** 重置ISV信息 **/
public
void
modifyIsvInfo
(
String
isvNo
)
{
log
.
info
(
"重置ISV信息, msg={}"
,
isvNo
);
configContextService
.
initIsvConfigContext
(
isvNo
);
}
/** 接收商户订单回调通知 **/
public
void
payOrderMchNotify
(
String
msg
)
{
try
{
log
.
info
(
"接收商户通知MQ, msg={}"
,
msg
);
Long
notifyId
=
Long
.
parseLong
(
msg
);
MchNotifyRecord
record
=
mchNotifyRecordService
.
getById
(
notifyId
);
if
(
record
==
null
||
record
.
getState
()
!=
MchNotifyRecord
.
STATE_ING
){
log
.
info
(
"查询通知记录不存在或状态不是通知中"
);
return
;
}
if
(
record
.
getNotifyCount
()
>=
record
.
getNotifyCountLimit
()
){
log
.
info
(
"已达到最大发送次数"
);
return
;
}
//1. (发送结果最多6次)
Integer
currentCount
=
record
.
getNotifyCount
()
+
1
;
String
notifyUrl
=
record
.
getNotifyUrl
();
String
res
=
""
;
try
{
res
=
HttpUtil
.
createPost
(
notifyUrl
).
timeout
(
20000
).
execute
().
body
();
}
catch
(
HttpException
e
)
{
log
.
error
(
"http error"
,
e
);
}
if
(
currentCount
==
1
){
//第一次通知: 更新为已通知
payOrderService
.
updateNotifySent
(
record
.
getOrderId
());
}
//通知成功
if
(
"SUCCESS"
.
equalsIgnoreCase
(
res
)){
mchNotifyRecordService
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_SUCCESS
,
res
);
}
//通知次数 >= 最大通知次数时, 更新响应结果为异常, 不在继续延迟发送消息
if
(
currentCount
>=
record
.
getNotifyCountLimit
()
){
mchNotifyRecordService
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_FAIL
,
res
);
}
// 继续发送MQ 延迟发送
mchNotifyRecordService
.
updateNotifyResult
(
notifyId
,
MchNotifyRecord
.
STATE_ING
,
res
);
// 通知延时次数
// 1 2 3 4 5 6
// 0 30 60 90 120 150
mqCommonService
.
send
(
msg
,
currentCount
*
30
*
1000
,
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
);
return
;
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
());
return
;
}
}
/** 接收订单查单通知 **/
public
void
channelOrderQuery
(
String
msg
)
{
try
{
String
[]
arr
=
msg
.
split
(
","
);
String
payOrderId
=
arr
[
0
];
int
currentCount
=
Integer
.
parseInt
(
arr
[
1
]);
log
.
info
(
"接收轮询查单通知MQ, payOrderId={}, count={}"
,
payOrderId
,
currentCount
);
currentCount
++
;
PayOrder
payOrder
=
payOrderService
.
getById
(
payOrderId
);
if
(
payOrder
==
null
)
{
log
.
warn
(
"查询支付订单为空,payOrderId={}"
,
payOrderId
);
return
;
}
if
(
payOrder
.
getState
()
!=
PayOrder
.
STATE_ING
)
{
log
.
warn
(
"订单状态不是支付中,不需查询渠道.payOrderId={}"
,
payOrderId
);
return
;
}
if
(
payOrder
==
null
)
return
;
ChannelRetMsg
channelRetMsg
=
channelOrderReissueService
.
processPayOrder
(
payOrder
);
//返回null 可能为接口报错等, 需要再次轮询
if
(
channelRetMsg
==
null
||
channelRetMsg
.
getChannelState
()
==
null
||
channelRetMsg
.
getChannelState
().
equals
(
ChannelRetMsg
.
ChannelState
.
WAITING
)){
//最多查询6次
if
(
currentCount
<=
6
){
mqCommonService
.
send
(
buildMsg
(
payOrderId
,
currentCount
),
5
*
1000
,
CS
.
MQ
.
MQ_TYPE_CHANNEL_ORDER_QUERY
);
//延迟5s再次查询
}
else
{
//TODO 调用【撤销订单】接口
}
}
else
{
//其他状态, 不需要再次轮询。
}
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
());
return
;
}
}
/** 接收系统配置修改通知 **/
public
void
initDbConfig
(
String
msg
)
{
log
.
info
(
"成功接收更新系统配置的订阅通知, msg={}"
,
msg
);
sysConfigService
.
initDBConfig
(
msg
);
log
.
info
(
"系统配置静态属性已重置"
);
}
public
static
final
String
buildMsg
(
String
payOrderId
,
int
count
){
return
payOrderId
+
","
+
count
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/mq/topic/MqTopic4ModifySysConfig.java
deleted
100644 → 0
View file @
387e9627
/*
* 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.mq.topic
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.service.impl.SysConfigService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.jms.annotation.JmsListener
;
import
org.springframework.stereotype.Component
;
/*
* 更改系统配置参数
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/8 17:35
*/
@Slf4j
@Component
public
class
MqTopic4ModifySysConfig
{
@Autowired
private
SysConfigService
sysConfigService
;
/** 接收 更新系统配置项的消息 **/
@JmsListener
(
destination
=
CS
.
MQ
.
TOPIC_MODIFY_SYS_CONFIG
,
containerFactory
=
"jmsListenerContainer"
)
public
void
receive
(
String
msg
)
{
log
.
info
(
"成功接收更新系统配置的订阅通知, msg={}"
,
msg
);
sysConfigService
.
initDBConfig
(
msg
);
log
.
info
(
"系统配置静态属性已重置"
);
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/ChannelUserIdRQ.java
View file @
cf2a0c61
...
...
@@ -29,10 +29,6 @@ import javax.validation.constraints.NotBlank;
@Data
public
class
ChannelUserIdRQ
extends
AbstractMchAppRQ
{
/** 商户号 **/
@NotBlank
(
message
=
"商户号不能为空"
)
private
String
mchNo
;
/** 接口代码, AUTO表示:自动获取 **/
@NotBlank
(
message
=
"接口代码不能为空"
)
private
String
ifCode
;
...
...
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/service/PayMchNotifyService.java
View file @
cf2a0c61
...
...
@@ -16,12 +16,13 @@
package
com.jeequan.jeepay.pay.service
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.MchNotifyRecord
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.entity.RefundOrder
;
import
com.jeequan.jeepay.core.mq.MqCommonService
;
import
com.jeequan.jeepay.core.utils.JeepayKit
;
import
com.jeequan.jeepay.core.utils.StringKit
;
import
com.jeequan.jeepay.pay.mq.queue.MqQueue4PayOrderMchNotify
;
import
com.jeequan.jeepay.pay.rqrs.payorder.QueryPayOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.refund.QueryRefundOrderRS
;
import
com.jeequan.jeepay.service.impl.MchNotifyRecordService
;
...
...
@@ -42,8 +43,8 @@ import org.springframework.stereotype.Service;
public
class
PayMchNotifyService
{
@Autowired
private
MchNotifyRecordService
mchNotifyRecordService
;
@Autowired
private
MqQueue4PayOrderMchNotify
mqPayOrderMchNotifyQueue
;
@Autowired
private
ConfigContextService
configContextService
;
@Autowired
private
MqCommonService
mqCommonService
;
/** 商户通知信息, 只有订单是终态,才会发送通知, 如明确成功和明确失败 **/
...
...
@@ -84,7 +85,7 @@ public class PayMchNotifyService {
//推送到MQ
Long
notifyId
=
mchNotifyRecord
.
getNotifyId
();
mq
PayOrderMchNotifyQueue
.
send
(
notifyId
+
""
);
mq
CommonService
.
send
(
notifyId
+
""
,
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
);
}
catch
(
Exception
e
)
{
log
.
error
(
"推送失败!"
,
e
);
...
...
@@ -129,7 +130,7 @@ public class PayMchNotifyService {
//推送到MQ
Long
notifyId
=
mchNotifyRecord
.
getNotifyId
();
mq
PayOrderMchNotifyQueue
.
send
(
notifyId
+
""
);
mq
CommonService
.
send
(
notifyId
+
""
,
CS
.
MQ
.
MQ_TYPE_PAY_ORDER_MCH_NOTIFY
);
}
catch
(
Exception
e
)
{
log
.
error
(
"推送失败!"
,
e
);
...
...
jeepay-payment/src/main/resources/application.yml
View file @
cf2a0c61
...
...
@@ -50,9 +50,25 @@ spring:
timeout
:
1000
database
:
3
#1库:运营平台 #2库:商户系统 #3库:支付网关
password
:
# 注意:以下MQ配置需注意【如需使用activeMQ则需将rabbitMQ配置注释即可】
# profiles:
# include:
# - activeMQ
# - rabbitMQ # 需要安装延迟队列插件:https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq/
#activeMQ配置
activemq
:
broker-url
:
tcp://localhost:61616
#连接地址
# activemq:
# broker-url: tcp://localhost:61616 #连接地址
#rabbitmq配置
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
#日志配置参数。
# 当存在logback-spring.xml文件时: 该配置将引进到logback配置, springboot配置不生效。
...
...
jeepay-service/src/main/java/com/jeequan/jeepay/service/impl/PayOrderService.java
View file @
cf2a0c61
...
...
@@ -125,34 +125,26 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
}
public
Map
payCount
(
String
mchNo
,
Byte
state
,
String
dayStart
,
String
dayEnd
)
{
public
Map
payCount
(
String
mchNo
,
Byte
state
,
Byte
refundState
,
String
dayStart
,
String
dayEnd
)
{
Map
param
=
new
HashMap
<>();
if
(
state
!=
null
)
param
.
put
(
"state"
,
state
);
if
(
refundState
!=
null
)
param
.
put
(
"refundState"
,
refundState
);
if
(
StrUtil
.
isNotBlank
(
mchNo
))
param
.
put
(
"mchNo"
,
mchNo
);
if
(
StrUtil
.
isNotBlank
(
dayStart
))
param
.
put
(
"createTimeStart"
,
dayStart
);
if
(
StrUtil
.
isNotBlank
(
dayEnd
))
param
.
put
(
"createTimeEnd"
,
dayEnd
);
return
payOrderMapper
.
payCount
(
param
);
}
public
List
<
Map
>
payTypeCount
(
String
mchNo
,
Byte
state
,
String
dayStart
,
String
dayEnd
)
{
public
List
<
Map
>
payTypeCount
(
String
mchNo
,
Byte
state
,
Byte
refundState
,
String
dayStart
,
String
dayEnd
)
{
Map
param
=
new
HashMap
<>();
if
(
state
!=
null
)
param
.
put
(
"state"
,
state
);
if
(
refundState
!=
null
)
param
.
put
(
"refundState"
,
refundState
);
if
(
StrUtil
.
isNotBlank
(
mchNo
))
param
.
put
(
"mchNo"
,
mchNo
);
if
(
StrUtil
.
isNotBlank
(
dayStart
))
param
.
put
(
"createTimeStart"
,
dayStart
);
if
(
StrUtil
.
isNotBlank
(
dayEnd
))
param
.
put
(
"createTimeEnd"
,
dayEnd
);
return
payOrderMapper
.
payTypeCount
(
param
);
}
public
Map
selectTotalCount
(
String
mchNo
,
Byte
state
,
String
dayStart
,
String
dayEnd
)
{
Map
param
=
new
HashMap
<>();
if
(
state
!=
null
)
param
.
put
(
"state"
,
state
);
if
(
StrUtil
.
isNotBlank
(
mchNo
))
param
.
put
(
"mchNo"
,
mchNo
);
if
(
StrUtil
.
isNotBlank
(
dayStart
))
param
.
put
(
"createTimeStart"
,
dayStart
);
if
(
StrUtil
.
isNotBlank
(
dayEnd
))
param
.
put
(
"createTimeEnd"
,
dayEnd
);
return
payOrderMapper
.
selectTotalCount
(
param
);
}
/** 更新订单为 超时状态 **/
public
Integer
updateOrderExpired
(){
...
...
@@ -190,7 +182,7 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
String
dayStart
=
DateUtil
.
beginOfDay
(
date
).
toString
(
DatePattern
.
NORM_DATETIME_MINUTE_PATTERN
);
String
dayEnd
=
DateUtil
.
endOfDay
(
date
).
toString
(
DatePattern
.
NORM_DATETIME_MINUTE_PATTERN
);
// 每日交易金额查询
dayAmount
=
payCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
dayStart
,
dayEnd
);
dayAmount
=
payCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
null
,
dayStart
,
dayEnd
);
if
(
dayAmount
!=
null
)
payAmount
=
new
BigDecimal
(
dayAmount
.
get
(
"payAmount"
).
toString
());
if
(
i
==
0
)
{
todayAmount
=
dayAmount
.
get
(
"payAmount"
).
toString
();
...
...
@@ -219,7 +211,7 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
// 服务商总数
int
isvCount
=
isvInfoMapper
.
selectCount
(
IsvInfo
.
gw
());
// 总交易金额
Map
<
String
,
String
>
payCountMap
=
payCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
null
,
null
);
Map
<
String
,
String
>
payCountMap
=
payCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
null
,
null
,
null
);
json
.
put
(
"totalMch"
,
mchCount
);
json
.
put
(
"totalIsv"
,
isvCount
);
json
.
put
(
"totalAmount"
,
payCountMap
.
get
(
"payAmount"
));
...
...
@@ -247,9 +239,10 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
param
.
put
(
"createTimeEnd"
,
createdEnd
);
// 查询收款的记录
param
.
put
(
"state"
,
PayOrder
.
STATE_SUCCESS
);
param
.
put
(
"refundState"
,
null
);
List
<
Map
>
payOrderList
=
payOrderMapper
.
selectOrderCount
(
param
);
// 查询退款的记录
param
.
put
(
"
s
tate"
,
PayOrder
.
STATE_REFUND
);
param
.
put
(
"
refundS
tate"
,
PayOrder
.
STATE_REFUND
);
List
<
Map
>
refundOrderList
=
payOrderMapper
.
selectOrderCount
(
param
);
// 生成前端返回参数类型
List
<
Map
>
returnList
=
getReturnList
(
daySpace
,
createdEnd
,
payOrderList
,
refundOrderList
);
...
...
@@ -272,7 +265,7 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
createdEnd
=
end
+
" 23:59:59"
;
}
// 统计列表
List
<
Map
>
payCountMap
=
payTypeCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
createdStart
,
createdEnd
);
List
<
Map
>
payCountMap
=
payTypeCount
(
mchNo
,
PayOrder
.
STATE_SUCCESS
,
null
,
createdStart
,
createdEnd
);
// 得到所有支付方式
Map
<
String
,
String
>
payWayNameMap
=
new
HashMap
<>();
...
...
@@ -326,7 +319,7 @@ public class PayOrderService extends ServiceImpl<PayOrderMapper, PayOrder> {
payListMap
.
add
(
payMap
);
for
(
Map
refundOrderMap:
refundOrderList
)
{
if
(
dayMap
.
get
(
"date"
).
equals
(
refundOrderMap
.
get
(
"groupDate"
)))
{
refundMap
.
put
(
"payAmount"
,
refundOrderMap
.
get
(
"
pay
Amount"
));
refundMap
.
put
(
"payAmount"
,
refundOrderMap
.
get
(
"
refund
Amount"
));
}
}
refundListMap
.
add
(
refundMap
);
...
...
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.java
View file @
cf2a0c61
...
...
@@ -36,8 +36,6 @@ public interface PayOrderMapper extends BaseMapper<PayOrder> {
List
<
Map
>
payTypeCount
(
Map
param
);
Map
selectTotalCount
(
Map
param
);
List
<
Map
>
selectOrderCount
(
Map
param
);
/** 更新订单退款金额和次数 **/
...
...
jeepay-service/src/main/java/com/jeequan/jeepay/service/mapper/PayOrderMapper.xml
View file @
cf2a0c61
...
...
@@ -45,18 +45,7 @@
FROM t_pay_order
WHERE 1=1
<if
test=
"state != null"
>
AND state = #{state}
</if>
<if
test=
"mchNo != null"
>
AND mch_no = #{mchNo}
</if>
<if
test=
"createTimeStart != null"
>
AND created_at
>
= #{createTimeStart}
</if>
<if
test=
"createTimeEnd != null"
>
AND created_at
<
= #{createTimeEnd}
</if>
;
</select>
<!--总交易统计-->
<select
id=
"selectTotalCount"
resultType=
"java.util.Map"
parameterType=
"java.util.Map"
>
SELECT ROUND(IFNULL(SUM(amount), 0)/100, 2) AS totalAmount, IFNULL(COUNT(1), 0) AS totalCount
FROM t_pay_order
WHERE 1=1
<if
test=
"state != null"
>
AND state = #{state}
</if>
<if
test=
"refundState != null"
>
AND refund_state = #{refundState}
</if>
<if
test=
"mchNo != null"
>
AND mch_no = #{mchNo}
</if>
<if
test=
"createTimeStart != null"
>
AND created_at
>
= #{createTimeStart}
</if>
<if
test=
"createTimeEnd != null"
>
AND created_at
<
= #{createTimeEnd}
</if>
...
...
@@ -69,6 +58,7 @@
FROM t_pay_order
WHERE 1=1
<if
test=
"state != null"
>
AND state = #{state}
</if>
<if
test=
"refundState != null"
>
AND refund_state = #{refundState}
</if>
<if
test=
"mchNo != null"
>
AND mch_no = #{mchNo}
</if>
<if
test=
"createTimeStart != null"
>
AND created_at
>
= #{createTimeStart}
</if>
<if
test=
"createTimeEnd != null"
>
AND created_at
<
= #{createTimeEnd}
</if>
...
...
@@ -77,10 +67,14 @@
<!--成功、退款订单统计-->
<select
id=
"selectOrderCount"
resultType=
"java.util.Map"
parameterType=
"java.util.Map"
>
SELECT DATE_FORMAT(FLOOR(created_at),'%m-%d') groupDate, ROUND(IFNULL(SUM(amount), 0)/100, 2) AS payAmount
SELECT DATE_FORMAT(FLOOR(created_at),'%m-%d') groupDate, ROUND(IFNULL(SUM(amount), 0)/100, 2) AS payAmount,
ROUND(IFNULL(SUM(refund_amount), 0)/100, 2) AS refundAmount
FROM t_pay_order
WHERE 1=1
<if
test=
"state != null"
>
AND state = #{state}
</if>
<if
test=
"refundState == 0"
>
AND refund_state = #{refundState}
</if>
<if
test=
"refundState == 1"
>
AND refund_state = #{refundState}
</if>
<if
test=
"refundState == 2"
>
AND refund_state != 0
</if>
<if
test=
"mchNo != null"
>
AND mch_no = #{mchNo}
</if>
<if
test=
"createTimeStart != null"
>
AND created_at
>
= #{createTimeStart}
</if>
<if
test=
"createTimeEnd != null"
>
AND created_at
<
= #{createTimeEnd}
</if>
...
...
pom.xml
View file @
cf2a0c61
...
...
@@ -34,7 +34,7 @@
<properties>
<java.version>
1.8
</java.version>
<!-- 指定java版本号 -->
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<!-- 项目构建输出编码 -->
<isys.version>
1.
1.1
</isys.version>
<!-- 指定当前[项目]版本号 -->
<isys.version>
1.
2.0
</isys.version>
<!-- 指定当前[项目]版本号 -->
<!-- 其他工具包 -->
<jeepay.sdk.java.version>
1.1.0
</jeepay.sdk.java.version>
...
...
Prev
1
2
3
Next
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