Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
IJPay
提交
7807d402
I
IJPay
项目概览
int
/
IJPay
9 个月 前同步成功
通知
4
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
IJPay
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7807d402
编写于
7月 18, 2019
作者:
J
Javen205
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
WxPay
上级
16b027b8
变更
19
展开全部
隐藏空白更改
内联
并排
Showing
19 changed file
with
1688 addition
and
15 deletion
+1688
-15
IJPay-Demo/pom.xml
IJPay-Demo/pom.xml
+5
-0
IJPay-Demo/src/main/java/com/ijpay/demo/controller/wxpay/WxPayController.java
...java/com/ijpay/demo/controller/wxpay/WxPayController.java
+116
-0
IJPay-Demo/src/main/java/com/ijpay/demo/entity/AliPayBean.java
...-Demo/src/main/java/com/ijpay/demo/entity/AliPayBean.java
+12
-13
IJPay-Demo/src/main/java/com/ijpay/demo/entity/WxPayBean.java
...y-Demo/src/main/java/com/ijpay/demo/entity/WxPayBean.java
+71
-0
IJPay-Demo/src/main/java/com/ijpay/demo/kit/IpKit.java
IJPay-Demo/src/main/java/com/ijpay/demo/kit/IpKit.java
+27
-0
IJPay-Demo/src/main/java/com/ijpay/demo/utils/StringUtils.java
...-Demo/src/main/java/com/ijpay/demo/utils/StringUtils.java
+1
-1
IJPay-Demo/src/main/resources/application.yml
IJPay-Demo/src/main/resources/application.yml
+1
-1
IJPay-Demo/src/main/resources/production/wxpay.properties
IJPay-Demo/src/main/resources/production/wxpay.properties
+6
-0
IJPay-WxPay/pom.xml
IJPay-WxPay/pom.xml
+15
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/HttpDelegate.java
IJPay-WxPay/src/main/java/com/ijpay/wxpay/HttpDelegate.java
+82
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/WxPayApi.java
IJPay-WxPay/src/main/java/com/ijpay/wxpay/WxPayApi.java
+720
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/XmlHelper.java
IJPay-WxPay/src/main/java/com/ijpay/wxpay/XmlHelper.java
+252
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/PayModel.java
...rc/main/java/com/ijpay/wxpay/constant/enums/PayModel.java
+29
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/SignType.java
...rc/main/java/com/ijpay/wxpay/constant/enums/SignType.java
+22
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/TradeType.java
...c/main/java/com/ijpay/wxpay/constant/enums/TradeType.java
+40
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/HttpKit.java
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/HttpKit.java
+29
-0
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/WxPayKit.java
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/WxPayKit.java
+214
-0
IJPay-WxPay/src/test/java/com/ijpay/wxpay/WxPayKitTest.java
IJPay-WxPay/src/test/java/com/ijpay/wxpay/WxPayKitTest.java
+37
-0
pom.xml
pom.xml
+9
-0
未找到文件。
IJPay-Demo/pom.xml
浏览文件 @
7807d402
...
...
@@ -20,6 +20,7 @@
<java.version>
1.8
</java.version>
<ijapy.alipay.version>
2.0.0
</ijapy.alipay.version>
<ijapy.wxpay.version>
2.0.0
</ijapy.wxpay.version>
</properties>
<dependencies>
...
...
@@ -48,6 +49,10 @@
<groupId>
com.github.javen205
</groupId>
<artifactId>
IJPay-AliPay
</artifactId>
<version>
${ijapy.alipay.version}
</version>
</dependency><dependency>
<groupId>
com.github.javen205
</groupId>
<artifactId>
IJPay-WxPay
</artifactId>
<version>
${ijapy.wxpay.version}
</version>
</dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
...
...
IJPay-Demo/src/main/java/com/ijpay/demo/controller/wxpay/WxPayController.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.demo.controller.wxpay
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.ijpay.demo.entity.WxPayBean
;
import
com.ijpay.demo.kit.IpKit
;
import
com.ijpay.demo.vo.AjaxResult
;
import
com.ijpay.wxpay.WxPayApi
;
import
com.ijpay.wxpay.constant.enums.SignType
;
import
com.ijpay.wxpay.constant.enums.TradeType
;
import
com.ijpay.wxpay.kit.WxPayKit
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author Javen
*/
@Controller
@RequestMapping
(
"/wxpay"
)
public
class
WxPayController
{
private
Logger
log
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
private
AjaxResult
result
=
new
AjaxResult
();
@Autowired
WxPayBean
wxPayBean
;
@RequestMapping
(
""
)
@ResponseBody
public
String
index
()
{
log
.
info
(
"欢迎使用 IJPay 中的微信支付 -By Javen <br/><br> 交流群:723992875"
);
log
.
info
(
wxPayBean
.
toString
());
return
(
"欢迎使用 IJPay 中的微信支付 -By Javen <br/><br> 交流群:723992875"
);
}
@GetMapping
(
"/test"
)
@ResponseBody
public
WxPayBean
test
()
{
return
wxPayBean
;
}
@GetMapping
(
"/getKey"
)
@ResponseBody
public
String
getKey
()
{
return
WxPayApi
.
getSignKey
(
wxPayBean
.
getMchId
(),
wxPayBean
.
getPartnerKey
(),
SignType
.
MD5
);
}
/**
* 公众号支付
*/
@RequestMapping
(
value
=
"/webPay"
,
method
=
{
RequestMethod
.
POST
,
RequestMethod
.
GET
})
@ResponseBody
public
AjaxResult
webPay
(
HttpServletRequest
request
,
@RequestParam
(
"total_fee"
)
String
total_fee
)
{
// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
String
openId
=
(
String
)
request
.
getSession
().
getAttribute
(
"openId"
);
if
(
openId
==
null
){
openId
=
"11111111"
;
}
if
(
StrUtil
.
isEmpty
(
openId
))
{
result
.
addError
(
"openId is null"
);
return
result
;
}
if
(
StrUtil
.
isEmpty
(
total_fee
))
{
result
.
addError
(
"请输入数字金额"
);
return
result
;
}
String
ip
=
IpKit
.
getRealIp
(
request
);
if
(
StrUtil
.
isEmpty
(
ip
))
{
ip
=
"127.0.0.1"
;
}
Map
<
String
,
String
>
params
=
new
HashMap
<>();
params
.
put
(
"appid"
,
wxPayBean
.
getAppId
());
params
.
put
(
"mch_id"
,
wxPayBean
.
getMchId
());
params
.
put
(
"body"
,
"IJPay"
);
params
.
put
(
"attach"
,
"IJPay"
);
params
.
put
(
"out_trade_no"
,
WxPayKit
.
generateStr
());
params
.
put
(
"total_fee"
,
total_fee
);
params
.
put
(
"spbill_create_ip"
,
ip
);
params
.
put
(
"notify_url"
,
wxPayBean
.
getDomain
().
concat
(
"/wxpay/pay_notify"
));
params
.
put
(
"trade_type"
,
TradeType
.
JSAPI
.
getTradeType
());
String
xmlResult
=
WxPayApi
.
pushOrder
(
false
,
WxPayKit
.
buildSign
(
params
,
wxPayBean
.
getPartnerKey
(),
SignType
.
MD5
));
log
.
info
(
xmlResult
);
Map
<
String
,
String
>
resultMap
=
WxPayKit
.
xmlToMap
(
xmlResult
);
String
return_code
=
resultMap
.
get
(
"return_code"
);
String
return_msg
=
resultMap
.
get
(
"return_msg"
);
if
(!
WxPayKit
.
codeIsOK
(
return_code
))
{
result
.
addError
(
return_msg
);
return
result
;
}
String
result_code
=
resultMap
.
get
(
"result_code"
);
if
(!
WxPayKit
.
codeIsOK
(
result_code
))
{
result
.
addError
(
return_msg
);
return
result
;
}
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
String
prepay_id
=
resultMap
.
get
(
"prepay_id"
);
Map
<
String
,
String
>
packageParams
=
WxPayKit
.
prepayIdCreateSign
(
prepay_id
,
wxPayBean
.
getAppId
(),
wxPayBean
.
getPartnerKey
());
String
jsonStr
=
JSON
.
toJSONString
(
packageParams
);
result
.
success
(
jsonStr
);
return
result
;
}
}
IJPay-Demo/src/main/java/com/ijpay/demo/entity/AliPayBean.java
浏览文件 @
7807d402
...
...
@@ -46,21 +46,20 @@ public class AliPayBean {
this
.
serverUrl
=
serverUrl
;
}
public
String
getDomain
()
{
return
domain
;
}
public
String
getDomain
()
{
return
domain
;
}
public
void
setDomain
(
String
domain
)
{
this
.
domain
=
domain
;
}
public
void
setDomain
(
String
domain
)
{
this
.
domain
=
domain
;
}
@Override
public
String
toString
()
{
return
"AliPayBean [appId="
+
appId
+
", privateKey="
+
privateKey
+
", publicKey="
+
publicKey
+
", serverUrl="
+
serverUrl
+
", domain="
+
domain
+
"]"
;
}
@Override
public
String
toString
()
{
return
"AliPayBean [appId="
+
appId
+
", privateKey="
+
privateKey
+
", publicKey="
+
publicKey
+
", serverUrl="
+
serverUrl
+
", domain="
+
domain
+
"]"
;
}
}
\ No newline at end of file
IJPay-Demo/src/main/java/com/ijpay/demo/entity/WxPayBean.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.demo.entity
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.stereotype.Component
;
@Component
@PropertySource
(
"classpath:/production/wxpay.properties"
)
@ConfigurationProperties
(
prefix
=
"wxpay"
)
public
class
WxPayBean
{
private
String
appId
;
private
String
appSecret
;
private
String
mchId
;
private
String
partnerKey
;
private
String
certPath
;
private
String
domain
;
public
String
getAppId
()
{
return
appId
;
}
public
void
setAppId
(
String
appId
)
{
this
.
appId
=
appId
;
}
public
String
getAppSecret
()
{
return
appSecret
;
}
public
void
setAppSecret
(
String
appSecret
)
{
this
.
appSecret
=
appSecret
;
}
public
String
getMchId
()
{
return
mchId
;
}
public
void
setMchId
(
String
mchId
)
{
this
.
mchId
=
mchId
;
}
public
String
getPartnerKey
()
{
return
partnerKey
;
}
public
void
setPartnerKey
(
String
partnerKey
)
{
this
.
partnerKey
=
partnerKey
;
}
public
String
getCertPath
()
{
return
certPath
;
}
public
void
setCertPath
(
String
certPath
)
{
this
.
certPath
=
certPath
;
}
public
String
getDomain
()
{
return
domain
;
}
public
void
setDomain
(
String
domain
)
{
this
.
domain
=
domain
;
}
@Override
public
String
toString
()
{
return
"WxPayBean [appId="
+
appId
+
", appSecret="
+
appSecret
+
", mchId="
+
mchId
+
", partnerKey="
+
partnerKey
+
", certPath="
+
certPath
+
", domain="
+
domain
+
"]"
;
}
}
\ No newline at end of file
IJPay-Demo/src/main/java/com/ijpay/demo/kit/IpKit.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.demo.kit
;
import
javax.servlet.http.HttpServletRequest
;
public
class
IpKit
{
public
static
String
getRealIp
(
HttpServletRequest
request
)
{
String
ip
=
request
.
getHeader
(
"x-forwarded-for"
);
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getRemoteAddr
();
}
return
ip
;
}
public
static
String
getRealIpV2
(
HttpServletRequest
request
)
{
String
accessIP
=
request
.
getHeader
(
"x-forwarded-for"
);
if
(
null
==
accessIP
)
return
request
.
getRemoteAddr
();
return
accessIP
;
}
}
\ No newline at end of file
IJPay-Demo/src/main/java/com/ijpay/demo/utils/StringUtils.java
浏览文件 @
7807d402
...
...
@@ -29,7 +29,7 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
* @return {String}
*
*/
public
static
String
ge
tUUID
()
{
public
static
String
ge
nerateStr
()
{
return
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
}
...
...
IJPay-Demo/src/main/resources/application.yml
浏览文件 @
7807d402
server
:
port
:
8081
port
:
7788
IJPay-Demo/src/main/resources/production/wxpay.properties
0 → 100644
浏览文件 @
7807d402
wxpay.appId
=
wx50037ba14d1ab128
wxpay.appSecret
=
67a9a24f899ce7b5170d96872f3081a9
wxpay.mchId
=
1445388302
wxpay.partnerKey
=
CQtr0JyC4XiTPMXhxED93MsbcPM7zG83
wxpay.certPath
=
/Users/Javen/Documents/dev/IJPay/wxpay/1444446802_20181219_cert/apiclient_cert.p1
wxpay.domain
=
https://ijpay.javen.com
\ No newline at end of file
IJPay-WxPay/pom.xml
0 → 100644
浏览文件 @
7807d402
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
IJPay
</artifactId>
<groupId>
com.github.javen205
</groupId>
<version>
2.0.0
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
IJPay-WxPay
</artifactId>
</project>
\ No newline at end of file
IJPay-WxPay/src/main/java/com/ijpay/wxpay/HttpDelegate.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay
;
import
cn.hutool.http.HttpRequest
;
import
cn.hutool.http.HttpUtil
;
import
cn.hutool.http.ssl.SSLSocketFactoryBuilder
;
import
javax.net.ssl.KeyManager
;
import
javax.net.ssl.KeyManagerFactory
;
import
java.io.FileInputStream
;
import
java.io.InputStream
;
import
java.security.KeyStore
;
import
java.security.SecureRandom
;
import
java.util.Map
;
/**
* Http 代理类
*
* @author Javen
*/
public
abstract
class
HttpDelegate
{
protected
String
get
(
String
url
)
{
return
HttpUtil
.
get
(
url
);
}
protected
String
get
(
String
url
,
Map
<
String
,
Object
>
paramMap
)
{
return
HttpUtil
.
get
(
url
,
paramMap
);
}
protected
String
post
(
String
url
,
String
data
)
{
return
HttpUtil
.
post
(
url
,
data
);
}
protected
String
post
(
String
url
,
Map
<
String
,
Object
>
paramMap
){
return
HttpUtil
.
post
(
url
,
paramMap
);
}
protected
String
postSSL
(
String
url
,
String
data
,
String
certPath
,
String
certPass
){
try
{
return
HttpRequest
.
post
(
url
)
.
setSSLSocketFactory
(
SSLSocketFactoryBuilder
.
create
()
.
setProtocol
(
SSLSocketFactoryBuilder
.
TLSv1
)
.
setKeyManagers
(
getKeyManager
(
certPass
,
certPath
,
null
))
.
setSecureRandom
(
new
SecureRandom
())
.
build
()
)
.
body
(
data
)
.
execute
()
.
body
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
protected
String
postSSL
(
String
url
,
String
data
,
InputStream
certFile
,
String
certPass
){
try
{
return
HttpRequest
.
post
(
url
)
.
setSSLSocketFactory
(
SSLSocketFactoryBuilder
.
create
()
.
setProtocol
(
SSLSocketFactoryBuilder
.
TLSv1
)
.
setKeyManagers
(
getKeyManager
(
certPass
,
null
,
certFile
))
.
setSecureRandom
(
new
SecureRandom
())
.
build
()
)
.
body
(
data
)
.
execute
()
.
body
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
private
KeyManager
[]
getKeyManager
(
String
certPass
,
String
certPath
,
InputStream
certFile
)
throws
Exception
{
KeyStore
clientStore
=
KeyStore
.
getInstance
(
"PKCS12"
);
if
(
certFile
!=
null
)
clientStore
.
load
(
certFile
,
certPass
.
toCharArray
());
else
clientStore
.
load
(
new
FileInputStream
(
certPath
),
certPass
.
toCharArray
());
KeyManagerFactory
kmf
=
KeyManagerFactory
.
getInstance
(
KeyManagerFactory
.
getDefaultAlgorithm
());
kmf
.
init
(
clientStore
,
certPass
.
toCharArray
());
return
kmf
.
getKeyManagers
();
}
}
IJPay-WxPay/src/main/java/com/ijpay/wxpay/WxPayApi.java
0 → 100644
浏览文件 @
7807d402
此差异已折叠。
点击以展开。
IJPay-WxPay/src/main/java/com/ijpay/wxpay/XmlHelper.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.Element
;
import
org.w3c.dom.Node
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
javax.xml.namespace.QName
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
javax.xml.xpath.XPath
;
import
javax.xml.xpath.XPathConstants
;
import
javax.xml.xpath.XPathExpressionException
;
import
javax.xml.xpath.XPathFactory
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.StringReader
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* xpath解析xml
*
* <pre>
* 文档地址:
* http://www.w3school.com.cn/xpath/index.asp
* </pre>
*/
public
class
XmlHelper
{
private
final
XPath
path
;
private
final
Document
doc
;
private
XmlHelper
(
InputSource
inputSource
)
throws
ParserConfigurationException
,
SAXException
,
IOException
{
DocumentBuilderFactory
dbf
=
getDocumentBuilderFactory
();
// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all
// XML entity attacks are prevented
// Xerces 2 only -
// http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
dbf
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 -
// http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 -
// http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
dbf
.
setFeature
(
"http://xml.org/sax/features/external-general-entities"
,
false
);
// Xerces 1 -
// http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 -
// http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
dbf
.
setFeature
(
"http://xml.org/sax/features/external-parameter-entities"
,
false
);
// Disable external DTDs as well
dbf
.
setFeature
(
"http://apache.org/xml/features/nonvalidating/load-external-dtd"
,
false
);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and
// Entity Attacks"
dbf
.
setXIncludeAware
(
false
);
dbf
.
setExpandEntityReferences
(
false
);
DocumentBuilder
db
=
dbf
.
newDocumentBuilder
();
doc
=
db
.
parse
(
inputSource
);
path
=
getXPathFactory
().
newXPath
();
}
private
static
XmlHelper
create
(
InputSource
inputSource
)
{
try
{
return
new
XmlHelper
(
inputSource
);
}
catch
(
ParserConfigurationException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
SAXException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
XmlHelper
of
(
InputStream
is
)
{
InputSource
inputSource
=
new
InputSource
(
is
);
return
create
(
inputSource
);
}
public
static
XmlHelper
of
(
File
file
)
{
InputSource
inputSource
=
new
InputSource
(
file
.
toURI
().
toASCIIString
());
return
create
(
inputSource
);
}
public
static
XmlHelper
of
(
String
xmlStr
)
{
StringReader
sr
=
new
StringReader
(
xmlStr
.
trim
());
InputSource
inputSource
=
new
InputSource
(
sr
);
XmlHelper
xmlHelper
=
create
(
inputSource
);
sr
.
close
();
return
xmlHelper
;
}
private
Object
evalXPath
(
String
expression
,
Object
item
,
QName
returnType
)
{
item
=
null
==
item
?
doc
:
item
;
try
{
return
path
.
evaluate
(
expression
,
item
,
returnType
);
}
catch
(
XPathExpressionException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* 获取String
*
* @param expression 路径
* @return String
*/
public
String
getString
(
String
expression
)
{
return
(
String
)
evalXPath
(
expression
,
null
,
XPathConstants
.
STRING
);
}
/**
* 获取Boolean
*
* @param expression 路径
* @return String
*/
public
Boolean
getBoolean
(
String
expression
)
{
return
(
Boolean
)
evalXPath
(
expression
,
null
,
XPathConstants
.
BOOLEAN
);
}
/**
* 获取Number
*
* @param expression 路径
* @return {Number}
*/
public
Number
getNumber
(
String
expression
)
{
return
(
Number
)
evalXPath
(
expression
,
null
,
XPathConstants
.
NUMBER
);
}
/**
* 获取某个节点
*
* @param expression 路径
* @return {Node}
*/
public
Node
getNode
(
String
expression
)
{
return
(
Node
)
evalXPath
(
expression
,
null
,
XPathConstants
.
NODE
);
}
/**
* 获取子节点
*
* @param expression 路径
* @return NodeList
*/
public
NodeList
getNodeList
(
String
expression
)
{
return
(
NodeList
)
evalXPath
(
expression
,
null
,
XPathConstants
.
NODESET
);
}
/**
* 获取String
*
* @param node 节点
* @param expression 相对于node的路径
* @return String
*/
public
String
getString
(
Object
node
,
String
expression
)
{
return
(
String
)
evalXPath
(
expression
,
node
,
XPathConstants
.
STRING
);
}
/**
* 获取
*
* @param node 节点
* @param expression 相对于node的路径
* @return String
*/
public
Boolean
getBoolean
(
Object
node
,
String
expression
)
{
return
(
Boolean
)
evalXPath
(
expression
,
node
,
XPathConstants
.
BOOLEAN
);
}
/**
* 获取
*
* @param node 节点
* @param expression 相对于node的路径
* @return {Number}
*/
public
Number
getNumber
(
Object
node
,
String
expression
)
{
return
(
Number
)
evalXPath
(
expression
,
node
,
XPathConstants
.
NUMBER
);
}
/**
* 获取某个节点
*
* @param node 节点
* @param expression 路径
* @return {Node}
*/
public
Node
getNode
(
Object
node
,
String
expression
)
{
return
(
Node
)
evalXPath
(
expression
,
node
,
XPathConstants
.
NODE
);
}
/**
* 获取子节点
*
* @param node 节点
* @param expression 相对于node的路径
* @return NodeList
*/
public
NodeList
getNodeList
(
Object
node
,
String
expression
)
{
return
(
NodeList
)
evalXPath
(
expression
,
node
,
XPathConstants
.
NODESET
);
}
/**
* 针对没有嵌套节点的简单处理
*
* @return map集合
*/
public
Map
<
String
,
String
>
toMap
()
{
Element
root
=
doc
.
getDocumentElement
();
Map
<
String
,
String
>
params
=
new
HashMap
<
String
,
String
>();
// 将节点封装成map形式
NodeList
list
=
root
.
getChildNodes
();
for
(
int
i
=
0
;
i
<
list
.
getLength
();
i
++)
{
Node
node
=
list
.
item
(
i
);
params
.
put
(
node
.
getNodeName
(),
node
.
getTextContent
());
}
// 含有空白符会生成一个#text参数
params
.
remove
(
"#text"
);
return
params
;
}
private
static
DocumentBuilderFactory
getDocumentBuilderFactory
()
{
return
XmlHelper
.
XmlHelperHolder
.
documentBuilderFactory
;
}
private
static
XPathFactory
getXPathFactory
()
{
return
XmlHelper
.
XmlHelperHolder
.
xPathFactory
;
}
/**
* 内部类单例
*/
private
static
class
XmlHelperHolder
{
private
static
DocumentBuilderFactory
documentBuilderFactory
=
DocumentBuilderFactory
.
newInstance
();
private
static
XPathFactory
xPathFactory
=
XPathFactory
.
newInstance
();
}
}
\ No newline at end of file
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/PayModel.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay.constant.enums
;
public
enum
PayModel
{
BUSINESS_MODEL
(
"BUSINESS_MODEL"
,
"商户模式"
),
SERVICE_MODE
(
"SERVICE_MODE"
,
"服务商模式"
);
PayModel
(
String
payModel
,
String
description
)
{
this
.
payModel
=
payModel
;
this
.
description
=
description
;
}
/**
* 商户模式
*/
private
final
String
payModel
;
/**
* 描述
*/
private
final
String
description
;
public
String
getPayModel
()
{
return
payModel
;
}
public
String
getDescription
()
{
return
description
;
}
}
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/SignType.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay.constant.enums
;
/**
* 签名方式
*
* @author Javen
*/
public
enum
SignType
{
HMACSHA256
(
"HMAC-SHA256"
),
MD5
(
"MD5"
);
SignType
(
String
type
)
{
this
.
type
=
type
;
}
private
final
String
type
;
public
String
getType
()
{
return
type
;
}
}
IJPay-WxPay/src/main/java/com/ijpay/wxpay/constant/enums/TradeType.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay.constant.enums
;
public
enum
TradeType
{
JSAPI
(
"JSAPI"
,
"微信公众号支付或者小程序支付)"
),
NATIVE
(
"NATIVE"
,
"微信扫码支付"
),
APP
(
"APP"
,
"微信APP支付"
),
MICROPAY
(
"MICROPAY"
,
"付款码支付"
),
MWEB
(
"MWEB"
,
"H5支付"
);
/**
* 交易类型枚举<br/>
* JSAPI 公众号支付、小程序支付<br/>
* NATIVE 原生扫码支付<br/>
* APP APP支付<br/>
* MWEB WAP支付<br/>
* MICROPAY 刷卡支付<br/>
*/
TradeType
(
String
tradeType
,
String
description
)
{
this
.
tradeType
=
tradeType
;
this
.
description
=
description
;
}
/**
* 交易类型
*/
private
final
String
tradeType
;
/**
* 描述
*/
private
final
String
description
;
public
String
getTradeType
()
{
return
tradeType
;
}
public
String
getDescription
()
{
return
description
;
}
}
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/HttpKit.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay.kit
;
import
com.ijpay.wxpay.HttpDelegate
;
/**
* Http 工具类
*
* @author Javen
*/
public
class
HttpKit
{
private
static
HttpDelegate
delegate
=
new
DefaultHttpKit
();
public
static
HttpDelegate
getDelegate
()
{
return
delegate
;
}
public
static
void
setDelegate
(
HttpDelegate
delegate
)
{
HttpKit
.
delegate
=
delegate
;
}
}
/**
* 使用 hutool 实现的 Http 工具类
*
* @author Javen
*/
class
DefaultHttpKit
extends
HttpDelegate
{
}
IJPay-WxPay/src/main/java/com/ijpay/wxpay/kit/WxPayKit.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay.kit
;
import
cn.hutool.core.util.CharsetUtil
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.crypto.SecureUtil
;
import
cn.hutool.crypto.digest.HmacAlgorithm
;
import
com.ijpay.wxpay.XmlHelper
;
import
com.ijpay.wxpay.constant.enums.SignType
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLEncoder
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.TreeMap
;
public
class
WxPayKit
{
private
static
final
String
FIELD_SIGN
=
"sign"
;
private
static
final
String
FIELD_SIGN_TYPE
=
"sign_type"
;
public
static
String
hmacSHA256
(
String
data
,
String
key
)
{
return
SecureUtil
.
hmac
(
HmacAlgorithm
.
HmacSHA256
,
key
).
digestHex
(
data
,
CharsetUtil
.
UTF_8
);
}
public
static
String
md5
(
String
data
)
{
return
SecureUtil
.
md5
(
data
);
}
/**
* AES 解密
*
* @param base64Data 需要解密的数据
* @param key 密钥
* @return 解密后的数据
*/
public
static
String
decryptData
(
String
base64Data
,
String
key
)
{
return
SecureUtil
.
aes
(
md5
(
key
).
toLowerCase
().
getBytes
()).
decryptStr
(
base64Data
);
}
/**
* AES 加密
*
* @param data 需要加密的数据
* @param key 密钥
* @return 加密后的数据
*/
public
static
String
encryptData
(
String
data
,
String
key
)
{
return
SecureUtil
.
aes
(
md5
(
key
).
toLowerCase
().
getBytes
()).
encryptBase64
(
data
.
getBytes
());
}
public
static
String
generateStr
()
{
return
IdUtil
.
fastSimpleUUID
();
}
/**
* 组装签名的字段
*
* @param params 参数
* @param urlEncoder 是否urlEncoder
* @return {String}
*/
public
static
String
packageSign
(
Map
<
String
,
String
>
params
,
boolean
urlEncoder
)
{
// 先将参数以其参数名的字典序升序进行排序
TreeMap
<
String
,
String
>
sortedParams
=
new
TreeMap
<
String
,
String
>(
params
);
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
StringBuilder
sb
=
new
StringBuilder
();
boolean
first
=
true
;
for
(
Map
.
Entry
<
String
,
String
>
param
:
sortedParams
.
entrySet
())
{
String
value
=
param
.
getValue
();
if
(
StrUtil
.
isEmpty
(
value
))
{
continue
;
}
if
(
first
)
{
first
=
false
;
}
else
{
sb
.
append
(
"&"
);
}
sb
.
append
(
param
.
getKey
()).
append
(
"="
);
if
(
urlEncoder
)
{
try
{
value
=
urlEncode
(
value
);
}
catch
(
UnsupportedEncodingException
e
)
{
}
}
sb
.
append
(
value
);
}
return
sb
.
toString
();
}
public
static
String
urlEncode
(
String
src
)
throws
UnsupportedEncodingException
{
return
URLEncoder
.
encode
(
src
,
CharsetUtil
.
UTF_8
).
replace
(
"+"
,
"%20"
);
}
/**
* 生成签名
*
* @param params 需要签名的参数
* @param partnerKey 密钥
* @param signType 签名类型
* @return 签名后的数据
*/
public
static
String
createSign
(
Map
<
String
,
String
>
params
,
String
partnerKey
,
SignType
signType
)
{
if
(
signType
==
null
)
{
signType
=
SignType
.
MD5
;
}
// 生成签名前先去除sign
params
.
remove
(
FIELD_SIGN
);
String
stringA
=
packageSign
(
params
,
false
);
System
.
out
.
println
(
"stringA>>>"
+
stringA
);
String
stringSignTemp
=
stringA
+
"&key="
+
partnerKey
;
System
.
out
.
println
(
"stringSignTemp>>"
+
stringSignTemp
);
if
(
signType
==
SignType
.
MD5
)
return
md5
(
stringSignTemp
).
toUpperCase
();
else
return
hmacSHA256
(
stringSignTemp
,
partnerKey
).
toUpperCase
();
}
/**
* 构建签名
*
* @param params 需要签名的参数
* @param partnerKey 密钥
* @param signType 签名类型
* @return <@link Map<String, String>> 签名后的
*/
public
static
Map
<
String
,
String
>
buildSign
(
Map
<
String
,
String
>
params
,
String
partnerKey
,
SignType
signType
)
{
if
(
signType
==
null
)
{
signType
=
SignType
.
MD5
;
}
params
.
put
(
"nonce_str"
,
WxPayKit
.
generateStr
());
params
.
put
(
FIELD_SIGN_TYPE
,
signType
.
getType
());
String
sign
=
createSign
(
params
,
partnerKey
,
signType
);
params
.
put
(
FIELD_SIGN
,
sign
);
return
params
;
}
/**
* 微信下单 map to xml
*
* @param params Map 参数
* @return xml 字符串
*/
public
static
String
toXml
(
Map
<
String
,
String
>
params
)
{
StringBuilder
xml
=
new
StringBuilder
();
xml
.
append
(
"<xml>"
);
for
(
Map
.
Entry
<
String
,
String
>
entry
:
params
.
entrySet
())
{
String
key
=
entry
.
getKey
();
String
value
=
entry
.
getValue
();
// 略过空值
if
(
StrUtil
.
isEmpty
(
value
))
continue
;
xml
.
append
(
"<"
).
append
(
key
).
append
(
">"
);
xml
.
append
(
entry
.
getValue
());
xml
.
append
(
"</"
).
append
(
key
).
append
(
">"
);
}
xml
.
append
(
"</xml>"
);
return
xml
.
toString
();
}
/**
* 针对支付的 xml,没有嵌套节点的简单处理
*
* @param xmlStr xml 字符串
* @return <@link Map<String, String>>
*/
public
static
Map
<
String
,
String
>
xmlToMap
(
String
xmlStr
)
{
XmlHelper
xmlHelper
=
XmlHelper
.
of
(
xmlStr
);
return
xmlHelper
.
toMap
();
}
/**
* 替换url中的参数
*
* @param str 原始字符串
* @param regex 表达式
* @param args 替换字符串
* @return {String}
*/
public
static
String
replace
(
String
str
,
String
regex
,
String
...
args
)
{
for
(
String
arg:
args
)
{
str
=
str
.
replaceFirst
(
regex
,
arg
);
}
return
str
;
}
/**
* 判断接口返回的 code
*
* @param codeValue code 值
* @return 是否是 SUCCESS
*/
public
static
boolean
codeIsOK
(
String
codeValue
)
{
return
StrUtil
.
isNotEmpty
(
codeValue
)
&&
"SUCCESS"
.
equals
(
codeValue
);
}
/**
* 预付订单再次签名
* @param prepay_id 预付订单号
* @param appId 应用编号
* @param partnerKey API Key
* @return {@link Map<String,String>} 再次签名后的 Map
*/
public
static
Map
<
String
,
String
>
prepayIdCreateSign
(
String
prepay_id
,
String
appId
,
String
partnerKey
)
{
Map
<
String
,
String
>
packageParams
=
new
HashMap
<
String
,
String
>();
packageParams
.
put
(
"appId"
,
appId
);
packageParams
.
put
(
"timeStamp"
,
String
.
valueOf
(
System
.
currentTimeMillis
()
/
1000
));
packageParams
.
put
(
"nonceStr"
,
String
.
valueOf
(
System
.
currentTimeMillis
()));
packageParams
.
put
(
"package"
,
"prepay_id="
+
prepay_id
);
packageParams
.
put
(
"signType"
,
"MD5"
);
String
packageSign
=
WxPayKit
.
createSign
(
packageParams
,
partnerKey
,
SignType
.
MD5
);
packageParams
.
put
(
"paySign"
,
packageSign
);
return
packageParams
;
}
}
IJPay-WxPay/src/test/java/com/ijpay/wxpay/WxPayKitTest.java
0 → 100644
浏览文件 @
7807d402
package
com.ijpay.wxpay
;
import
com.ijpay.wxpay.kit.WxPayKit
;
import
org.junit.Assert
;
import
org.junit.Test
;
public
class
WxPayKitTest
{
@Test
public
void
hmacSHA256
(){
Assert
.
assertEquals
(
"9d67ee93641f99f0de85756c1debd8a4e315fbf8fd4ed966ed352bc1a658a8df"
,
WxPayKit
.
hmacSHA256
(
"IJPay 让支付触手可及"
,
"123"
));
}
@Test
public
void
mad5
(){
Assert
.
assertEquals
(
"42cc1d91bab89b65ff55b19e28fff4f0"
,
WxPayKit
.
md5
(
"IJPay 让支付触手可及"
));
}
@Test
public
void
generateStr
(){
Assert
.
assertEquals
(
"42cc1d91bab89b65ff55b19e28fff4f0"
,
WxPayKit
.
generateStr
());
}
@Test
public
void
encryptData
(){
Assert
.
assertEquals
(
""
,
WxPayKit
.
encryptData
(
"IJPay 让支付触手可及"
,
"42cc1d91bab89b65ff55b19e28fff4f0"
));
}
@Test
public
void
decryptData
(){
Assert
.
assertEquals
(
"IJPay 让支付触手可及"
,
WxPayKit
.
decryptData
(
WxPayKit
.
encryptData
(
"IJPay 让支付触手可及"
,
"42cc1d91bab89b65ff55b19e28fff4f0"
),
"42cc1d91bab89b65ff55b19e28fff4f0"
));
}
}
pom.xml
浏览文件 @
7807d402
...
...
@@ -44,11 +44,20 @@
<properties>
<jdk.version>
1.6
</jdk.version>
<junit.version>
4.12
</junit.version>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<project.reporting.outputEncoding>
UTF-8
</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- 全局单元测试 -->
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
${junit.version}
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-all
</artifactId>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录