Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
holmes
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QA
holmes
Commits
5513f075
Commit
5513f075
authored
Feb 23, 2022
by
黎博
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
微信和支付宝与支付中心对账
parent
839d5af5
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1194 additions
and
8 deletions
+1194
-8
pom.xml
pom.xml
+18
-1
AliPayBillData.java
...va/cn/qg/holmes/entity/reconciliation/AliPayBillData.java
+47
-0
WxPayBillData.java
...ava/cn/qg/holmes/entity/reconciliation/WxPayBillData.java
+68
-0
AliPayBillService.java
...n/qg/holmes/service/reconciliation/AliPayBillService.java
+213
-0
WxPayBillService.java
...cn/qg/holmes/service/reconciliation/WxPayBillService.java
+187
-0
BugNotifyTask.java
src/main/java/cn/qg/holmes/task/BugNotifyTask.java
+7
-7
ReconciliationTask.java
src/main/java/cn/qg/holmes/task/ReconciliationTask.java
+437
-0
DateUtils.java
src/main/java/cn/qg/holmes/utils/DateUtils.java
+86
-0
alipayCertPublicKey_RSA2.crt
src/main/resources/alipay/alipayCertPublicKey_RSA2.crt
+19
-0
alipayRootCert.crt
src/main/resources/alipay/alipayRootCert.crt
+88
-0
appCertPublicKey_2021002106644714.crt
...in/resources/alipay/appCertPublicKey_2021002106644714.crt
+24
-0
No files found.
pom.xml
View file @
5513f075
...
...
@@ -43,7 +43,7 @@
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<version>
3.
0
</version>
<version>
3.
6
</version>
</dependency>
<!--mybatis-plus-->
...
...
@@ -177,6 +177,23 @@
<artifactId>
mongo-java-driver
</artifactId>
<version>
3.12.10
</version>
</dependency>
<dependency>
<groupId>
org.simpleframework
</groupId>
<artifactId>
simple-xml
</artifactId>
<version>
2.7.1
</version>
</dependency>
<dependency>
<groupId>
com.alipay.sdk
</groupId>
<artifactId>
alipay-sdk-java
</artifactId>
<version>
4.22.30.ALL
</version>
</dependency>
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-all
</artifactId>
<version>
5.7.20
</version>
</dependency>
</dependencies>
...
...
src/main/java/cn/qg/holmes/entity/reconciliation/AliPayBillData.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
entity
.
reconciliation
;
import
lombok.Data
;
/**
* 支付宝支付账单相关实体类
* @author libo
* 2022-02-22
*/
@Data
public
class
AliPayBillData
{
/**
* 交易时间
*/
private
String
tradeTime
;
/**
* 支付宝交易号
*/
private
String
aliPayTradeNo
;
/**
* 商户订单号
*/
private
String
merchantOrderNo
;
/**
* 业务类型
*/
private
String
tradeType
;
/**
* 订单金额
*/
private
String
orderAmount
;
/**
* 商家实收
*/
private
String
merchantReceiveAmount
;
/**
* 退款批次号/请求号,仅业务类型是退款时有值
*/
private
String
refundOrderNo
;
}
src/main/java/cn/qg/holmes/entity/reconciliation/WxPayBillData.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
entity
.
reconciliation
;
import
lombok.Data
;
/**
* 微信支付账单相关数据实体类
* @author libo
* 2022-02-21
*/
@Data
public
class
WxPayBillData
{
/**
* 交易时间
*/
private
String
tradeTime
;
/**
* 微信订单号
*/
private
String
wxOrderNo
;
/**
* 商户订单号
*/
private
String
merchantOrderNo
;
/**
* 交易类型
*/
private
String
tradeType
;
/**
* 交易状态
*/
private
String
tradeStatus
;
/**
* 订单金额
*/
private
String
orderAmount
;
/**
* 微信退款单号
*/
private
String
wxRefundOrderNo
;
/**
* 商户退款单号
*/
private
String
merchantRefundOrderNo
;
/**
* 退款类型
*/
private
String
refundType
;
/**
* 退款状态
*/
private
String
refundStatus
;
/**
* 退款金额
*/
private
String
refundAmount
;
}
src/main/java/cn/qg/holmes/service/reconciliation/AliPayBillService.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
service
.
reconciliation
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.ZipUtil
;
import
cn.qg.holmes.entity.reconciliation.AliPayBillData
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alipay.api.AlipayApiException
;
import
com.alipay.api.AlipayConfig
;
import
com.alipay.api.DefaultAlipayClient
;
import
com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest
;
import
com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse
;
import
lombok.SneakyThrows
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.stereotype.Component
;
import
java.io.*
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.nio.charset.Charset
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* 支付宝支付账单服务
*
* @author libo
* 2022-02-22
*/
@Slf4j
@Component
public
class
AliPayBillService
{
private
final
String
ALI_SERVER_URL
=
"https://openapi.alipay.com/gateway.do"
;
private
final
String
ALIPAY_PRIVATE_KEY
=
"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3rgHa/x67gaY08RJoeVWLghAiQooLG/dOojW+639RAuirhxLyeuawbcch291uj/90MPTQy86nNKKQBbet41MQtS8L6ts/5Bjp2GYgzsQlmPCRWE7Il94/6R18fg9ZZQ4rx280BrX60hKTFcM+rn6IuNAiT7wHMcsjonRLsbWW/ZaSmMwqJcfhRU2/8Slznw2AX8jHs3X/ZZtM8usm3Hd41U9m7DIRPgejo4wlgTmUrFJrgQIWdsuSCYm88a4BzFc3Wfa2No5stqkHZizsshx52UGOgvgJdxF6PUqC9af+qQSdldTcbOeQjgQbJOLfiZoPQzyO8DaszIzJkB8FB38DAgMBAAECggEBAIbZ7qzMjtCU3+SQdLZVFlQFGjk85sI/NvL5LkJL/T4Jx65eza9OQd2XyxH1rH1GpQK2CpbceozRnOPl/rNgaRSkILU8KNmgahYM9PXzN5huz3e2AKlOrjH3wNksZ7J2+c90bRUiNCrAXji0SpLTYzyXit8V8PLLQNuZoo4MG0iNCJy8riZwUn8ZQLJnCMv1VD0yUyGSr/6LAEJjJZTrrnpibw/99hqFO8Z6UvIs9JewfvjdzamT3UxF0gURSncieQwvsq3mYlq6ppcWqzBrEqJHZJOGzZrxtsOALmOFr7KCp6qRziareK/9vb9RLnZtBSrLZqhJF/MU1oFWpHixRoECgYEA3yKt0rT2v1rjaOlMQDF7pKKfnGmRHGps9214Smsj/wOwWdlwwixWZA2DUFLOUpPQRu3dPp3ZZQdcg21NejvEbtu4CcN0lrvnVlBIrExQmm9zqjDWijljtNvf+POqMkwyLumtNtdNxWLZxdiDClosShEX9kv4ttdlF5bEc2z3V8ECgYEA0rumR+zUnvT6OS6l6msUXgZ/f/XBgcW8BLdZV6pSJJVh3I9CVgc55MlTTGTd0yNfrDPVbwloDpjVVPSNI9YNL0h9i0vfMTHolWOR7RCcqBoquvt66NjtaV70PjBm1pxNVVDaUSgCva+oOFaRnoHjOSA+jyZkKRHjwnEWlcyRZ8MCgYBnZCtE6gM3cYbUEt35FLSk+ZGZqTTLBOlO0NOfL/vy6yOozl84KdEx9Sz2aBggHUuxwf/1RrD35ixQ3bG7xLvlXjvtkjqQqaqszPCPnaDvnlrq7kxKqgLwR72FHmqrebD7Gd3f/m2T25Tq3sMBZf0FqNwAjP1Gw5GdF4gZr9EAQQKBgQCQrWgxxTUMlOAd1hru3+kxzIBIl67sq5a0HjTmbPbMSwrO5EQE0B09J8NalX198bFDhqqn+utH6kG8e9FSoyiWJ8yZj9OB8OPffGa5PUhwWNaxXOo7ZoNIbnp9H7na6aBmTIY2ZaPMGwcA9t4u1rnrhGmu2gq176RQ4FdDLRk/BQKBgQDU+Oab3jL2MoDMtGk4ZGYQUcTMB/ILtG4O1bx8BhJZ/Rula3Rt7dYPrRng3uZ0sTVh7/QRSn02hLY72UoItge3POZMEbNQLb+gzhIuU4v4hLT3H6WK2MSaLftsb9mPyW9LX76xQS4ayf5xZqeKK2jOtIZCsiLmC/ALvIytcr2DHA=="
;
private
String
format
=
"json"
;
private
String
charset
=
"GBK"
;
private
String
signType
=
"RSA2"
;
private
String
aliAppId
=
"2021002106644714"
;
private
String
merchantCertPath
=
"alipay/appCertPublicKey_2021002106644714.crt"
;
private
String
alipayCertPath
=
"alipay/alipayCertPublicKey_RSA2.crt"
;
private
String
alipayRootCertPath
=
"alipay/alipayRootCert.crt"
;
/**
* 业务账单下载路径
*/
@Value
(
"${alipay.file.path}"
)
private
String
aliPayFilePath
;
private
String
FILE_NAME_CONTENT
=
"业务明细.csv"
;
private
String
BILL_TYPE_REPAY
=
"交易"
;
private
String
BILL_TYPE_REFUND
=
"退款"
;
/**
* 请求支付宝对账单下载接口
*
* @param billDate 账单日期,格式:2022-02-22
* @return
* @throws IOException
* @throws AlipayApiException
*/
public
List
<
String
>
downloadBillFile
(
String
billDate
)
throws
IOException
,
AlipayApiException
{
log
.
info
(
"开始下载支付宝对账文件,账单日期:{}"
,
billDate
);
InputStream
merchantCert
=
new
ClassPathResource
(
merchantCertPath
).
getInputStream
();
InputStream
alipayCert
=
new
ClassPathResource
(
alipayCertPath
).
getInputStream
();
InputStream
alipayRootCert
=
new
ClassPathResource
(
alipayRootCertPath
).
getInputStream
();
AlipayConfig
alipayConfig
=
new
AlipayConfig
();
alipayConfig
.
setServerUrl
(
ALI_SERVER_URL
);
alipayConfig
.
setAppId
(
aliAppId
);
alipayConfig
.
setPrivateKey
(
ALIPAY_PRIVATE_KEY
);
alipayConfig
.
setAppCertContent
(
IOUtils
.
toString
(
merchantCert
,
String
.
valueOf
(
Charset
.
defaultCharset
())));
alipayConfig
.
setAlipayPublicCertContent
(
IOUtils
.
toString
(
alipayCert
,
String
.
valueOf
(
Charset
.
defaultCharset
())));
alipayConfig
.
setRootCertContent
(
IOUtils
.
toString
(
alipayRootCert
,
String
.
valueOf
(
Charset
.
defaultCharset
())));
alipayConfig
.
setFormat
(
format
);
alipayConfig
.
setCharset
(
charset
);
alipayConfig
.
setSignType
(
signType
);
DefaultAlipayClient
alipayClient
=
new
DefaultAlipayClient
(
alipayConfig
);
AlipayDataDataserviceBillDownloadurlQueryRequest
request
=
new
AlipayDataDataserviceBillDownloadurlQueryRequest
();
JSONObject
bizContent
=
new
JSONObject
();
bizContent
.
put
(
"bill_type"
,
"trade"
);
bizContent
.
put
(
"bill_date"
,
billDate
);
request
.
setBizContent
(
bizContent
.
toJSONString
());
AlipayDataDataserviceBillDownloadurlQueryResponse
response
=
alipayClient
.
certificateExecute
(
request
);
return
parseResponseResult
(
response
);
}
/**
* 处理响应结果,并下载对账文件
*
* @param response
* @return
*/
public
List
<
String
>
parseResponseResult
(
AlipayDataDataserviceBillDownloadurlQueryResponse
response
)
{
if
(!
response
.
isSuccess
())
{
log
.
info
(
"获取支付宝支付账单下载地址失败."
);
return
null
;
}
String
downloadUrl
=
response
.
getBillDownloadUrl
();
log
.
info
(
"获取支付宝支付账单下载地址成功,地址为:{}"
,
downloadUrl
);
Map
<
String
,
String
>
urlParamMap
=
new
HashMap
<>();
for
(
String
prop
:
StringUtils
.
split
(
downloadUrl
,
"&"
))
{
String
[]
splitVal
=
StringUtils
.
split
(
prop
,
"="
);
urlParamMap
.
put
(
splitVal
[
0
],
splitVal
[
1
]);
}
StringBuilder
tempFilePath
=
new
StringBuilder
(
aliPayFilePath
);
String
zipFilePath
=
tempFilePath
.
append
(
urlParamMap
.
get
(
"downloadFileName"
)).
toString
();
downloadFileFromURL
(
downloadUrl
,
zipFilePath
);
ZipUtil
.
unzip
(
zipFilePath
,
Charset
.
forName
(
"gbk"
));
String
filePath
=
zipFilePath
.
substring
(
0
,
zipFilePath
.
lastIndexOf
(
"."
));
File
file
=
new
File
(
filePath
);
String
[]
fileList
=
file
.
list
();
String
newFileName
=
StrUtil
.
EMPTY
;
for
(
String
fileName
:
fileList
)
{
if
(
fileName
.
contains
(
FILE_NAME_CONTENT
))
{
newFileName
=
fileName
;
break
;
}
}
//解压后文件所在路径
String
newFilePath
=
filePath
+
File
.
separator
+
newFileName
;
log
.
info
(
"下载到支付宝对账文件路径:{}"
,
newFilePath
);
return
FileUtil
.
readLines
(
newFilePath
,
"gbk"
);
}
/**
* 解析支付宝账单文件,转换成实体类列表
*
* @param billFile
* @return
*/
public
List
<
AliPayBillData
>
parseAliPayBillFile
(
List
<
String
>
billFile
)
{
log
.
info
(
"开始解析支付宝账单文件."
);
List
<
AliPayBillData
>
aliPayBillDataList
=
new
ArrayList
<>();
// 前五行和后四行不要
for
(
int
i
=
5
;
i
<
billFile
.
size
()
-
4
;
i
++)
{
String
[]
dataArray
=
billFile
.
get
(
i
).
replaceAll
(
"\t"
,
""
).
split
(
","
);
AliPayBillData
aliPayBillData
=
new
AliPayBillData
();
aliPayBillData
.
setAliPayTradeNo
(
dataArray
[
0
]);
aliPayBillData
.
setMerchantOrderNo
(
dataArray
[
1
]);
aliPayBillData
.
setTradeType
(
dataArray
[
2
]);
aliPayBillData
.
setTradeTime
(
dataArray
[
4
]);
if
(
StringUtils
.
equals
(
dataArray
[
2
],
BILL_TYPE_REPAY
))
{
aliPayBillData
.
setOrderAmount
(
dataArray
[
11
]);
}
if
(
StringUtils
.
equals
(
dataArray
[
2
],
BILL_TYPE_REFUND
))
{
// 业务类型为退款时,去掉订单金额前面的负号
aliPayBillData
.
setOrderAmount
(
dataArray
[
11
].
substring
(
1
));
// 业务类型退款时,设置退款批次号
aliPayBillData
.
setRefundOrderNo
(
dataArray
[
21
]);
}
// 商户实收金额
aliPayBillData
.
setMerchantReceiveAmount
(
dataArray
[
12
]);
aliPayBillDataList
.
add
(
aliPayBillData
);
}
log
.
info
(
"开始解析支付宝账单文件结果:{}"
,
aliPayBillDataList
);
return
aliPayBillDataList
;
}
@SneakyThrows
public
void
downloadFileFromURL
(
String
url
,
String
filePath
)
{
FileUtil
.
touch
(
filePath
);
FileOutputStream
fos
=
null
;
BufferedInputStream
bis
=
null
;
BufferedOutputStream
bos
=
null
;
InputStream
is
=
null
;
HttpURLConnection
conn
=
null
;
try
{
URL
httpUrl
=
new
URL
(
url
);
conn
=
(
HttpURLConnection
)
httpUrl
.
openConnection
();
conn
.
setRequestMethod
(
"GET"
);
conn
.
setDoInput
(
true
);
conn
.
setDoOutput
(
true
);
conn
.
setUseCaches
(
false
);
conn
.
setRequestProperty
(
"Charset"
,
"UTF-8"
);
conn
.
connect
();
is
=
conn
.
getInputStream
();
bis
=
new
BufferedInputStream
(
is
);
fos
=
new
FileOutputStream
(
filePath
);
bos
=
new
BufferedOutputStream
(
fos
);
byte
[]
buf
=
new
byte
[
1024
];
int
length
=
bis
.
read
(
buf
);
while
(
length
!=
-
1
)
{
bos
.
write
(
buf
,
0
,
length
);
length
=
bis
.
read
(
buf
);
}
bos
.
close
();
bis
.
close
();
conn
.
disconnect
();
}
catch
(
Exception
e
)
{
log
.
error
(
"解析URL异常:{}"
,
e
,
e
.
getMessage
());
}
}
}
src/main/java/cn/qg/holmes/service/reconciliation/WxPayBillService.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
service
.
reconciliation
;
import
cn.qg.holmes.entity.reconciliation.WxPayBillData
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.google.common.base.Joiner
;
import
com.google.common.hash.Hashing
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.http.HttpEntity
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.apache.http.client.methods.HttpPost
;
import
org.apache.http.entity.StringEntity
;
import
org.apache.http.impl.client.CloseableHttpClient
;
import
org.apache.http.impl.client.HttpClients
;
import
org.apache.http.util.EntityUtils
;
import
org.springframework.stereotype.Component
;
import
java.util.*
;
import
static
com
.
google
.
common
.
base
.
Charsets
.
UTF_8
;
/**
* 微信支付账单服务
*
* @author libo
* 2022-02-21
*/
@Slf4j
@Component
public
class
WxPayBillService
{
private
final
String
WX_API_KEY
=
"77f7565be7d8992ab882d4dc31271c71"
;
private
final
String
WX_BILL_DOWNLOAD_URL
=
"https://api.mch.weixin.qq.com/pay/downloadbill"
;
private
final
String
WX_FUND_FLOW_DOWNLOAD_URL
=
"https://api.mch.weixin.qq.com/pay/downloadfundflow"
;
/**
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6
* 下载微信支付交易账单
*
* @param billDate 下载对账单的日期,格式:20140603
* @param billType ALL(默认值),返回当日所有订单信息(不含充值退款订单)SUCCESS,返回当日成功支付的订单(不含充值退款订单), REFUND,返回当日退款订单(不含充值退款订单,RECHARGE_REFUND,返回当日充值退款订单
* @return
*/
public
String
downloadTradeBillFile
(
String
billDate
,
String
billType
)
{
log
.
info
(
"开始下载微信支付交易账单,账单日期:{}, 账单类型:{}"
,
billDate
,
billType
);
String
randomString
=
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
TreeMap
<
String
,
Object
>
treeMap
=
new
TreeMap
<>();
treeMap
.
put
(
"appid"
,
"wx75d5a207551d0b4d"
);
treeMap
.
put
(
"mch_id"
,
"1604055791"
);
treeMap
.
put
(
"nonce_str"
,
randomString
);
treeMap
.
put
(
"bill_date"
,
billDate
);
treeMap
.
put
(
"bill_type"
,
billType
);
treeMap
.
put
(
"sign"
,
md5Sign
(
treeMap
));
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
HttpPost
httpPost
=
new
HttpPost
(
WX_BILL_DOWNLOAD_URL
);
CloseableHttpResponse
response
=
null
;
try
{
httpPost
.
setHeader
(
"Content-type"
,
"text/xml"
);
String
params
=
mapToXml
(
treeMap
);
HttpEntity
entity
=
new
StringEntity
(
params
);
httpPost
.
setEntity
(
entity
);
response
=
httpClient
.
execute
(
httpPost
);
if
(
response
.
getStatusLine
().
getStatusCode
()
==
200
)
{
String
content
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"UTF-8"
);
return
content
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
return
null
;
}
/**
* 解析微信交易账单
*
* @param content 微信交易账单内容
* @param billType 账单类型
* @return
*/
public
List
<
WxPayBillData
>
parseTradeBill
(
String
content
,
String
billType
)
{
log
.
info
(
"开始解析微信账单文件."
);
if
(
StringUtils
.
isEmpty
(
content
))
{
return
null
;
}
String
[]
tradeBillArray
=
content
.
split
(
"\n"
);
List
<
WxPayBillData
>
wxTradeBillDataList
=
new
ArrayList
<>();
// 三种类型账单下载的文件格式不一样,分别处理
if
(
StringUtils
.
equals
(
billType
,
"ALL"
))
{
// 第一行为表头,最后两行为统计数据,均忽略
for
(
int
i
=
1
;
i
<
tradeBillArray
.
length
-
2
;
i
++)
{
String
[]
dataArray
=
tradeBillArray
[
i
].
replace
(
"`"
,
""
).
split
(
","
);
WxPayBillData
wxTradeBillData
=
new
WxPayBillData
();
wxTradeBillData
.
setTradeTime
(
dataArray
[
0
]);
wxTradeBillData
.
setWxOrderNo
(
dataArray
[
5
]);
wxTradeBillData
.
setMerchantOrderNo
(
dataArray
[
6
]);
wxTradeBillData
.
setTradeType
(
dataArray
[
8
]);
wxTradeBillData
.
setTradeStatus
(
dataArray
[
9
]);
wxTradeBillData
.
setOrderAmount
(
dataArray
[
24
]);
wxTradeBillData
.
setWxRefundOrderNo
(
dataArray
[
14
]);
wxTradeBillData
.
setMerchantRefundOrderNo
(
dataArray
[
15
]);
wxTradeBillData
.
setRefundAmount
(
dataArray
[
16
]);
wxTradeBillData
.
setRefundType
(
dataArray
[
18
]);
wxTradeBillData
.
setRefundStatus
(
dataArray
[
19
]);
wxTradeBillDataList
.
add
(
wxTradeBillData
);
}
}
if
(
StringUtils
.
equals
(
billType
,
"SUCCESS"
))
{
for
(
int
i
=
1
;
i
<
tradeBillArray
.
length
-
2
;
i
++)
{
String
[]
dataArray
=
tradeBillArray
[
i
].
replace
(
"`"
,
""
).
split
(
","
);
WxPayBillData
wxTradeBillData
=
new
WxPayBillData
();
wxTradeBillData
.
setTradeTime
(
dataArray
[
0
]);
wxTradeBillData
.
setWxOrderNo
(
dataArray
[
5
]);
wxTradeBillData
.
setMerchantOrderNo
(
dataArray
[
6
]);
wxTradeBillData
.
setTradeType
(
dataArray
[
8
]);
wxTradeBillData
.
setTradeStatus
(
dataArray
[
9
]);
wxTradeBillData
.
setOrderAmount
(
dataArray
[
18
]);
wxTradeBillDataList
.
add
(
wxTradeBillData
);
}
}
if
(
StringUtils
.
equals
(
billType
,
"REFUND"
))
{
for
(
int
i
=
1
;
i
<
tradeBillArray
.
length
-
2
;
i
++)
{
String
[]
dataArray
=
tradeBillArray
[
i
].
replace
(
"`"
,
""
).
split
(
","
);
WxPayBillData
wxTradeBillData
=
new
WxPayBillData
();
wxTradeBillData
.
setTradeTime
(
dataArray
[
0
]);
wxTradeBillData
.
setWxOrderNo
(
dataArray
[
5
]);
wxTradeBillData
.
setMerchantOrderNo
(
dataArray
[
6
]);
wxTradeBillData
.
setTradeType
(
dataArray
[
8
]);
wxTradeBillData
.
setTradeStatus
(
dataArray
[
9
]);
wxTradeBillData
.
setWxRefundOrderNo
(
dataArray
[
16
]);
wxTradeBillData
.
setMerchantRefundOrderNo
(
dataArray
[
17
]);
wxTradeBillData
.
setRefundAmount
(
dataArray
[
18
]);
wxTradeBillData
.
setRefundType
(
dataArray
[
20
]);
wxTradeBillData
.
setRefundStatus
(
dataArray
[
21
]);
wxTradeBillDataList
.
add
(
wxTradeBillData
);
}
}
return
wxTradeBillDataList
;
}
/**
* md5签名
*
* @param value
* @return
*/
public
String
md5Sign
(
Object
value
)
{
JSONObject
jsonMap
=
JSON
.
parseObject
(
JSON
.
toJSONString
(
value
));
TreeMap
<
String
,
Object
>
treeMap
=
new
TreeMap
<>(
jsonMap
);
String
signStr
=
Joiner
.
on
(
"&"
).
withKeyValueSeparator
(
"="
).
join
(
treeMap
);
return
Hashing
.
md5
().
newHasher
()
.
putString
(
signStr
+
"&key="
+
WX_API_KEY
,
UTF_8
)
.
hash
()
.
toString
()
.
toUpperCase
();
}
public
String
mapToXml
(
SortedMap
<
String
,
Object
>
sortedMap
)
{
StringBuffer
sb
=
new
StringBuffer
(
"<xml>"
);
Iterator
iterator
=
sortedMap
.
keySet
().
iterator
();
while
(
iterator
.
hasNext
())
{
Object
key
=
iterator
.
next
();
Object
value
=
sortedMap
.
get
(
key
);
sb
.
append
(
"<"
+
key
+
">"
);
sb
.
append
(
value
);
sb
.
append
(
"</"
+
key
+
">"
);
}
sb
.
append
(
"</xml>"
);
return
sb
.
toString
();
}
}
src/main/java/cn/qg/holmes/task/BugNotifyTask.java
View file @
5513f075
...
...
@@ -6,7 +6,6 @@ import cn.qg.holmes.service.quality.DingRobotService;
import
cn.qg.holmes.service.quality.JiraBugPoolService
;
import
cn.qg.holmes.service.quality.JiraService
;
import
cn.qg.holmes.utils.DingdingUtils
;
import
com.alibaba.fastjson.JSON
;
import
com.atlassian.jira.rest.client.api.domain.Issue
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -21,6 +20,7 @@ import java.util.List;
/**
* JIRA BUG相关定时任务
* @author libo
*/
@Component
@Slf4j
...
...
@@ -38,8 +38,8 @@ public class BugNotifyTask {
@Value
(
"${sjgd.ding.url}"
)
private
String
sjgdDingUrl
;
@Value
(
"${
task.debug
}"
)
private
String
taskDebug
;
@Value
(
"${
scheduled.task.start
}"
)
private
String
scheduledTaskStart
;
/**
* 电商线上故障处理群钉钉机器人地址
...
...
@@ -59,7 +59,7 @@ public class BugNotifyTask {
*/
// @Scheduled(cron = "0 0 19 * * ?")
public
void
SJGDJiraIssueStatisticsTimedJob
()
throws
Exception
{
if
(
taskDebug
.
equals
(
"true"
))
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
log
.
info
(
"开始执行数据工单BUG统计定时任务!"
);
Iterable
<
Issue
>
issues
=
jiraService
.
getUnsolvedIssueListByProject
(
"SJGD"
);
String
markdownMsg
=
DingdingUtils
.
buildMarkdownMsgForUnsolvedIssueList
(
issues
);
...
...
@@ -75,7 +75,7 @@ public class BugNotifyTask {
*/
// @Scheduled(cron = "0 0 10-20 ? * MON-FRI")
public
void
cycleJiraBugPool
()
throws
Exception
{
if
(
taskDebug
.
equals
(
"true"
))
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
log
.
info
(
"开始执行jira bug pool定时任务!"
);
QueryWrapper
<
JiraBugPool
>
jiraBugPoolQueryWrapper
=
new
QueryWrapper
<>();
jiraBugPoolQueryWrapper
.
eq
(
"enable"
,
1
);
...
...
@@ -124,7 +124,7 @@ public class BugNotifyTask {
// @Scheduled(cron = "0 */1 * * * ?")
@Scheduled
(
cron
=
"0 0 18 ? * MON-FRI"
)
public
void
DailyCycleHandleJiraBugPool
()
{
if
(
taskDebug
.
equals
(
"true"
))
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
// 首先遍历ding_robot, 获取状态是进行中的项目
QueryWrapper
<
DingRobot
>
dingRobotQueryWrapper
=
new
QueryWrapper
<>();
dingRobotQueryWrapper
.
eq
(
"status"
,
1
);
...
...
@@ -177,7 +177,7 @@ public class BugNotifyTask {
// @Scheduled(cron = "0 */1 * * * ?")
@Scheduled
(
cron
=
"0 0 18 ? * *"
)
public
void
prodBugDailyNotifyTask
()
throws
Exception
{
if
(
taskDebug
.
equals
(
"true"
))
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
Iterable
<
Issue
>
dsUnsolvedList
=
jiraService
.
getIssueListByJQL
(
"project = YXMXS AND resolution = Unresolved ORDER BY priority DESC, created DESC"
);
Iterable
<
Issue
>
jrUnsolvedList
=
jiraService
.
getIssueListByJQL
(
"project = YFGDZZ AND resolution = Unresolved ORDER BY priority DESC, created DESC"
);
DingdingUtils
.
sendToDingding
(
DingdingUtils
.
buildDailyProdBugNotifyMsg
(
dsUnsolvedList
),
dsProdDingUrl
);
...
...
src/main/java/cn/qg/holmes/task/ReconciliationTask.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
task
;
import
cn.hutool.core.io.FileUtil
;
import
cn.qg.holmes.entity.reconciliation.AliPayBillData
;
import
cn.qg.holmes.entity.reconciliation.WxPayBillData
;
import
cn.qg.holmes.service.reconciliation.AliPayBillService
;
import
cn.qg.holmes.service.reconciliation.WxPayBillService
;
import
cn.qg.holmes.utils.DateUtils
;
import
cn.qg.holmes.utils.DingdingUtils
;
import
cn.qg.holmes.utils.JdbcUtils
;
import
com.alipay.api.AlipayApiException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Component
;
import
java.io.IOException
;
import
java.math.BigDecimal
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
/**
* 对账相关定时任务
* @author libo
* 2022-02-21
*/
@Slf4j
@Component
public
class
ReconciliationTask
{
/**
* 脱敏库相关信息
*/
private
final
String
DB_HOST
=
"172.30.5.27"
;
private
final
String
DB_PORT
=
"7434"
;
private
final
String
USERNAME
=
"haiyuan.wen"
;
private
final
String
PASSWORD
=
"QKawjtLXHXFVdars"
;
@Autowired
WxPayBillService
wxPayBillService
;
@Autowired
AliPayBillService
aliPayBillService
;
/**
* 对账机器人webhook
*/
@Value
(
"${reconciliation.ding.url}"
)
private
String
reconciliationDingUrl
;
/**
* 是否启动定时任务,true-启动,false-不启动
*/
@Value
(
"${scheduled.task.start}"
)
private
String
scheduledTaskStart
;
/**
* 微信商户后台与支付中心数据对账
*/
// @Scheduled(cron = "0 */5 * * * ?")
@Scheduled
(
cron
=
"0 0 13 ? * *"
)
public
void
wxPayDailyReconciliation
()
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
log
.
info
(
"开始微信支付对账."
);
String
payOrderSql
=
"SELECT * FROM pay_channel_order "
+
"WHERE updated_at > (SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY)) AND updated_at < CURDATE() "
+
"AND pay_approach IN (77, 83) "
+
"AND pay_status=3"
;
String
refundOrderSql
=
"SELECT * FROM refund_order "
+
"WHERE updated_at > (SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY)) "
+
"AND updated_at < CURDATE() "
+
"AND channel_account_id='86' "
+
"AND refund_status=4"
;
List
<
Map
<
String
,
Object
>>
payOrderList
=
JdbcUtils
.
queryForList
(
DB_HOST
,
DB_PORT
,
USERNAME
,
PASSWORD
,
"vpayment_center"
,
payOrderSql
);
List
<
Map
<
String
,
Object
>>
refundOrderList
=
JdbcUtils
.
queryForList
(
DB_HOST
,
DB_PORT
,
USERNAME
,
PASSWORD
,
"vpayment_center"
,
refundOrderSql
);
// 从微信商户后台获取数据
String
billDate
=
DateUtils
.
convertDate
(
DateUtils
.
getBeforeDay
(
new
Date
(),
1
),
"yyyyMMdd"
);
String
billType
=
"SUCCESS"
;
// 仅支付
List
<
WxPayBillData
>
payBillDataList
=
wxPayBillService
.
parseTradeBill
(
wxPayBillService
.
downloadTradeBillFile
(
billDate
,
billType
),
billType
);
billType
=
"REFUND"
;
// 仅退款
List
<
WxPayBillData
>
refundBillDataList
=
wxPayBillService
.
parseTradeBill
(
wxPayBillService
.
downloadTradeBillFile
(
billDate
,
billType
),
billType
);
// 对比交易数据,微信商户后台有,但是支付中心数据库中没有的数据列表
BigDecimal
wxTradeAmount
=
new
BigDecimal
(
0
);
List
<
WxPayBillData
>
notInPayCenterTradeList
=
new
ArrayList
<>();
for
(
WxPayBillData
wxTradeBillData:
payBillDataList
)
{
String
merchantOrderNo
=
wxTradeBillData
.
getMerchantOrderNo
();
String
orderAmount
=
wxTradeBillData
.
getOrderAmount
();
wxTradeAmount
=
wxTradeAmount
.
add
(
new
BigDecimal
(
orderAmount
));
boolean
flag
=
false
;
for
(
Map
<
String
,
Object
>
map:
payOrderList
)
{
if
(
StringUtils
.
equals
(
map
.
get
(
"call_flow_no"
).
toString
(),
merchantOrderNo
)
&&
StringUtils
.
equals
(
map
.
get
(
"amount"
).
toString
(),
orderAmount
))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInPayCenterTradeList
.
add
(
wxTradeBillData
);
}
}
// 对比交易数据,支付中心有,但是微信商户后台没有
BigDecimal
payCenterTradeAmount
=
new
BigDecimal
(
0
);
List
<
Map
<
String
,
Object
>>
notInWxTradeList
=
new
ArrayList
<>();
for
(
Map
<
String
,
Object
>
map:
payOrderList
)
{
String
callFlowNo
=
map
.
get
(
"call_flow_no"
).
toString
();
String
amount
=
map
.
get
(
"amount"
).
toString
();
payCenterTradeAmount
=
payCenterTradeAmount
.
add
(
new
BigDecimal
(
amount
));
boolean
flag
=
false
;
for
(
WxPayBillData
wxTradeBillData:
payBillDataList
)
{
if
(
StringUtils
.
equals
(
callFlowNo
,
wxTradeBillData
.
getMerchantOrderNo
())
&&
StringUtils
.
equals
(
amount
,
wxTradeBillData
.
getOrderAmount
()))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInWxTradeList
.
add
(
map
);
}
}
// 对比退款数据,微信商户后台有,但是支付中心数据库中没有的数据列表
BigDecimal
wxRefundAmount
=
new
BigDecimal
(
0
);
List
<
WxPayBillData
>
notInPayCenterRefundList
=
new
ArrayList
<>();
for
(
WxPayBillData
wxTradeBillData:
refundBillDataList
)
{
String
merchantRefundOrderNo
=
wxTradeBillData
.
getMerchantRefundOrderNo
();
String
refundAmount
=
wxTradeBillData
.
getRefundAmount
();
wxRefundAmount
=
wxRefundAmount
.
add
(
new
BigDecimal
(
refundAmount
));
boolean
flag
=
false
;
for
(
Map
<
String
,
Object
>
map:
refundOrderList
)
{
if
(
StringUtils
.
equals
(
map
.
get
(
"refund_order_id"
).
toString
(),
merchantRefundOrderNo
)
&&
StringUtils
.
equals
(
map
.
get
(
"refund_amount"
).
toString
(),
refundAmount
))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInPayCenterRefundList
.
add
(
wxTradeBillData
);
}
}
// 对比退款数据,支付中心有,但是微信商户后台没有
BigDecimal
payCenterRefundAmount
=
new
BigDecimal
(
0
);
List
<
Map
<
String
,
Object
>>
notInWxRefundList
=
new
ArrayList
<>();
for
(
Map
<
String
,
Object
>
map:
refundOrderList
)
{
String
refundOrderId
=
map
.
get
(
"refund_order_id"
).
toString
();
String
refundAmount
=
map
.
get
(
"refund_amount"
).
toString
();
payCenterRefundAmount
=
payCenterRefundAmount
.
add
(
new
BigDecimal
(
refundAmount
));
boolean
flag
=
false
;
for
(
WxPayBillData
wxTradeBillData:
refundBillDataList
)
{
if
(
StringUtils
.
equals
(
refundOrderId
,
wxTradeBillData
.
getMerchantRefundOrderNo
())
&&
StringUtils
.
equals
(
refundAmount
,
wxTradeBillData
.
getRefundAmount
()))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInWxRefundList
.
add
(
map
);
}
}
String
text
=
"日期:"
+
billDate
+
"\n\n"
+
"微信商户平台-交易金额:"
+
wxTradeAmount
+
"\n\n"
+
"支付中心-微信交易金额:"
+
payCenterTradeAmount
+
"\n\n"
+
"微信商户平台-退款金额:"
+
wxRefundAmount
+
"\n\n"
+
"支付中心-微信退款金额:"
+
payCenterRefundAmount
+
"\n\n"
;
if
(
wxTradeAmount
.
compareTo
(
payCenterTradeAmount
)
!=
0
)
{
int
tradeErrorCount
=
notInPayCenterTradeList
.
size
()
+
notInWxTradeList
.
size
();
text
+=
"**交易异常数据:共"
+
tradeErrorCount
+
"条**\n\n"
;
int
index
=
0
;
if
(
notInPayCenterTradeList
.
size
()
>
0
)
{
text
+=
"微信商户平台有,支付中心没有的数据:\n\n"
;
for
(
WxPayBillData
wxTradeBillData:
notInPayCenterTradeList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 交易时间:"
+
wxTradeBillData
.
getTradeTime
()
+
"\n\n"
;
text
+=
"> 微信订单号:"
+
wxTradeBillData
.
getWxOrderNo
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
wxTradeBillData
.
getMerchantOrderNo
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
wxTradeBillData
.
getOrderAmount
()
+
"\n\n"
;
}
}
if
(
notInWxTradeList
.
size
()
>
0
)
{
text
+=
"支付中心有,微信商户平台没有的数据:\n\n"
;
for
(
Map
<
String
,
Object
>
map:
notInWxTradeList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
map
.
get
(
"updated_at"
).
toString
()
+
"\n\n"
;
text
+=
"> 微信订单号:"
+
map
.
get
(
"third_trade_no"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
map
.
get
(
"call_flow_no"
).
toString
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
map
.
get
(
"amount"
).
toString
()
+
"\n\n"
;
}
}
}
if
(
wxRefundAmount
.
compareTo
(
payCenterRefundAmount
)
!=
0
)
{
int
refundErrorCount
=
notInWxRefundList
.
size
()
+
notInPayCenterRefundList
.
size
();
text
+=
"**退款异常数据:共"
+
refundErrorCount
+
"条**\n\n"
;
int
index
=
0
;
if
(
notInPayCenterRefundList
.
size
()
>
0
)
{
text
+=
"微信商户平台有,支付中心没有的数据:\n\n"
;
for
(
WxPayBillData
wxPayBillData:
notInPayCenterRefundList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
wxPayBillData
.
getTradeTime
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
wxPayBillData
.
getMerchantOrderNo
()
+
"\n\n"
;
text
+=
"> 商户退款单号:"
+
wxPayBillData
.
getMerchantRefundOrderNo
()
+
"\n\n"
;
text
+=
"> 退款金额:"
+
wxPayBillData
.
getRefundAmount
()
+
"\n\n"
;
}
}
if
(
notInWxRefundList
.
size
()
>
0
)
{
text
+=
"支付中心有,微信商户平台没有的数据:\n\n"
;
for
(
Map
<
String
,
Object
>
map:
notInWxRefundList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
map
.
get
(
"updated_at"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
map
.
get
(
"repay_order_id"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户退款单号:"
+
map
.
get
(
"refund_order_id"
).
toString
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
map
.
get
(
"refund_amount"
).
toString
()
+
"\n\n"
;
}
}
}
String
mkMsg
=
DingdingUtils
.
buildMarkdownMsg
(
"微信支付对账"
+
billDate
,
text
,
false
);
DingdingUtils
.
sendToDingding
(
mkMsg
,
reconciliationDingUrl
);
}
}
/**
* 支付宝商户后台与支付中心数据对账
*/
// @Scheduled(cron = "0 */5 * * * ?")
@Scheduled
(
cron
=
"0 0 13 ? * *"
)
public
void
aliPayDailyReconciliation
()
throws
AlipayApiException
,
IOException
{
if
(
scheduledTaskStart
.
equals
(
"true"
))
{
log
.
info
(
"开始支付宝支付对账."
);
String
aliPayOrderSql
=
"SELECT * FROM pay_channel_order "
+
"WHERE updated_at > (SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY)) AND updated_at < CURDATE() "
+
"AND pay_approach in (81, 84) "
+
"AND pay_status = 3"
;
String
aliPayRefundSql
=
"SELECT * FROM refund_order "
+
"WHERE updated_at > (SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY)) "
+
"AND updated_at < CURDATE() "
+
"AND channel_account_id = '87' "
+
"AND refund_status = 4"
;
List
<
Map
<
String
,
Object
>>
payOrderList
=
JdbcUtils
.
queryForList
(
DB_HOST
,
DB_PORT
,
USERNAME
,
PASSWORD
,
"vpayment_center"
,
aliPayOrderSql
);
List
<
Map
<
String
,
Object
>>
refundOrderList
=
JdbcUtils
.
queryForList
(
DB_HOST
,
DB_PORT
,
USERNAME
,
PASSWORD
,
"vpayment_center"
,
aliPayRefundSql
);
String
billDate
=
DateUtils
.
convertDate
(
DateUtils
.
getBeforeDay
(
new
Date
(),
1
),
"yyyy-MM-dd"
);
List
<
AliPayBillData
>
aliPayBillDataList
=
aliPayBillService
.
parseAliPayBillFile
(
aliPayBillService
.
downloadBillFile
(
billDate
));
List
<
AliPayBillData
>
aliPayTradeList
=
new
ArrayList
<>();
List
<
AliPayBillData
>
aliPayRefundList
=
new
ArrayList
<>();;
for
(
AliPayBillData
aliPayBillData:
aliPayBillDataList
)
{
if
(
StringUtils
.
equals
(
aliPayBillData
.
getTradeType
(),
"交易"
))
{
aliPayTradeList
.
add
(
aliPayBillData
);
}
if
(
StringUtils
.
equals
(
aliPayBillData
.
getTradeType
(),
"退款"
))
{
aliPayRefundList
.
add
(
aliPayBillData
);
}
}
// 对比交易数据,支付宝商户后台有,但是支付中心数据库中没有的数据列表
BigDecimal
aliTradeAmount
=
new
BigDecimal
(
0
);
List
<
AliPayBillData
>
notInPayCenterTradeList
=
new
ArrayList
<>();
for
(
AliPayBillData
aliPayBillData:
aliPayTradeList
)
{
String
merchantOrderNo
=
aliPayBillData
.
getMerchantOrderNo
();
String
orderAmount
=
aliPayBillData
.
getOrderAmount
();
aliTradeAmount
=
aliTradeAmount
.
add
(
new
BigDecimal
(
orderAmount
));
boolean
flag
=
false
;
for
(
Map
<
String
,
Object
>
map:
payOrderList
)
{
if
(
StringUtils
.
equals
(
map
.
get
(
"call_flow_no"
).
toString
(),
merchantOrderNo
)
&&
StringUtils
.
equals
(
map
.
get
(
"amount"
).
toString
(),
orderAmount
))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInPayCenterTradeList
.
add
(
aliPayBillData
);
}
}
// 对比交易数据,支付中心有,但是支付宝商户后台没有
BigDecimal
payCenterTradeAmount
=
new
BigDecimal
(
0
);
List
<
Map
<
String
,
Object
>>
notInAliTradeList
=
new
ArrayList
<>();
for
(
Map
<
String
,
Object
>
map:
payOrderList
)
{
String
callFlowNo
=
map
.
get
(
"call_flow_no"
).
toString
();
String
amount
=
map
.
get
(
"amount"
).
toString
();
payCenterTradeAmount
=
payCenterTradeAmount
.
add
(
new
BigDecimal
(
amount
));
boolean
flag
=
false
;
for
(
AliPayBillData
aliPayBillData:
aliPayTradeList
)
{
if
(
StringUtils
.
equals
(
callFlowNo
,
aliPayBillData
.
getMerchantOrderNo
())
&&
StringUtils
.
equals
(
amount
,
aliPayBillData
.
getOrderAmount
()))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInAliTradeList
.
add
(
map
);
}
}
// 对比退款数据,支付宝商户后台有,但是支付中心数据库中没有的数据列表
BigDecimal
aliRefundAmount
=
new
BigDecimal
(
0
);
List
<
AliPayBillData
>
notInPayCenterRefundList
=
new
ArrayList
<>();
for
(
AliPayBillData
aliPayBillData:
aliPayRefundList
)
{
String
merchantRefundOrderNo
=
aliPayBillData
.
getRefundOrderNo
();
String
refundAmount
=
aliPayBillData
.
getOrderAmount
();
aliRefundAmount
=
aliRefundAmount
.
add
(
new
BigDecimal
(
refundAmount
));
boolean
flag
=
false
;
for
(
Map
<
String
,
Object
>
map:
refundOrderList
)
{
if
(
StringUtils
.
equals
(
map
.
get
(
"refund_order_id"
).
toString
(),
merchantRefundOrderNo
)
&&
StringUtils
.
equals
(
map
.
get
(
"refund_amount"
).
toString
(),
refundAmount
))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInPayCenterRefundList
.
add
(
aliPayBillData
);
}
}
// 对比退款数据,支付中心有,但是支付宝商户后台没有
BigDecimal
payCenterRefundAmount
=
new
BigDecimal
(
0
);
List
<
Map
<
String
,
Object
>>
notInAliRefundList
=
new
ArrayList
<>();
for
(
Map
<
String
,
Object
>
map:
refundOrderList
)
{
String
refundOrderId
=
map
.
get
(
"refund_order_id"
).
toString
();
String
refundAmount
=
map
.
get
(
"refund_amount"
).
toString
();
payCenterRefundAmount
=
payCenterRefundAmount
.
add
(
new
BigDecimal
(
refundAmount
));
boolean
flag
=
false
;
for
(
AliPayBillData
aliPayBillData:
aliPayRefundList
)
{
if
(
StringUtils
.
equals
(
refundOrderId
,
aliPayBillData
.
getRefundOrderNo
())
&&
StringUtils
.
equals
(
refundAmount
,
aliPayBillData
.
getOrderAmount
()))
{
flag
=
true
;
}
}
if
(!
flag
)
{
notInAliRefundList
.
add
(
map
);
}
}
String
text
=
"日期:"
+
billDate
+
"\n\n"
+
"支付宝商户平台-交易金额:"
+
aliTradeAmount
+
"\n\n"
+
"支付中心-支付宝交易金额:"
+
payCenterTradeAmount
+
"\n\n"
+
"支付宝商户平台-退款金额:"
+
aliRefundAmount
+
"\n\n"
+
"支付中心-支付宝退款金额:"
+
payCenterRefundAmount
+
"\n\n"
;
if
(
aliTradeAmount
.
compareTo
(
payCenterTradeAmount
)
!=
0
)
{
int
tradeErrorCount
=
notInPayCenterTradeList
.
size
()
+
notInAliTradeList
.
size
();
text
+=
"**交易异常数据:共"
+
tradeErrorCount
+
"条**\n\n"
;
int
index
=
0
;
if
(
notInPayCenterTradeList
.
size
()
>
0
)
{
text
+=
"支付宝平台有,支付中心没有的数据:\n\n"
;
for
(
AliPayBillData
aliPayBillData:
notInPayCenterTradeList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 交易时间:"
+
aliPayBillData
.
getTradeTime
()
+
"\n\n"
;
text
+=
"> 支付宝订单号:"
+
aliPayBillData
.
getAliPayTradeNo
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
aliPayBillData
.
getMerchantOrderNo
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
aliPayBillData
.
getOrderAmount
()
+
"\n\n"
;
}
}
if
(
notInAliTradeList
.
size
()
>
0
)
{
text
+=
"支付中心有,支付宝平台没有的数据:\n\n"
;
for
(
Map
<
String
,
Object
>
map:
notInAliTradeList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
map
.
get
(
"updated_at"
).
toString
()
+
"\n\n"
;
text
+=
"> 支付宝订单号:"
+
map
.
get
(
"third_trade_no"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
map
.
get
(
"call_flow_no"
).
toString
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
map
.
get
(
"amount"
).
toString
()
+
"\n\n"
;
}
}
}
if
(
aliRefundAmount
.
compareTo
(
payCenterRefundAmount
)
!=
0
)
{
int
refundErrorCount
=
notInAliRefundList
.
size
()
+
notInPayCenterRefundList
.
size
();
text
+=
"**退款异常数据:共"
+
refundErrorCount
+
"条**\n\n"
;
int
index
=
0
;
if
(
notInPayCenterRefundList
.
size
()
>
0
)
{
text
+=
"支付宝平台有,支付中心没有的数据:\n\n"
;
for
(
AliPayBillData
aliPayBillData:
notInPayCenterRefundList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
aliPayBillData
.
getTradeTime
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
aliPayBillData
.
getMerchantOrderNo
()
+
"\n\n"
;
text
+=
"> 商户退款单号:"
+
aliPayBillData
.
getRefundOrderNo
()
+
"\n\n"
;
text
+=
"> 退款金额:"
+
aliPayBillData
.
getOrderAmount
()
+
"\n\n"
;
}
}
if
(
notInAliRefundList
.
size
()
>
0
)
{
text
+=
"支付中心有,支付宝平台没有的数据:\n\n"
;
for
(
Map
<
String
,
Object
>
map:
notInAliRefundList
)
{
if
(
index
>
0
)
{
text
+=
"> ----------------\n\n"
;
}
index
+=
1
;
text
+=
"> 时间:"
+
map
.
get
(
"updated_at"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户订单号:"
+
map
.
get
(
"repay_order_id"
).
toString
()
+
"\n\n"
;
text
+=
"> 商户退款单号:"
+
map
.
get
(
"refund_order_id"
).
toString
()
+
"\n\n"
;
text
+=
"> 订单金额:"
+
map
.
get
(
"refund_amount"
).
toString
()
+
"\n\n"
;
}
}
}
String
mkMsg
=
DingdingUtils
.
buildMarkdownMsg
(
"支付宝对账"
+
billDate
,
text
,
false
);
DingdingUtils
.
sendToDingding
(
mkMsg
,
reconciliationDingUrl
);
}
}
}
src/main/java/cn/qg/holmes/utils/DateUtils.java
0 → 100644
View file @
5513f075
package
cn
.
qg
.
holmes
.
utils
;
import
org.apache.commons.lang3.time.FastDateFormat
;
import
java.text.ParseException
;
import
java.time.*
;
import
java.time.format.DateTimeFormatter
;
import
java.util.Calendar
;
import
java.util.Date
;
/**
* 日期格式化工具类
*/
public
class
DateUtils
{
public
static
Date
getCurrentTime
()
{
return
new
Date
(
System
.
currentTimeMillis
());
}
public
static
String
getCurrentDate
(
String
pattern
)
{
LocalDate
now
=
LocalDate
.
now
();
return
now
.
format
(
DateTimeFormatter
.
ofPattern
(
pattern
));
}
public
static
String
convertDate
(
Date
date
,
String
pattern
)
{
return
FastDateFormat
.
getInstance
(
pattern
)
.
format
(
date
);
}
public
static
Date
convertStr
(
String
date
,
String
pattern
)
throws
ParseException
{
return
FastDateFormat
.
getInstance
(
pattern
)
.
parse
(
date
);
}
public
static
long
betweenDays
(
Date
dateBefore
,
Date
dateAfter
)
{
return
Duration
.
between
(
toLocalDate
(
dateBefore
).
atStartOfDay
(),
toLocalDate
(
dateAfter
).
atStartOfDay
())
.
toDays
();
}
public
static
LocalDate
toLocalDate
(
Date
date
)
{
return
date
.
toInstant
()
.
atZone
(
ZoneId
.
systemDefault
())
.
toLocalDate
();
}
public
static
String
formatLocalTime
(
LocalTime
localTime
,
String
pattern
)
{
return
DateTimeFormatter
.
ofPattern
(
pattern
).
format
(
localTime
);
}
public
static
String
formatLocalDate
(
LocalDate
localDate
,
String
pattern
)
{
return
DateTimeFormatter
.
ofPattern
(
pattern
).
format
(
localDate
);
}
// 获得某天最小时间 2020-02-17 00:00:00
public
static
Date
getStartOfDay
(
Date
date
)
{
LocalDateTime
localDateTime
=
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
date
.
getTime
()),
ZoneId
.
systemDefault
());
LocalDateTime
startOfDay
=
localDateTime
.
with
(
LocalTime
.
MIN
);
return
Date
.
from
(
startOfDay
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
());
}
// 获得某天最大时间 2020-02-19 23:59:59
public
static
Date
getEndOfDay
(
Date
date
)
{
LocalDateTime
localDateTime
=
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
date
.
getTime
()),
ZoneId
.
systemDefault
());
LocalDateTime
endOfDay
=
localDateTime
.
with
(
LocalTime
.
MAX
);
return
Date
.
from
(
endOfDay
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
());
}
// 获取指定日期的前几天
public
static
Date
getBeforeDay
(
Date
date
,
int
day
)
{
Calendar
calendar
=
Calendar
.
getInstance
();
calendar
.
setTime
(
date
);
calendar
.
add
(
Calendar
.
DAY_OF_MONTH
,
day
*
-
1
);
return
calendar
.
getTime
();
}
// 获取指定日期的后几天
public
static
Date
getAfterDay
(
Date
date
,
int
day
)
{
Calendar
c
=
Calendar
.
getInstance
();
c
.
setTimeInMillis
(
date
.
getTime
());
c
.
add
(
Calendar
.
DATE
,
day
);
return
new
Date
(
c
.
getTimeInMillis
());
}
}
src/main/resources/alipay/alipayCertPublicKey_RSA2.crt
0 → 100644
View file @
5513f075
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQICARFv38DKhJ31odYtzGpDANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE
BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0
aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs
YXNzIDIgUjEwHhcNMjAxMTE2MDcwMTMwWhcNMjIxMTE2MDcwMTMwWjCBjzELMAkGA1UEBhMCQ04x
KjAoBgNVBAoMIeWMl+S6rOmHj+WMlua0vuenkeaKgOaciemZkOWFrOWPuDEPMA0GA1UECwwGQWxp
cGF5MUMwQQYDVQQDDDrmlK/ku5jlrp0o5Lit5Zu9Kee9kee7nOaKgOacr+aciemZkOWFrOWPuC0y
MDg4OTMxOTU1NzA1MzIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm9LT+VzzI6Zy
r7ePg67m+6AB593Mpz9Pu3mdaYqhyN1MsW5p9l7Fjj/PSKJrCW7FzclCdDMVJrIMdopUMrscaHY8
ddncLA3+E0r5XK5+2lBmb35SNNlsKfVgnt122AymK5mkdar7rqOtQ1QrXM8NtlcY3UdZTUaPWbz5
0A/t2tlMoUSM9EANgqQbrT7wPIG+5bq6VWW2piVcyx+Qh0CLHLd9E3QSJKyYzYfJpLFjiQlSa8/S
aEHuBQTREyuO0/Kz/2Pxt5r7kkU80Yd0l4E1/oYPd3EhMbRpFNh79LxKjVtgxWq1hf2sdarvT9Ce
OftxnDn3yXTFXa9CEQqtByoANQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCA/gwDQYJKoZIhvcNAQEL
BQADggEBAEiC3Dzm+oayzvSJoZZA3jrxdRJhJ6pQQ1vGcCe1mNfR7XKA0r4ht4J4weTryF9tmUVw
6D+5UFdiA/2AfwOQ3rxmhc3TTN9xFDzm5koGfHFI9UV46PfBtugTUbgc+5HqsPPzcy6SvsQk3V17
/3ua+c/wM4Db9S7JX0Ug2kfFYsGZ/IxRQYmTiHDcD4FYUKjAep0uPbVu0/Nc5gR2OKiGwwr8MvDQ
dmozWdgJ42on5N7KkRNy0rRINQ9Z/QNMtQQ8GJB73rEbdty7q4psBsZ5Si2FuejNJSN4BuLybcM8
IZRSYtUFCmzX9QoKfUMQO215f6bxMK9GZFu0TyWTxlXjvr0=
-----END CERTIFICATE-----
src/main/resources/alipay/alipayRootCert.crt
0 → 100644
View file @
5513f075
-----BEGIN CERTIFICATE-----
MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG
EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw
MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO
UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE
MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT
V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti
W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ
MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b
53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI
pDoiVhsLwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE
BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0
MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV
BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j
aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk
rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2
xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp
dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6
vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl
YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1
Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H
DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98
SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG
PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe
9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC
AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90
tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy
nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf
tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq
JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3
IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW
05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41
T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI
kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop
PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N
1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y
jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02
77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi
kT9qhqn+lw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG
EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0
WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp
YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU
WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt
rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ
4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2
zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg
wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH
Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF
BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM
E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg
MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq
MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp
bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv
b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV
nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5
4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg
wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw
WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN
z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g
KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA
uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF
MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp
emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3
U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I
UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn
DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU
1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX
Yf4Zr0fJsGuv
-----END CERTIFICATE-----
\ No newline at end of file
src/main/resources/alipay/appCertPublicKey_2021002106644714.crt
0 → 100644
View file @
5513f075
-----BEGIN CERTIFICATE-----
MIIErjCCA5agAwIBAgIQICARGDrIh1PZVJ5tAyihwzANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE
BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0
aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs
YXNzIDEgUjEwHhcNMjAxMTE4MDkwOTE2WhcNMjIxMTE4MDkwOTE2WjB2MQswCQYDVQQGEwJDTjEq
MCgGA1UECgwh5YyX5Lqs6YeP5YyW5rS+56eR5oqA5pyJ6ZmQ5YWs5Y+4MQ8wDQYDVQQLDAZBbGlw
YXkxKjAoBgNVBAMMITIwODg5MzE5NTU3MDUzMjMtMjAyMTAwMjEwNjY0NDcxNDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALeuAdr/HruBpjTxEmh5VYuCECJCigsb906iNb7rf1EC6KuH
EvJ65rBtxyHb3W6P/3Qw9NDLzqc0opAFt63jUxC1Lwvq2z/kGOnYZiDOxCWY8JFYTsiX3j/pHXx+
D1llDivHbzQGtfrSEpMVwz6ufoi40CJPvAcxyyOidEuxtZb9lpKYzColx+FFTb/xKXOfDYBfyMez
df9lm0zy6ybcd3jVT2bsMhE+B6OjjCWBOZSsUmuBAhZ2y5IJibzxrgHMVzdZ9rY2jmy2qQdmLOyy
HHnZQY6C+Al3EXo9SoL1p/6pBJ2V1Nxs55COBBsk4t+Jmg9DPI7wNqzMjMmQHwUHfwMCAwEAAaOC
ASkwggElMB8GA1UdIwQYMBaAFHEH4gRhFuTl8mXrMQ/J4PQ8mtWRMB0GA1UdDgQWBBQImTjGQ3Bx
PQVszP7T4OZ+am6YGTBABgNVHSAEOTA3MDUGB2CBHAFuAQEwKjAoBggrBgEFBQcCARYcaHR0cDov
L2NhLmFsaXBheS5jb20vY3BzLnBkZjAOBgNVHQ8BAf8EBAMCBsAwLwYDVR0fBCgwJjAkoCKgIIYe
aHR0cDovL2NhLmFsaXBheS5jb20vY3JsNDcuY3JsMGAGCCsGAQUFBwEBBFQwUjAoBggrBgEFBQcw
AoYcaHR0cDovL2NhLmFsaXBheS5jb20vY2E2LmNlcjAmBggrBgEFBQcwAYYaaHR0cDovL2NhLmFs
aXBheS5jb206ODM0MC8wDQYJKoZIhvcNAQELBQADggEBAAuKP7KQadec991A8SFAZsaIHIPFb5mb
Tb+shnzi71IeNsAnBWqhjKzBwEMAeyJt6z652pOE3zuzJ5XimPS5AUz8ZK91D9ViEuk03vBs1r2g
ZW5dEmqZwg0m2q7KXV8hNjzSKqlSyVojxjHwvdh6iHsKCtiMz0CRic6CkKMSTInP98g1lYjxsbL2
Vr1o22BvOtdr2sGeYFZbe8eNURyfmeiIPGcOwOwLURc0U32tm4MP+PqceW6jzRjjh7VCU0luOHWT
ZRnO4jWrhkF3E1Cqgg2OUWEdd2yAsbUuMbVb7Hm1HPNGOY5/V/D1AW3l4Obc+SffrPZKM/QJK3sq
VUPXWU8=
-----END CERTIFICATE-----
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment