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
de3de82d
Commit
de3de82d
authored
Jun 09, 2021
by
dingzhiwei
Browse files
初始化Jeepay项目
parent
40dcaf4a
Changes
453
Hide whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
20 of 453+
files are displayed.
Plain diff
Email patch
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/WxpayPayOrderQueryService.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest
;
import
com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult
;
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.pay.channel.IPayOrderQueryService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
org.springframework.stereotype.Service
;
/*
* 微信查单接口
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:10
*/
@Service
public
class
WxpayPayOrderQueryService
implements
IPayOrderQueryService
{
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
WXPAY
;
}
@Override
public
ChannelRetMsg
query
(
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
try
{
if
(
CS
.
PAY_IF_VERSION
.
WX_V2
.
equals
(
mchConfigContext
.
getWxServiceWrapper
().
getApiVersion
()))
{
//V2
WxPayOrderQueryRequest
req
=
new
WxPayOrderQueryRequest
();
//放置isv信息
WxpayKit
.
putApiIsvInfo
(
mchConfigContext
,
req
);
req
.
setOutTradeNo
(
payOrder
.
getPayOrderId
());
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
WxPayOrderQueryResult
result
=
wxPayService
.
queryOrder
(
req
);
if
(
"SUCCESS"
.
equals
(
result
.
getTradeState
())){
//支付成功
return
ChannelRetMsg
.
confirmSuccess
(
result
.
getTransactionId
());
}
else
if
(
"USERPAYING"
.
equals
(
result
.
getTradeState
())){
//支付中,等待用户输入密码
return
ChannelRetMsg
.
waiting
();
//支付中
}
else
if
(
"CLOSED"
.
equals
(
result
.
getTradeState
())
||
"REVOKED"
.
equals
(
result
.
getTradeState
())
||
"PAYERROR"
.
equals
(
result
.
getTradeState
())){
//CLOSED—已关闭, REVOKED—已撤销(刷卡支付), PAYERROR--支付失败(其他原因,如银行返回失败)
return
ChannelRetMsg
.
confirmFail
();
//支付失败
}
else
{
return
ChannelRetMsg
.
unknown
();
}
}
else
if
(
CS
.
PAY_IF_VERSION
.
WX_V3
.
equals
(
mchConfigContext
.
getWxServiceWrapper
().
getApiVersion
()))
{
//V3
JSONObject
resultJSON
=
WxpayV3Util
.
queryOrderV3
(
payOrder
.
getPayOrderId
(),
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
().
getConfig
());
String
channelState
=
resultJSON
.
getString
(
"trade_state"
);
if
(
"SUCCESS"
.
equals
(
channelState
))
{
return
ChannelRetMsg
.
confirmSuccess
(
resultJSON
.
getString
(
"transaction_id"
));
}
else
if
(
"USERPAYING"
.
equals
(
channelState
)){
//支付中,等待用户输入密码
return
ChannelRetMsg
.
waiting
();
//支付中
}
else
if
(
"CLOSED"
.
equals
(
channelState
)
||
"REVOKED"
.
equals
(
channelState
)
||
"PAYERROR"
.
equals
(
channelState
)){
//CLOSED—已关闭, REVOKED—已撤销(刷卡支付), PAYERROR--支付失败(其他原因,如银行返回失败)
return
ChannelRetMsg
.
confirmFail
();
//支付失败
}
else
{
return
ChannelRetMsg
.
unknown
();
}
}
else
{
return
ChannelRetMsg
.
unknown
();
}
}
catch
(
WxPayException
e
)
{
return
ChannelRetMsg
.
sysError
(
e
.
getReturnMsg
());
}
catch
(
Exception
e
)
{
return
ChannelRetMsg
.
sysError
(
e
.
getMessage
());
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/WxpayPaymentService.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
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.exception.BizException
;
import
com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvsubMchParams
;
import
com.jeequan.jeepay.pay.channel.AbstractPaymentService
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.util.PaywayUtil
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 支付接口: 微信官方
* 支付方式: 自适应
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:10
*/
@Service
public
class
WxpayPaymentService
extends
AbstractPaymentService
{
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
WXPAY
;
}
@Override
public
boolean
isSupport
(
String
wayCode
)
{
return
true
;
}
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
PaywayUtil
.
getRealPaywayService
(
this
,
payOrder
.
getWayCode
()).
preCheck
(
rq
,
payOrder
);
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
// 微信API版本
String
apiVersion
=
mchConfigContext
.
getWxServiceWrapper
().
getApiVersion
();
if
(
CS
.
PAY_IF_VERSION
.
WX_V2
.
equals
(
apiVersion
))
{
return
PaywayUtil
.
getRealPaywayService
(
this
,
payOrder
.
getWayCode
()).
pay
(
rq
,
payOrder
,
mchConfigContext
);
}
else
if
(
CS
.
PAY_IF_VERSION
.
WX_V3
.
equals
(
apiVersion
))
{
return
PaywayUtil
.
getRealPaywayV3Service
(
this
,
payOrder
.
getWayCode
()).
pay
(
rq
,
payOrder
,
mchConfigContext
);
}
else
{
throw
new
BizException
(
"不支持的微信支付API版本"
);
}
}
/**
* 构建微信统一下单请求数据
* @param payOrder
* @return
*/
public
WxPayUnifiedOrderRequest
buildUnifiedOrderRequest
(
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
String
payOrderId
=
payOrder
.
getPayOrderId
();
// 微信统一下单请求对象
WxPayUnifiedOrderRequest
request
=
new
WxPayUnifiedOrderRequest
();
request
.
setOutTradeNo
(
payOrderId
);
request
.
setBody
(
payOrder
.
getSubject
());
request
.
setDetail
(
payOrder
.
getBody
());
request
.
setFeeType
(
"CNY"
);
request
.
setTotalFee
(
payOrder
.
getAmount
().
intValue
());
request
.
setSpbillCreateIp
(
payOrder
.
getClientIp
());
request
.
setNotifyUrl
(
getNotifyUrl
());
request
.
setProductId
(
System
.
currentTimeMillis
()+
""
);
// 特约商户
if
(
mchConfigContext
.
isIsvsubMch
()){
WxpayIsvsubMchParams
isvsubMchParams
=
mchConfigContext
.
getIsvsubMchParamsByIfCode
(
getIfCode
(),
WxpayIsvsubMchParams
.
class
);
request
.
setSubMchId
(
isvsubMchParams
.
getSubMchId
());
request
.
setSubAppId
(
isvsubMchParams
.
getSubMchAppId
());
}
return
request
;
}
/**
* 构建微信APIV3接口 统一下单请求数据
* @param payOrder
* @return
*/
public
JSONObject
buildV3OrderRequest
(
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
String
payOrderId
=
payOrder
.
getPayOrderId
();
// 微信统一下单请求对象
JSONObject
reqJSON
=
new
JSONObject
();
reqJSON
.
put
(
"out_trade_no"
,
payOrderId
);
reqJSON
.
put
(
"description"
,
payOrder
.
getSubject
());
reqJSON
.
put
(
"notify_url"
,
getNotifyUrl
(
payOrderId
));
JSONObject
amount
=
new
JSONObject
();
amount
.
put
(
"total"
,
payOrder
.
getAmount
().
intValue
());
amount
.
put
(
"currency"
,
"CNY"
);
reqJSON
.
put
(
"amount"
,
amount
);
JSONObject
sceneInfo
=
new
JSONObject
();
sceneInfo
.
put
(
"payer_client_ip"
,
payOrder
.
getClientIp
());
reqJSON
.
put
(
"scene_info"
,
sceneInfo
);
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
WxpayIsvsubMchParams
isvsubMchParams
=
mchConfigContext
.
getIsvsubMchParamsByIfCode
(
getIfCode
(),
WxpayIsvsubMchParams
.
class
);
reqJSON
.
put
(
"sp_appid"
,
wxPayService
.
getConfig
().
getAppId
());
reqJSON
.
put
(
"sp_mchid"
,
wxPayService
.
getConfig
().
getMchId
());
reqJSON
.
put
(
"sub_mchid"
,
isvsubMchParams
.
getSubMchId
());
reqJSON
.
put
(
"sub_appid"
,
isvsubMchParams
.
getSubMchAppId
());
}
else
{
// 普通商户
reqJSON
.
put
(
"appid"
,
wxPayService
.
getConfig
().
getAppId
());
reqJSON
.
put
(
"mchid"
,
wxPayService
.
getConfig
().
getMchId
());
}
return
reqJSON
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/kits/WxpayKit.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.kits
;
import
com.github.binarywang.wxpay.bean.request.BaseWxPayRequest
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvsubMchParams
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.apache.commons.lang3.StringUtils
;
/*
* 【微信支付】支付通道工具包
*
* @author terrfly
* @site https://www.jeepay.vip
* @date 2021/6/8 17:21
*/
public
class
WxpayKit
{
/** 放置 isv特殊信息 **/
public
static
void
putApiIsvInfo
(
MchConfigContext
mchConfigContext
,
BaseWxPayRequest
req
){
//不是特约商户, 无需放置此值
if
(!
mchConfigContext
.
isIsvsubMch
()){
return
;
}
WxpayIsvsubMchParams
isvsubMchParams
=
mchConfigContext
.
getIsvsubMchParamsByIfCode
(
CS
.
IF_CODE
.
WXPAY
,
WxpayIsvsubMchParams
.
class
);
req
.
setSubMchId
(
isvsubMchParams
.
getSubMchId
());
req
.
setSubAppId
(
isvsubMchParams
.
getSubMchAppId
());
}
public
static
String
appendErrCode
(
String
code
,
String
subCode
){
return
StringUtils
.
defaultIfEmpty
(
subCode
,
code
);
//优先: subCode
}
public
static
String
appendErrMsg
(
String
msg
,
String
subMsg
){
if
(
StringUtils
.
isNotEmpty
(
msg
)
&&
StringUtils
.
isNotEmpty
(
subMsg
)
){
return
msg
+
"【"
+
subMsg
+
"】"
;
}
return
StringUtils
.
defaultIfEmpty
(
subMsg
,
msg
);
}
public
static
void
commonSetErrInfo
(
ChannelRetMsg
channelRetMsg
,
WxPayException
wxPayException
){
channelRetMsg
.
setChannelErrCode
(
appendErrCode
(
wxPayException
.
getReturnCode
(),
wxPayException
.
getErrCode
()
));
channelRetMsg
.
setChannelErrMsg
(
appendErrMsg
(
"OK"
.
equalsIgnoreCase
(
wxPayException
.
getReturnMsg
())
?
null
:
wxPayException
.
getReturnMsg
(),
wxPayException
.
getErrCodeDes
()
));
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/kits/WxpayV3Util.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.kits
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.config.WxPayConfig
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder
;
import
com.github.binarywang.wxpay.v3.auth.AutoUpdateCertificatesVerifier
;
import
com.github.binarywang.wxpay.v3.auth.PrivateKeySigner
;
import
com.github.binarywang.wxpay.v3.auth.WxPayCredentials
;
import
com.github.binarywang.wxpay.v3.auth.WxPayValidator
;
import
com.github.binarywang.wxpay.v3.util.PemUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.http.HttpStatus
;
import
org.apache.http.client.config.RequestConfig
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.apache.http.client.methods.HttpGet
;
import
org.apache.http.client.methods.HttpPost
;
import
org.apache.http.entity.ContentType
;
import
org.apache.http.entity.StringEntity
;
import
org.apache.http.impl.client.CloseableHttpClient
;
import
org.apache.http.util.EntityUtils
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.charset.StandardCharsets
;
import
java.security.PrivateKey
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @Author: ZhuXiao
* @Description:
* @Date: 15:22 2021/5/26
*/
@Slf4j
public
class
WxpayV3Util
{
private
static
final
String
PAY_BASE_URL
=
"https://api.mch.weixin.qq.com"
;
public
static
final
Map
<
String
,
String
>
NORMALMCH_URL_MAP
=
new
HashMap
<>();
static
{
NORMALMCH_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
APP
,
"/v3/pay/transactions/app"
);
NORMALMCH_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
JSAPI
,
"/v3/pay/transactions/jsapi"
);
NORMALMCH_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
NATIVE
,
"/v3/pay/transactions/native"
);
NORMALMCH_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
MWEB
,
"/v3/pay/transactions/h5"
);
}
public
static
final
Map
<
String
,
String
>
ISV_URL_MAP
=
new
HashMap
<>();
static
{
ISV_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
APP
,
"/v3/pay/partner/transactions/app"
);
ISV_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
JSAPI
,
"/v3/pay/partner/transactions/jsapi"
);
ISV_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
NATIVE
,
"/v3/pay/partner/transactions/native"
);
ISV_URL_MAP
.
put
(
WxPayConstants
.
TradeType
.
MWEB
,
"/v3/pay/partner/transactions/h5"
);
}
public
static
JSONObject
unifiedOrderV3
(
String
url
,
JSONObject
reqJSON
,
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
String
response
=
postV3
(
PAY_BASE_URL
+
url
,
reqJSON
.
toJSONString
(),
wxPayConfig
);
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
);
return
JSON
.
parseObject
(
response
);
}
public
static
String
postV3
(
String
url
,
String
requestStr
,
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
CloseableHttpClient
httpClient
=
createApiV3HttpClient
(
wxPayConfig
);
HttpPost
httpPost
=
createHttpPost
(
url
,
requestStr
);
httpPost
.
addHeader
(
"Accept"
,
"application/json"
);
httpPost
.
addHeader
(
"Content-Type"
,
"application/json"
);
try
(
CloseableHttpResponse
response
=
httpClient
.
execute
(
httpPost
))
{
//v3已经改为通过状态码判断200 204 成功
int
statusCode
=
response
.
getStatusLine
().
getStatusCode
();
//post方法有可能会没有返回值的情况
String
responseString
;
if
(
response
.
getEntity
()
==
null
)
{
responseString
=
null
;
}
else
{
responseString
=
EntityUtils
.
toString
(
response
.
getEntity
(),
StandardCharsets
.
UTF_8
);
}
log
.
info
(
"\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}"
,
url
,
requestStr
,
responseString
);
if
(
HttpStatus
.
SC_OK
==
statusCode
||
HttpStatus
.
SC_NO_CONTENT
==
statusCode
)
{
return
responseString
;
}
else
{
//有错误提示信息返回
JSONObject
jsonObject
=
JSON
.
parseObject
(
responseString
);
WxPayException
wxPayException
=
new
WxPayException
(
jsonObject
.
getString
(
"message"
));
wxPayException
.
setErrCode
(
jsonObject
.
getString
(
"code"
));
wxPayException
.
setErrCodeDes
(
jsonObject
.
getString
(
"message"
));
throw
wxPayException
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"\n【异常信息】:{}"
,
e
.
getMessage
());
throw
(
e
instanceof
WxPayException
)
?
(
WxPayException
)
e
:
new
WxPayException
(
e
.
getMessage
(),
e
);
}
finally
{
httpPost
.
releaseConnection
();
}
}
public
static
String
getV3
(
String
url
,
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
HttpGet
httpGet
=
new
HttpGet
(
url
);
httpGet
.
addHeader
(
"Accept"
,
"application/json"
);
httpGet
.
addHeader
(
"Content-Type"
,
"application/json"
);
httpGet
.
setConfig
(
RequestConfig
.
custom
()
.
setConnectionRequestTimeout
(
5000
)
.
setConnectTimeout
(
5000
)
.
setSocketTimeout
(
10000
)
.
build
());
CloseableHttpClient
httpClient
=
createApiV3HttpClient
(
wxPayConfig
);
try
(
CloseableHttpResponse
response
=
httpClient
.
execute
(
httpGet
))
{
//v3已经改为通过状态码判断200 204 成功
int
statusCode
=
response
.
getStatusLine
().
getStatusCode
();
//post方法有可能会没有返回值的情况
String
responseString
;
if
(
response
.
getEntity
()
==
null
)
{
responseString
=
null
;
}
else
{
responseString
=
EntityUtils
.
toString
(
response
.
getEntity
(),
StandardCharsets
.
UTF_8
);
}
if
(
HttpStatus
.
SC_OK
==
statusCode
||
HttpStatus
.
SC_NO_CONTENT
==
statusCode
)
{
log
.
info
(
"\n【请求地址】:{}\n【响应数据】:{}"
,
url
,
responseString
);
return
responseString
;
}
else
{
//有错误提示信息返回
JSONObject
jsonObject
=
JSON
.
parseObject
(
responseString
);
WxPayException
wxPayException
=
new
WxPayException
(
jsonObject
.
getString
(
"message"
));
wxPayException
.
setErrCode
(
jsonObject
.
getString
(
"code"
));
wxPayException
.
setErrCodeDes
(
jsonObject
.
getString
(
"message"
));
throw
wxPayException
;
}
}
catch
(
Exception
e
)
{
log
.
error
(
"\n【异常信息】:{}"
,
url
,
e
.
getMessage
());
throw
(
e
instanceof
WxPayException
)
?
(
WxPayException
)
e
:
new
WxPayException
(
e
.
getMessage
(),
e
);
}
finally
{
httpGet
.
releaseConnection
();
}
}
private
static
CloseableHttpClient
createApiV3HttpClient
(
WxPayConfig
wxPayConfig
)
throws
WxPayException
{
try
{
// 自动获取微信平台证书
PrivateKey
privateKey
=
PemUtils
.
loadPrivateKey
(
new
FileInputStream
(
wxPayConfig
.
getPrivateKeyPath
()));
AutoUpdateCertificatesVerifier
verifier
=
new
AutoUpdateCertificatesVerifier
(
new
WxPayCredentials
(
wxPayConfig
.
getMchId
(),
new
PrivateKeySigner
(
wxPayConfig
.
getCertSerialNo
(),
privateKey
)),
wxPayConfig
.
getApiV3Key
().
getBytes
(
"utf-8"
));
WxPayV3HttpClientBuilder
builder
=
WxPayV3HttpClientBuilder
.
create
()
.
withMerchant
(
wxPayConfig
.
getMchId
(),
wxPayConfig
.
getCertSerialNo
(),
privateKey
)
.
withValidator
(
new
WxPayValidator
(
verifier
));
CloseableHttpClient
apiV3HttpClient
=
builder
.
build
();
return
apiV3HttpClient
;
}
catch
(
FileNotFoundException
|
UnsupportedEncodingException
e
)
{
log
.
error
(
""
,
e
);
}
CloseableHttpClient
apiV3HttpClient
=
wxPayConfig
.
getApiV3HttpClient
();
if
(
null
==
apiV3HttpClient
)
{
return
wxPayConfig
.
initApiV3HttpClient
();
}
return
null
;
}
private
static
HttpPost
createHttpPost
(
String
url
,
String
requestStr
)
{
HttpPost
httpPost
=
new
HttpPost
(
url
);
httpPost
.
setEntity
(
new
StringEntity
(
requestStr
,
ContentType
.
create
(
"application/json"
,
"utf-8"
)));
httpPost
.
setConfig
(
RequestConfig
.
custom
()
.
setConnectionRequestTimeout
(
5000
)
.
setConnectTimeout
(
5000
)
.
setSocketTimeout
(
10000
)
.
build
());
return
httpPost
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxApp.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxAppOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 app支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByAppService"
)
//Service Name需保持全局唯一性
public
class
WxApp
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxPayUnifiedOrderRequest
req
=
buildUnifiedOrderRequest
(
payOrder
,
mchConfigContext
);
req
.
setTradeType
(
WxPayConstants
.
TradeType
.
APP
);
// 构造函数响应数据
WxAppOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxAppOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayAppOrderResult
payResult
=
wxPayService
.
createOrder
(
req
);
JSONObject
resJSON
=
(
JSONObject
)
JSON
.
toJSON
(
payResult
);
resJSON
.
put
(
"package"
,
payResult
.
getPackageValue
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxBar.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest
;
import
com.github.binarywang.wxpay.bean.result.WxPayMicropayResult
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxBarOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxBarOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
/*
* 微信 bar
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByBarService"
)
//Service Name需保持全局唯一性
public
class
WxBar
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
WxBarOrderRQ
bizRQ
=
(
WxBarOrderRQ
)
rq
;
if
(
StringUtils
.
isEmpty
(
bizRQ
.
getAuthCode
())){
throw
new
BizException
(
"用户支付条码[authCode]不可为空"
);
}
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxBarOrderRQ
bizRQ
=
(
WxBarOrderRQ
)
rq
;
// 微信统一下单请求对象
WxPayMicropayRequest
request
=
new
WxPayMicropayRequest
();
request
.
setOutTradeNo
(
payOrder
.
getPayOrderId
());
request
.
setBody
(
payOrder
.
getSubject
());
request
.
setDetail
(
payOrder
.
getBody
());
request
.
setFeeType
(
"CNY"
);
request
.
setTotalFee
(
payOrder
.
getAmount
().
intValue
());
request
.
setSpbillCreateIp
(
payOrder
.
getClientIp
());
request
.
setAuthCode
(
bizRQ
.
getAuthCode
());
//放置isv信息
WxpayKit
.
putApiIsvInfo
(
mchConfigContext
,
request
);
// 构造函数响应数据
WxBarOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxBarOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayMicropayResult
wxPayMicropayResult
=
wxPayService
.
micropay
(
request
);
channelRetMsg
.
setChannelOrderId
(
wxPayMicropayResult
.
getTransactionId
());
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
);
}
catch
(
WxPayException
e
)
{
//微信返回支付状态为【支付结果未知】, 需进行查单操作
if
(
"SYSTEMERROR"
.
equals
(
e
.
getErrCode
())
||
"USERPAYING"
.
equals
(
e
.
getErrCode
())
||
"BANKERROR"
.
equals
(
e
.
getErrCode
())){
//轮询查询订单
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
channelRetMsg
.
setNeedQuery
(
true
);
}
else
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxH5.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
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.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxH5OrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxH5OrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 H5 支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByH5Service"
)
//Service Name需保持全局唯一性
public
class
WxH5
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
WxH5OrderRQ
bizRQ
=
(
WxH5OrderRQ
)
rq
;
WxPayUnifiedOrderRequest
req
=
buildUnifiedOrderRequest
(
payOrder
,
mchConfigContext
);
req
.
setTradeType
(
WxPayConstants
.
TradeType
.
MWEB
);
// 构造函数响应数据
WxH5OrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxH5OrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayMwebOrderResult
wxPayMwebOrderResult
=
wxPayService
.
createOrder
(
req
);
String
payUrl
=
wxPayMwebOrderResult
.
getMwebUrl
();
if
(
CS
.
PAY_DATA_TYPE
.
FORM
.
equals
(
bizRQ
.
getPayDataType
())){
//表单方式
res
.
setFormContent
(
payUrl
);
}
else
if
(
CS
.
PAY_DATA_TYPE
.
CODE_IMG_URL
.
equals
(
bizRQ
.
getPayDataType
())){
//二维码图片地址
res
.
setCodeImgUrl
(
sysConfigService
.
getDBApplicationConfig
().
genScanImgUrl
(
payUrl
));
}
else
{
// 默认都为 payUrl方式
res
.
setPayUrl
(
payUrl
);
}
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxJsapi.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
/*
* 微信 jsapi支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByJsapiService"
)
//Service Name需保持全局唯一性
@Slf4j
public
class
WxJsapi
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
if
(
StringUtils
.
isEmpty
(
bizRQ
.
getOpenid
())){
throw
new
BizException
(
"[openid]不可为空"
);
}
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
WxPayUnifiedOrderRequest
req
=
buildUnifiedOrderRequest
(
payOrder
,
mchConfigContext
);
req
.
setTradeType
(
WxPayConstants
.
TradeType
.
JSAPI
);
req
.
setOpenid
(
bizRQ
.
getOpenid
());
// 构造函数响应数据
WxJsapiOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxJsapiOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayMpOrderResult
payResult
=
wxPayService
.
createOrder
(
req
);
JSONObject
resJSON
=
(
JSONObject
)
JSON
.
toJSON
(
payResult
);
resJSON
.
put
(
"package"
,
payResult
.
getPackageValue
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
log
.
error
(
"WxPayException:"
,
e
);
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxLite.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
/*
* 微信 小程序支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByLiteService"
)
//Service Name需保持全局唯一性
public
class
WxLite
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
if
(
StringUtils
.
isEmpty
(
bizRQ
.
getOpenid
())){
throw
new
BizException
(
"[openid]不可为空"
);
}
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
WxPayUnifiedOrderRequest
req
=
buildUnifiedOrderRequest
(
payOrder
,
mchConfigContext
);
req
.
setTradeType
(
WxPayConstants
.
TradeType
.
JSAPI
);
req
.
setOpenid
(
bizRQ
.
getOpenid
());
// 构造函数响应数据
WxJsapiOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxJsapiOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayMpOrderResult
payResult
=
wxPayService
.
createOrder
(
req
);
JSONObject
resJSON
=
(
JSONObject
)
JSON
.
toJSON
(
payResult
);
resJSON
.
put
(
"package"
,
payResult
.
getPackageValue
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/payway/WxNative.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.payway
;
import
com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult
;
import
com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
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.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxNativeOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxNativeOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 native支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByNativeService"
)
//Service Name需保持全局唯一性
public
class
WxNative
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxNativeOrderRQ
bizRQ
=
(
WxNativeOrderRQ
)
rq
;
WxPayUnifiedOrderRequest
req
=
buildUnifiedOrderRequest
(
payOrder
,
mchConfigContext
);
req
.
setTradeType
(
WxPayConstants
.
TradeType
.
NATIVE
);
// 构造函数响应数据
WxNativeOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxNativeOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
try
{
WxPayNativeOrderResult
wxPayNativeOrderResult
=
wxPayService
.
createOrder
(
req
);
String
codeUrl
=
wxPayNativeOrderResult
.
getCodeUrl
();
if
(
CS
.
PAY_DATA_TYPE
.
CODE_IMG_URL
.
equals
(
bizRQ
.
getPayDataType
())){
//二维码图片地址
res
.
setCodeImgUrl
(
sysConfigService
.
getDBApplicationConfig
().
genScanImgUrl
(
codeUrl
));
}
else
{
res
.
setCodeUrl
(
codeUrl
);
}
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxApp.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxAppOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 app支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByAppV3Service"
)
//Service Name需保持全局唯一性
public
class
WxApp
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
// 构造请求数据
JSONObject
reqJSON
=
buildV3OrderRequest
(
payOrder
,
mchConfigContext
);
String
reqUrl
;
// 请求地址
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
reqUrl
=
WxpayV3Util
.
ISV_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
APP
);
}
else
{
reqUrl
=
WxpayV3Util
.
NORMALMCH_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
APP
);
}
// 构造函数响应数据
WxAppOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxAppOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
try
{
JSONObject
resJSON
=
WxpayV3Util
.
unifiedOrderV3
(
reqUrl
,
reqJSON
,
wxPayService
.
getConfig
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxBar.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
/*
* 微信 条码支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByBarV3Service"
)
//Service Name需保持全局唯一性
public
class
WxBar
extends
WxpayPaymentService
{
@Autowired
private
com
.
jeequan
.
jeepay
.
pay
.
channel
.
wxpay
.
payway
.
WxBar
wxBar
;
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
wxBar
.
preCheck
(
rq
,
payOrder
);
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
return
wxBar
.
pay
(
rq
,
payOrder
,
mchConfigContext
);
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxH5.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
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.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxH5OrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxH5OrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 H5支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByH5V3Service"
)
//Service Name需保持全局唯一性
public
class
WxH5
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
WxH5OrderRQ
bizRQ
=
(
WxH5OrderRQ
)
rq
;
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
// 构造请求数据
JSONObject
reqJSON
=
buildV3OrderRequest
(
payOrder
,
mchConfigContext
);
JSONObject
sceneInfo
=
reqJSON
.
getJSONObject
(
"scene_info"
);
JSONObject
h5Info
=
new
JSONObject
();
h5Info
.
put
(
"type"
,
"iOS, Android, Wap"
);
sceneInfo
.
put
(
"h5_info"
,
h5Info
);
reqJSON
.
put
(
"scene_info"
,
sceneInfo
);
String
reqUrl
;
// 请求地址
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
reqUrl
=
WxpayV3Util
.
ISV_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
MWEB
);
}
else
{
reqUrl
=
WxpayV3Util
.
NORMALMCH_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
MWEB
);
}
// 构造函数响应数据
WxH5OrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxH5OrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
try
{
JSONObject
resJSON
=
WxpayV3Util
.
unifiedOrderV3
(
reqUrl
,
reqJSON
,
wxPayService
.
getConfig
());
String
payUrl
=
resJSON
.
getString
(
"h5_url"
);
if
(
CS
.
PAY_DATA_TYPE
.
CODE_IMG_URL
.
equals
(
bizRQ
.
getPayDataType
())){
//二维码图片地址
res
.
setCodeImgUrl
(
sysConfigService
.
getDBApplicationConfig
().
genScanImgUrl
(
payUrl
));
}
else
{
// 默认都为 payUrl方式
res
.
setPayUrl
(
payUrl
);
}
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxJsapi.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 jsapi支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByJsapiV3Service"
)
//Service Name需保持全局唯一性
public
class
WxJsapi
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
// 使用的是V2接口的预先校验
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
// 构造请求数据
JSONObject
reqJSON
=
buildV3OrderRequest
(
payOrder
,
mchConfigContext
);
String
reqUrl
;
// 请求地址
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
reqUrl
=
WxpayV3Util
.
ISV_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
JSAPI
);
JSONObject
payer
=
new
JSONObject
();
payer
.
put
(
"sp_openid"
,
bizRQ
.
getOpenid
());
reqJSON
.
put
(
"payer"
,
payer
);
}
else
{
reqUrl
=
WxpayV3Util
.
NORMALMCH_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
JSAPI
);
JSONObject
payer
=
new
JSONObject
();
payer
.
put
(
"openid"
,
bizRQ
.
getOpenid
());
reqJSON
.
put
(
"payer"
,
payer
);
}
// 构造函数响应数据
WxJsapiOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxJsapiOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
try
{
JSONObject
resJSON
=
WxpayV3Util
.
unifiedOrderV3
(
reqUrl
,
reqJSON
,
wxPayService
.
getConfig
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxLite.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
import
com.github.binarywang.wxpay.exception.WxPayException
;
import
com.github.binarywang.wxpay.service.WxPayService
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxJsapiOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.springframework.stereotype.Service
;
/*
* 微信 小程序
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByLiteV3Service"
)
//Service Name需保持全局唯一性
public
class
WxLite
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
// 使用的是V2接口的预先校验
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
WxJsapiOrderRQ
bizRQ
=
(
WxJsapiOrderRQ
)
rq
;
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
// 构造请求数据
JSONObject
reqJSON
=
buildV3OrderRequest
(
payOrder
,
mchConfigContext
);
String
reqUrl
;
// 请求地址
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
reqUrl
=
WxpayV3Util
.
ISV_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
JSAPI
);
JSONObject
payer
=
new
JSONObject
();
payer
.
put
(
"sp_openid"
,
bizRQ
.
getOpenid
());
reqJSON
.
put
(
"payer"
,
payer
);
}
else
{
reqUrl
=
WxpayV3Util
.
NORMALMCH_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
JSAPI
);
JSONObject
payer
=
new
JSONObject
();
payer
.
put
(
"openid"
,
bizRQ
.
getOpenid
());
reqJSON
.
put
(
"payer"
,
payer
);
}
// 构造函数响应数据
WxJsapiOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxJsapiOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
try
{
JSONObject
resJSON
=
WxpayV3Util
.
unifiedOrderV3
(
reqUrl
,
reqJSON
,
wxPayService
.
getConfig
());
res
.
setPayInfo
(
resJSON
.
toJSONString
());
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/wxpay/paywayV3/WxNative.java
0 → 100644
View file @
de3de82d
/*
* 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.wxpay.paywayV3
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.binarywang.wxpay.constant.WxPayConstants
;
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.pay.channel.wxpay.WxpayPaymentService
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayKit
;
import
com.jeequan.jeepay.pay.channel.wxpay.kits.WxpayV3Util
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxNativeOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.WxNativeOrderRS
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
org.springframework.stereotype.Service
;
/*
* 微信 native支付
*
* @author zhuxiao
* @site https://www.jeepay.vip
* @date 2021/6/8 18:08
*/
@Service
(
"wxpayPaymentByNativeV3Service"
)
//Service Name需保持全局唯一性
public
class
WxNative
extends
WxpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
{
WxNativeOrderRQ
bizRQ
=
(
WxNativeOrderRQ
)
rq
;
WxPayService
wxPayService
=
mchConfigContext
.
getWxServiceWrapper
().
getWxPayService
();
// 构造请求数据
JSONObject
reqJSON
=
buildV3OrderRequest
(
payOrder
,
mchConfigContext
);
String
reqUrl
;
// 请求地址
if
(
mchConfigContext
.
isIsvsubMch
()){
// 特约商户
reqUrl
=
WxpayV3Util
.
ISV_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
NATIVE
);
}
else
{
reqUrl
=
WxpayV3Util
.
NORMALMCH_URL_MAP
.
get
(
WxPayConstants
.
TradeType
.
NATIVE
);
}
// 构造函数响应数据
WxNativeOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
WxNativeOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
// 调起上游接口:
// 1. 如果抛异常,则订单状态为: 生成状态,此时没有查单处理操作。 订单将超时关闭
// 2. 接口调用成功, 后续异常需进行捕捉, 如果 逻辑代码出现异常则需要走完正常流程,此时订单状态为: 支付中, 需要查单处理。
try
{
JSONObject
resJSON
=
WxpayV3Util
.
unifiedOrderV3
(
reqUrl
,
reqJSON
,
wxPayService
.
getConfig
());
String
codeUrl
=
resJSON
.
getString
(
"code_url"
);
if
(
CS
.
PAY_DATA_TYPE
.
CODE_IMG_URL
.
equals
(
bizRQ
.
getPayDataType
())){
//二维码图片地址
res
.
setCodeImgUrl
(
sysConfigService
.
getDBApplicationConfig
().
genScanImgUrl
(
codeUrl
));
}
else
{
res
.
setCodeUrl
(
codeUrl
);
}
// 支付中
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
}
catch
(
WxPayException
e
)
{
//明确失败
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
WxpayKit
.
commonSetErrInfo
(
channelRetMsg
,
e
);
}
return
res
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/ysfpay/YsfpayChannelNoticeService.java
0 → 100644
View file @
de3de82d
/*
* 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.ysfpay
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.ResponseException
;
import
com.jeequan.jeepay.core.model.params.ysf.YsfpayIsvParams
;
import
com.jeequan.jeepay.pay.channel.AbstractChannelNoticeService
;
import
com.jeequan.jeepay.pay.channel.ysfpay.utils.YsfSignUtils
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.model.IsvConfigContext
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.tuple.MutablePair
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.stereotype.Service
;
import
javax.servlet.http.HttpServletRequest
;
/**
* 云闪付回调
*
* @author pangxiaoyu
* @site https://www.jeepay.vip
* @date 2021-06-07 07:15
*/
@Service
@Slf4j
public
class
YsfpayChannelNoticeService
extends
AbstractChannelNoticeService
{
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
YSFPAY
;
}
@Override
public
MutablePair
<
String
,
Object
>
parseParams
(
HttpServletRequest
request
,
String
urlOrderId
,
NoticeTypeEnum
noticeTypeEnum
)
{
try
{
JSONObject
params
=
getReqParamJSON
();
String
payOrderId
=
params
.
getString
(
"orderNo"
);
return
MutablePair
.
of
(
payOrderId
,
params
);
}
catch
(
Exception
e
)
{
log
.
error
(
"error"
,
e
);
throw
ResponseException
.
buildText
(
"ERROR"
);
}
}
@Override
public
ChannelRetMsg
doNotice
(
HttpServletRequest
request
,
Object
params
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
,
NoticeTypeEnum
noticeTypeEnum
)
{
try
{
ChannelRetMsg
result
=
ChannelRetMsg
.
confirmSuccess
(
null
);
String
logPrefix
=
"【处理云闪付支付回调】"
;
// 获取请求参数
JSONObject
jsonParams
=
(
JSONObject
)
params
;
log
.
info
(
"{} 回调参数, jsonParams:{}"
,
logPrefix
,
jsonParams
);
// 校验支付回调
boolean
verifyResult
=
verifyParams
(
jsonParams
,
payOrder
,
mchConfigContext
.
getIsvConfigContext
());
// 验证参数失败
if
(!
verifyResult
){
throw
ResponseException
.
buildText
(
"ERROR"
);
}
log
.
info
(
"{}验证支付通知数据及签名通过"
,
logPrefix
);
//验签成功后判断上游订单状态
ResponseEntity
okResponse
=
textResp
(
"success"
);
result
.
setResponseEntity
(
okResponse
);
result
.
setChannelOrderId
(
jsonParams
.
getString
(
"transIndex"
));
return
result
;
}
catch
(
Exception
e
)
{
log
.
error
(
"error"
,
e
);
throw
ResponseException
.
buildText
(
"ERROR"
);
}
}
/**
* 验证云闪付支付通知参数
* @return
*/
public
boolean
verifyParams
(
JSONObject
jsonParams
,
PayOrder
payOrder
,
IsvConfigContext
isvConfigContext
)
{
String
orderNo
=
jsonParams
.
getString
(
"orderNo"
);
// 商户订单号
String
txnAmt
=
jsonParams
.
getString
(
"txnAmt"
);
// 支付金额
if
(
StringUtils
.
isEmpty
(
orderNo
))
{
log
.
info
(
"订单ID为空 [orderNo]={}"
,
orderNo
);
return
false
;
}
if
(
StringUtils
.
isEmpty
(
txnAmt
))
{
log
.
info
(
"金额参数为空 [txnAmt] :{}"
,
txnAmt
);
return
false
;
}
YsfpayIsvParams
isvParams
=
isvConfigContext
.
getIsvParamsByIfCode
(
getIfCode
(),
YsfpayIsvParams
.
class
);
//验签
String
ysfpayPublicKey
=
isvParams
.
getYsfpayPublicKey
();
//验签失败
if
(!
YsfSignUtils
.
validate
((
JSONObject
)
JSONObject
.
toJSON
(
jsonParams
),
ysfpayPublicKey
))
{
log
.
info
(
"【云闪付回调】 验签失败! 回调参数:parameter = {}, ysfpayPublicKey={} "
,
jsonParams
,
ysfpayPublicKey
);
return
false
;
}
// 核对金额
long
dbPayAmt
=
payOrder
.
getAmount
().
longValue
();
if
(
dbPayAmt
!=
Long
.
parseLong
(
txnAmt
))
{
log
.
info
(
"订单金额与参数金额不符。 dbPayAmt={}, txnAmt={}, payOrderId={}"
,
dbPayAmt
,
txnAmt
,
orderNo
);
return
false
;
}
return
true
;
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/ysfpay/YsfpayPayOrderQueryService.java
0 → 100644
View file @
de3de82d
/*
* 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.ysfpay
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.pay.channel.IPayOrderQueryService
;
import
com.jeequan.jeepay.pay.channel.ysfpay.utils.YsfHttpUtil
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
/**
* 云闪付查单
*
* @author pangxiaoyu
* @site https://www.jeepay.vip
* @date 2021-06-07 07:15
*/
@Service
@Slf4j
public
class
YsfpayPayOrderQueryService
implements
IPayOrderQueryService
{
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
YSFPAY
;
}
@Autowired
private
YsfpayPaymentService
ysfpayPaymentService
;
@Override
public
ChannelRetMsg
query
(
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
JSONObject
reqParams
=
new
JSONObject
();
String
orderType
=
YsfHttpUtil
.
getOrderTypeByCommon
(
payOrder
.
getWayCode
());
String
logPrefix
=
"【云闪付("
+
orderType
+
")查单】"
;
try
{
reqParams
.
put
(
"orderNo"
,
payOrder
.
getPayOrderId
());
//订单号
reqParams
.
put
(
"orderType"
,
orderType
);
//订单类型
//封装公共参数 & 签名 & 调起http请求 & 返回响应数据并包装为json格式。
JSONObject
resJSON
=
ysfpayPaymentService
.
packageParamAndReq
(
"/gateway/api/pay/queryOrder"
,
reqParams
,
logPrefix
,
mchConfigContext
.
getIsvConfigContext
(),
mchConfigContext
);
log
.
info
(
"查询订单 payorderId:{}, 返回结果:{}"
,
payOrder
.
getPayOrderId
(),
resJSON
);
if
(
resJSON
==
null
){
return
ChannelRetMsg
.
waiting
();
//支付中
}
//请求 & 响应成功, 判断业务逻辑
String
respCode
=
resJSON
.
getString
(
"respCode"
);
//应答码
String
origRespCode
=
resJSON
.
getString
(
"origRespCode"
);
//原交易应答码
String
respMsg
=
resJSON
.
getString
(
"respMsg"
);
//应答信息
if
((
"00"
).
equals
(
respCode
)){
//如果查询交易成功
//00- 支付成功 01- 转入退款 02- 未支付 03- 已关闭 04- 已撤销(付款码支付) 05- 用户支付中 06- 支付失败
if
((
"00"
).
equals
(
origRespCode
)){
//交易成功,更新商户订单状态
return
ChannelRetMsg
.
confirmSuccess
(
resJSON
.
getString
(
"transIndex"
));
//支付成功
}
else
if
(
"02"
.
equals
(
origRespCode
)
||
"05"
.
equals
(
origRespCode
)
)
{
return
ChannelRetMsg
.
waiting
();
//支付中
}
}
return
ChannelRetMsg
.
waiting
();
//支付中
}
catch
(
Exception
e
)
{
return
ChannelRetMsg
.
waiting
();
//支付中
}
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/ysfpay/YsfpayPaymentService.java
0 → 100644
View file @
de3de82d
/*
* 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.ysfpay
;
import
cn.hutool.core.date.DatePattern
;
import
cn.hutool.core.date.DateUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.constants.CS
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.core.model.params.ysf.YsfpayConfig
;
import
com.jeequan.jeepay.core.model.params.ysf.YsfpayIsvParams
;
import
com.jeequan.jeepay.core.model.params.ysf.YsfpayIsvsubMchParams
;
import
com.jeequan.jeepay.pay.channel.AbstractPaymentService
;
import
com.jeequan.jeepay.pay.channel.ysfpay.utils.YsfHttpUtil
;
import
com.jeequan.jeepay.pay.channel.ysfpay.utils.YsfSignUtils
;
import
com.jeequan.jeepay.pay.config.SystemYmlConfig
;
import
com.jeequan.jeepay.pay.model.IsvConfigContext
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.util.PaywayUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.io.File
;
import
java.util.Date
;
/**
* 云闪付下单
*
* @author pangxiaoyu
* @site https://www.jeepay.vip
* @date 2021-06-07 07:15
*/
@Service
@Slf4j
public
class
YsfpayPaymentService
extends
AbstractPaymentService
{
@Autowired
private
SystemYmlConfig
mainConfig
;
@Override
public
String
getIfCode
()
{
return
CS
.
IF_CODE
.
YSFPAY
;
}
@Override
public
boolean
isSupport
(
String
wayCode
)
{
return
true
;
}
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
return
PaywayUtil
.
getRealPaywayService
(
this
,
payOrder
.
getWayCode
()).
preCheck
(
rq
,
payOrder
);
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
return
PaywayUtil
.
getRealPaywayService
(
this
,
payOrder
.
getWayCode
()).
pay
(
rq
,
payOrder
,
mchConfigContext
);
}
/** 封装参数 & 统一请求 **/
public
JSONObject
packageParamAndReq
(
String
apiUri
,
JSONObject
reqParams
,
String
logPrefix
,
IsvConfigContext
isvConfigContext
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
YsfpayIsvParams
isvParams
=
isvConfigContext
.
getIsvParamsByIfCode
(
getIfCode
(),
YsfpayIsvParams
.
class
);
if
(
isvParams
.
getSerProvId
()
==
null
)
{
log
.
error
(
"服务商配置为空:isvParams:{}"
,
isvParams
);
throw
new
BizException
(
"服务商配置为空。"
);
}
reqParams
.
put
(
"serProvId"
,
isvParams
.
getSerProvId
());
//云闪付服务商标识
YsfpayIsvsubMchParams
isvsubMchParams
=
mchConfigContext
.
getIsvsubMchParamsByIfCode
(
getIfCode
(),
YsfpayIsvsubMchParams
.
class
);
reqParams
.
put
(
"merId"
,
isvsubMchParams
.
getMerId
());
// 商户号
//签名
String
isvPrivateCertFile
=
channelCertConfigKitBean
.
getCertFilePath
(
isvParams
.
getIsvPrivateCertFile
());
String
isvPrivateCertPwd
=
isvParams
.
getIsvPrivateCertPwd
();
reqParams
.
put
(
"signature"
,
YsfSignUtils
.
signBy256
(
reqParams
,
isvPrivateCertFile
,
isvPrivateCertPwd
));
//RSA 签名串
// 调起上游接口
log
.
info
(
"{} reqJSON={}"
,
logPrefix
,
reqParams
);
String
resText
=
YsfHttpUtil
.
doPostJson
(
getYsfpayHost4env
(
isvParams
)
+
apiUri
,
null
,
reqParams
);
log
.
info
(
"{} resJSON={}"
,
logPrefix
,
resText
);
if
(
StringUtils
.
isEmpty
(
resText
)){
return
null
;
}
return
JSONObject
.
parseObject
(
resText
);
}
/** 获取云闪付正式环境/沙箱HOST地址 **/
public
static
String
getYsfpayHost4env
(
YsfpayIsvParams
isvParams
){
return
CS
.
YES
==
isvParams
.
getSandbox
()
?
YsfpayConfig
.
SANDBOX_SERVER_URL
:
YsfpayConfig
.
PROD_SERVER_URL
;
}
/** 云闪付 jsapi下单请求统一发送参数 **/
public
static
void
jsapiParamsSet
(
JSONObject
reqParams
,
PayOrder
payOrder
,
String
notifyUrl
,
String
returnUrl
)
{
String
orderType
=
YsfHttpUtil
.
getOrderTypeByJSapi
(
payOrder
.
getWayCode
());
reqParams
.
put
(
"orderType"
,
orderType
);
//订单类型: alipayJs-支付宝, wechatJs-微信支付, upJs-银联二维码
ysfPublicParams
(
reqParams
,
payOrder
);
reqParams
.
put
(
"backUrl"
,
notifyUrl
);
//交易通知地址
reqParams
.
put
(
"frontUrl"
,
returnUrl
);
//前台通知地址
}
/** 云闪付 bar下单请求统一发送参数 **/
public
static
void
barParamsSet
(
JSONObject
reqParams
,
PayOrder
payOrder
)
{
String
orderType
=
YsfHttpUtil
.
getOrderTypeByBar
(
payOrder
.
getWayCode
());
reqParams
.
put
(
"orderType"
,
orderType
);
//订单类型: alipay-支付宝, wechat-微信支付, -unionpay银联二维码
ysfPublicParams
(
reqParams
,
payOrder
);
// TODO 终端编号暂时写死
reqParams
.
put
(
"termId"
,
"01727367"
);
// 终端编号
}
/** 云闪付公共参数赋值 **/
public
static
void
ysfPublicParams
(
JSONObject
reqParams
,
PayOrder
payOrder
)
{
//获取订单类型
reqParams
.
put
(
"orderNo"
,
payOrder
.
getPayOrderId
());
//订单号
reqParams
.
put
(
"orderTime"
,
DateUtil
.
format
(
new
Date
(),
DatePattern
.
PURE_DATETIME_PATTERN
));
//订单时间 如:20180702142900
reqParams
.
put
(
"txnAmt"
,
payOrder
.
getAmount
());
//交易金额 单位:分,不带小数点
reqParams
.
put
(
"currencyCode"
,
"156"
);
//交易币种 不出现则默认为人民币-156
reqParams
.
put
(
"orderInfo"
,
payOrder
.
getSubject
());
//订单信息 订单描述信息,如:京东生鲜食品
}
}
jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/ysfpay/payway/AliBar.java
0 → 100644
View file @
de3de82d
/*
* 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.ysfpay.payway
;
import
com.alibaba.fastjson.JSONObject
;
import
com.jeequan.jeepay.core.entity.PayOrder
;
import
com.jeequan.jeepay.core.exception.BizException
;
import
com.jeequan.jeepay.pay.channel.ysfpay.YsfpayPaymentService
;
import
com.jeequan.jeepay.pay.rqrs.AbstractRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.AliBarOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.payorder.payway.AliBarOrderRS
;
import
com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ
;
import
com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg
;
import
com.jeequan.jeepay.pay.util.ApiResBuilder
;
import
com.jeequan.jeepay.pay.model.MchConfigContext
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
/*
* 云闪付 支付宝 条码支付
*
* @author pangxiaoyu
* @site https://www.jeepay.vip
* @date 2021/6/8 18:11
*/
@Service
(
"ysfPaymentByAliBarService"
)
//Service Name需保持全局唯一性
public
class
AliBar
extends
YsfpayPaymentService
{
@Override
public
String
preCheck
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
)
{
AliBarOrderRQ
bizRQ
=
(
AliBarOrderRQ
)
rq
;
if
(
StringUtils
.
isEmpty
(
bizRQ
.
getAuthCode
())){
throw
new
BizException
(
"用户支付条码[authCode]不可为空"
);
}
return
null
;
}
@Override
public
AbstractRS
pay
(
UnifiedOrderRQ
rq
,
PayOrder
payOrder
,
MchConfigContext
mchConfigContext
)
throws
Exception
{
String
logPrefix
=
"【云闪付条码(alipay)支付】"
;
AliBarOrderRQ
bizRQ
=
(
AliBarOrderRQ
)
rq
;
AliBarOrderRS
res
=
ApiResBuilder
.
buildSuccess
(
AliBarOrderRS
.
class
);
ChannelRetMsg
channelRetMsg
=
new
ChannelRetMsg
();
res
.
setChannelRetMsg
(
channelRetMsg
);
JSONObject
reqParams
=
new
JSONObject
();
reqParams
.
put
(
"authCode"
,
bizRQ
.
getAuthCode
());
//付款码: 用户 APP 展示的付款条码或二维码
// 云闪付 bar 统一参数赋值
barParamsSet
(
reqParams
,
payOrder
);
//客户端IP
reqParams
.
put
(
"termInfo"
,
"{\"ip\": \""
+
StringUtils
.
defaultIfEmpty
(
payOrder
.
getClientIp
(),
"127.0.0.1"
)+
"\"}"
);
//终端信息
// 发送请求
JSONObject
resJSON
=
packageParamAndReq
(
"/gateway/api/pay/micropay"
,
reqParams
,
logPrefix
,
mchConfigContext
.
getIsvConfigContext
(),
mchConfigContext
);
//请求 & 响应成功, 判断业务逻辑
String
respCode
=
resJSON
.
getString
(
"respCode"
);
//应答码
String
respMsg
=
resJSON
.
getString
(
"respMsg"
);
//应答信息
try
{
//00-交易成功, 02-用户支付中 , 12-交易重复, 需要发起查询处理 其他认为失败
if
(
"00"
.
equals
(
respCode
)){
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_SUCCESS
);
res
.
setPayData
(
resJSON
.
getString
(
"payData"
));
}
else
if
(
"02"
.
equals
(
respCode
)
||
"12"
.
equals
(
respCode
)
||
"99"
.
equals
(
respCode
)){
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
WAITING
);
channelRetMsg
.
setNeedQuery
(
true
);
// 开启轮询查单
}
else
{
channelRetMsg
.
setChannelState
(
ChannelRetMsg
.
ChannelState
.
CONFIRM_FAIL
);
channelRetMsg
.
setChannelErrCode
(
respCode
);
channelRetMsg
.
setChannelErrMsg
(
respMsg
);
}
}
catch
(
Exception
e
)
{
channelRetMsg
.
setChannelErrCode
(
respCode
);
channelRetMsg
.
setChannelErrMsg
(
respMsg
);
}
return
res
;
}
}
Prev
1
…
6
7
8
9
10
11
12
13
14
…
23
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