Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
O
on-site-service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
external
on-site-service
Commits
3765b47f
Commit
3765b47f
authored
Jul 08, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 支付代码搬运、管理端推广码
parent
23ce2663
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
3171 additions
and
4 deletions
+3171
-4
pom.xml
admin/pom.xml
+5
-0
AdminWeixinService.java
...nsiteservice/admin/service/weixin/AdminWeixinService.java
+37
-0
MiniQrCodeDTO.java
...a/com/onsiteservice/common/service/dto/MiniQrCodeDTO.java
+1
-1
SysParamConstants.java
...om/onsiteservice/constant/constant/SysParamConstants.java
+9
-0
application-third-service.yaml
constant/src/main/resources/application-third-service.yaml
+0
-1
PayChannelWechatMapper.java
.../onsiteservice/dao/mapper/pay/PayChannelWechatMapper.java
+7
-0
PayChannelWechatMapper.xml
dao/src/main/resources/mapper/pay/PayChannelWechatMapper.xml
+17
-0
PayChannelWechat.java
...n/java/com/onsiteservice/entity/pay/PayChannelWechat.java
+73
-0
OrderPayVO.java
...onsiteservice/miniapp/controller/order/vo/OrderPayVO.java
+20
-0
WeiXinController.java
...iteservice/miniapp/controller/weixn/WeiXinController.java
+1
-1
WeiXinService.java
...m/onsiteservice/miniapp/service/weixin/WeiXinService.java
+1
-1
WechatNativePay.java
...teservice/miniapp/service/weixin/pay/WechatNativePay.java
+146
-0
IWXPayDomain.java
...rvice/miniapp/service/weixin/pay/config/IWXPayDomain.java
+42
-0
WXPayConfig.java
...ervice/miniapp/service/weixin/pay/config/WXPayConfig.java
+102
-0
WXPayConstants.java
...ice/miniapp/service/weixin/pay/config/WXPayConstants.java
+58
-0
WXPayDomainSimpleImpl.java
...iapp/service/weixin/pay/config/WXPayDomainSimpleImpl.java
+97
-0
WXPayReport.java
...ervice/miniapp/service/weixin/pay/config/WXPayReport.java
+262
-0
WXPayRequest.java
...rvice/miniapp/service/weixin/pay/config/WXPayRequest.java
+256
-0
WechatPayMini.java
...vice/miniapp/service/weixin/pay/config/WechatPayMini.java
+142
-0
WechatPayMyConfigMini.java
...iapp/service/weixin/pay/config/WechatPayMyConfigMini.java
+63
-0
AESUtil.java
...nsiteservice/miniapp/service/weixin/pay/util/AESUtil.java
+40
-0
Base64Util.java
...teservice/miniapp/service/weixin/pay/util/Base64Util.java
+299
-0
ClientCustomSSL.java
...vice/miniapp/service/weixin/pay/util/ClientCustomSSL.java
+90
-0
IPUtil.java
...onsiteservice/miniapp/service/weixin/pay/util/IPUtil.java
+17
-0
MD5Util.java
...nsiteservice/miniapp/service/weixin/pay/util/MD5Util.java
+745
-0
MapKeyComparator.java
...ice/miniapp/service/weixin/pay/util/MapKeyComparator.java
+10
-0
MapUtil.java
...nsiteservice/miniapp/service/weixin/pay/util/MapUtil.java
+103
-0
ParseXmlUtil.java
...service/miniapp/service/weixin/pay/util/ParseXmlUtil.java
+60
-0
UUIDGenerator.java
...ervice/miniapp/service/weixin/pay/util/UUIDGenerator.java
+103
-0
UUIDUtil.java
...siteservice/miniapp/service/weixin/pay/util/UUIDUtil.java
+15
-0
WXPayUtil.java
...iteservice/miniapp/service/weixin/pay/util/WXPayUtil.java
+320
-0
WXPayXmlUtil.java
...service/miniapp/service/weixin/pay/util/WXPayXmlUtil.java
+30
-0
No files found.
admin/pom.xml
View file @
3765b47f
...
@@ -19,6 +19,11 @@
...
@@ -19,6 +19,11 @@
<artifactId>
common
</artifactId>
<artifactId>
common
</artifactId>
<version>
1.0.0
</version>
<version>
1.0.0
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.github.binarywang
</groupId>
<artifactId>
wx-java-miniapp-spring-boot-starter
</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
admin/src/main/java/com/onsiteservice/admin/service/weixin/AdminWeixinService.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
admin
.
service
.
weixin
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor
;
import
com.onsiteservice.common.service.dto.MiniQrCodeDTO
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.core.result.Result
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Service
public
class
AdminWeixinService
{
@Resource
private
WxMaService
wxMaService
;
/**
* 获取推广二维码
*/
public
Result
getQrCode
(
MiniQrCodeDTO
miniQrCodeDTO
)
{
try
{
// 获取base64数据
byte
[]
qrCode
=
wxMaService
.
getQrcodeService
().
createWxaCodeUnlimitBytes
(
miniQrCodeDTO
.
getScene
(),
miniQrCodeDTO
.
getPath
(),
miniQrCodeDTO
.
getWidth
(),
false
,
new
WxMaCodeLineColor
(
"0"
,
"0"
,
"0"
),
false
);
return
success
(
qrCode
,
"获取微信小程序码成功"
);
}
catch
(
Exception
e
)
{
throw
new
ServiceException
(
"获取微信小程序码失败"
);
}
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin
/dto/MiniQrCodeDTO.java
→
common/src/main/java/com/onsiteservice/common/service
/dto/MiniQrCodeDTO.java
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
dto
;
package
com
.
onsiteservice
.
common
.
service
.
dto
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
io.swagger.annotations.ApiModelProperty
;
...
...
constant/src/main/java/com/onsiteservice/constant/constant/SysParamConstants.java
View file @
3765b47f
...
@@ -7,4 +7,13 @@ public class SysParamConstants {
...
@@ -7,4 +7,13 @@ public class SysParamConstants {
/* 默认头像 */
/* 默认头像 */
public
static
final
String
AVATAR_URL
=
""
;
public
static
final
String
AVATAR_URL
=
""
;
/**
* 微信支付回调地址
*/
public
final
static
String
MINI_WECHAT_PAY_NOTIFY_URL
=
"MINI_WECHAT_PAY_NOTIFY_URL"
;
/**
* 微信退款回调地址
*/
public
final
static
String
MINI_WECHAT_REFUND_NOTIFY_URL
=
"MINI_WECHAT_REFUND_NOTIFY_URL"
;
}
}
constant/src/main/resources/application-third-service.yaml
View file @
3765b47f
...
@@ -29,7 +29,6 @@ wx:
...
@@ -29,7 +29,6 @@ wx:
pay
:
pay
:
appId
:
wxa56f0845ca456bac
#微信公众号或者小程序等的appid
appId
:
wxa56f0845ca456bac
#微信公众号或者小程序等的appid
mchId
:
1602411974
#微信支付商户号
mchId
:
1602411974
#微信支付商户号
wechat_key
:
xxxxxxx
# 公众号
# 公众号
###
###
...
...
dao/src/main/java/com/onsiteservice/dao/mapper/pay/PayChannelWechatMapper.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
dao
.
mapper
.
pay
;
import
com.onsiteservice.dao.common.Mapper
;
import
com.onsiteservice.entity.pay.PayChannelWechat
;
public
interface
PayChannelWechatMapper
extends
Mapper
<
PayChannelWechat
>
{
}
\ No newline at end of file
dao/src/main/resources/mapper/pay/PayChannelWechatMapper.xml
0 → 100644
View file @
3765b47f
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.onsiteservice.dao.mapper.pay.PayChannelWechatMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.onsiteservice.entity.pay.PayChannelWechat"
>
<!--
WARNING - @mbg.generated
-->
<id
column=
"id"
jdbcType=
"BIGINT"
property=
"id"
/>
<result
column=
"merchant_name"
jdbcType=
"VARCHAR"
property=
"merchantName"
/>
<result
column=
"appid"
jdbcType=
"VARCHAR"
property=
"appid"
/>
<result
column=
"mchid"
jdbcType=
"VARCHAR"
property=
"mchid"
/>
<result
column=
"remark"
jdbcType=
"VARCHAR"
property=
"remark"
/>
<result
column=
"create_time"
jdbcType=
"TIMESTAMP"
property=
"createTime"
/>
<result
column=
"wechat_key"
jdbcType=
"LONGVARCHAR"
property=
"wechatKey"
/>
<result
column=
"refund_cert"
jdbcType=
"LONGVARBINARY"
property=
"refundCert"
/>
</resultMap>
</mapper>
\ No newline at end of file
entity/src/main/java/com/onsiteservice/entity/pay/PayChannelWechat.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
entity
.
pay
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.util.Date
;
import
javax.persistence.*
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
@Getter
@Setter
@ToString
@ApiModel
(
"微信支付商户表"
)
@Table
(
name
=
"pay_channel_wechat"
)
public
class
PayChannelWechat
implements
Serializable
{
/**
* 主键
*/
@Id
@GeneratedValue
(
strategy
=
GenerationType
.
IDENTITY
)
@ApiModelProperty
(
"主键"
)
private
Long
id
;
/**
* 商户名称
*/
@Column
(
name
=
"merchant_name"
)
@ApiModelProperty
(
"商户名称"
)
private
String
merchantName
;
/**
* appid
*/
@ApiModelProperty
(
"appid"
)
private
String
appid
;
/**
* 商户id
*/
@ApiModelProperty
(
"商户id"
)
private
String
mchid
;
/**
* 备注
*/
@ApiModelProperty
(
"备注"
)
private
String
remark
;
/**
* 创建时间
*/
@Column
(
name
=
"create_time"
)
@ApiModelProperty
(
"创建时间"
)
private
Date
createTime
;
/**
* 秘钥
*/
@Column
(
name
=
"wechat_key"
)
@ApiModelProperty
(
"秘钥"
)
private
String
wechatKey
;
/**
* 退款证书
*/
@Column
(
name
=
"refund_cert"
)
@ApiModelProperty
(
"退款证书"
)
private
byte
[]
refundCert
;
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
mini-app/src/main/java/com/onsiteservice/miniapp/controller/order/vo/OrderPayVO.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
controller
.
order
.
vo
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.ToString
;
import
java.util.Map
;
@Getter
@Setter
@ToString
@ApiModel
(
description
=
"订单支付参数"
)
public
class
OrderPayVO
{
@ApiModelProperty
(
"支付参数(key:appId,timeStamp,nonceStr,package,signType,paySign)"
)
private
Map
<
String
,
String
>
payParam
;
}
mini-app/src/main/java/com/onsiteservice/miniapp/controller/weixn/WeiXinController.java
View file @
3765b47f
...
@@ -4,11 +4,11 @@ package com.onsiteservice.miniapp.controller.weixn;
...
@@ -4,11 +4,11 @@ package com.onsiteservice.miniapp.controller.weixn;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
com.github.xiaoymin.knife4j.annotations.ApiSupport
;
import
com.github.xiaoymin.knife4j.annotations.ApiSupport
;
import
com.onsiteservice.common.annotation.user.CurrentUserId
;
import
com.onsiteservice.common.annotation.user.CurrentUserId
;
import
com.onsiteservice.common.service.dto.MiniQrCodeDTO
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.service.weixin.WeiXinService
;
import
com.onsiteservice.miniapp.service.weixin.WeiXinService
;
import
com.onsiteservice.miniapp.service.weixin.dto.MiniQrCodeDTO
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.NonNull
;
import
lombok.NonNull
;
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/WeiXinService.java
View file @
3765b47f
...
@@ -6,6 +6,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
...
@@ -6,6 +6,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import
cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo
;
import
cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo
;
import
cn.binarywang.wx.miniapp.bean.WxMaUserInfo
;
import
cn.binarywang.wx.miniapp.bean.WxMaUserInfo
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.ImmutableMap
;
import
com.onsiteservice.common.service.dto.MiniQrCodeDTO
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
import
com.onsiteservice.core.security.jwt.JwtManager
;
...
@@ -13,7 +14,6 @@ import com.onsiteservice.entity.user.User;
...
@@ -13,7 +14,6 @@ import com.onsiteservice.entity.user.User;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.LoginDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.controller.weixn.dto.WxEncryptDTO
;
import
com.onsiteservice.miniapp.service.user.UserService
;
import
com.onsiteservice.miniapp.service.user.UserService
;
import
com.onsiteservice.miniapp.service.weixin.dto.MiniQrCodeDTO
;
import
io.micrometer.core.instrument.util.StringUtils
;
import
io.micrometer.core.instrument.util.StringUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
me.chanjar.weixin.common.error.WxErrorException
;
import
me.chanjar.weixin.common.error.WxErrorException
;
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/WechatNativePay.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.miniapp.service.weixin.pay.config.*
;
import
com.onsiteservice.miniapp.service.weixin.pay.util.*
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.ByteArrayInputStream
;
import
java.math.BigDecimal
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author: qiaobin
* @description:微信网页扫码支付
* @date: 2019/1/22
*/
public
class
WechatNativePay
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
WechatNativePay
.
class
);
WechatPayMyConfigMini
configMini
;
WechatPayMini
wxpayMini
;
public
WechatNativePay
(
String
appID
,
String
mchID
,
String
key
)
{
configMini
=
new
WechatPayMyConfigMini
(
appID
,
mchID
,
key
);
wxpayMini
=
new
WechatPayMini
(
configMini
);
}
public
Map
<
String
,
String
>
getPayParam
(
String
body
,
String
out_trade_no
,
BigDecimal
total_fee
,
String
notifyUrl
,
String
openId
,
HttpServletRequest
request
)
throws
Exception
{
//微信支付
HashMap
<
String
,
String
>
payParam
=
new
HashMap
<>();
String
timestamp
=
String
.
valueOf
(
System
.
currentTimeMillis
()
/
1000
);
String
prepayId
=
getPrepayId
(
body
,
out_trade_no
,
total_fee
,
notifyUrl
,
openId
,
request
);
payParam
.
put
(
"appId"
,
configMini
.
getAppID
());
payParam
.
put
(
"timeStamp"
,
timestamp
);
payParam
.
put
(
"nonceStr"
,
UUIDGenerator
.
generate
());
payParam
.
put
(
"package"
,
"prepay_id="
+
prepayId
);
payParam
.
put
(
"signType"
,
"MD5"
);
String
paySign
=
WXPayUtil
.
generateSignature
(
payParam
,
configMini
.
getKey
());
payParam
.
put
(
"paySign"
,
paySign
);
return
payParam
;
}
/**
* 生成预支付交易单
*
* @param body 商品或支付单简要描述 32个字符
* @param out_trade_no 商户系统内部的订单号,32个字符内
* @param total_fee 支付金额单位为【分】
* @param notifyUrl
* @param request
* @return
* @throws Exception
*/
public
String
getPrepayId
(
String
body
,
String
out_trade_no
,
BigDecimal
total_fee
,
String
notifyUrl
,
String
openId
,
HttpServletRequest
request
)
throws
Exception
{
logger
.
info
(
"===getPrepayId 参数====="
+
body
+
"|"
+
out_trade_no
+
"|"
+
total_fee
.
toString
()
+
"|"
+
notifyUrl
+
"|"
+
openId
);
String
prepayId
=
""
;
total_fee
=
total_fee
.
multiply
(
new
BigDecimal
(
100
));
//微信支付金额需要乘以100
Map
<
String
,
String
>
data
=
new
HashMap
<
String
,
String
>();
data
.
put
(
"body"
,
body
);
data
.
put
(
"appid"
,
configMini
.
getAppID
());
data
.
put
(
"mch_id"
,
configMini
.
getMchID
());
data
.
put
(
"out_trade_no"
,
out_trade_no
);
data
.
put
(
"fee_type"
,
"CNY"
);
data
.
put
(
"openid"
,
openId
);
data
.
put
(
"total_fee"
,
String
.
valueOf
(
total_fee
.
intValue
()));
data
.
put
(
"spbill_create_ip"
,
IPUtil
.
getIpAddress
(
request
));
data
.
put
(
"notify_url"
,
notifyUrl
);
data
.
put
(
"trade_type"
,
"JSAPI"
);
// 此处指定为小程序支付
data
.
put
(
"nonce_str"
,
UUIDGenerator
.
generate
());
String
s
=
MapUtil
.
FormatBizQueryParaMap
(
data
,
false
);
String
buildSign
=
s
+
"&key="
+
configMini
.
getKey
();
String
sign
=
MD5Util
.
MD5
(
buildSign
).
toUpperCase
();
data
.
put
(
"sign"
,
sign
);
Map
<
String
,
String
>
respXml
=
wxpayMini
.
unifiedOrder
(
data
);
logger
.
info
(
"===获取预支付id,返回xml数据====="
+
respXml
);
String
returnCode
=
respXml
.
get
(
"return_code"
);
String
resultCode
=
respXml
.
get
(
"result_code"
);
if
(
"SUCCESS"
.
equals
(
resultCode
)
&&
"SUCCESS"
.
equals
(
returnCode
))
{
prepayId
=
respXml
.
get
(
"prepay_id"
);
}
else
{
throw
new
RuntimeException
(
"生成预支付id时未成功."
);
}
return
prepayId
;
}
/**
* 生成退款交易单
*
* @param out_trade_no 商户系统内部的订单号,32个字符内
* @param out_refund_no 商户系统内部的退款订单号,32个字符内
* @param total_fee 支付金额单位为【分】
* @return
* @throws Exception
*/
public
String
doRefundMini
(
String
out_trade_no
,
String
out_refund_no
,
BigDecimal
total_fee
,
BigDecimal
refund_fee
,
String
refundNotifyUrl
,
byte
[]
certData
)
throws
Exception
{
String
appId
=
configMini
.
getAppID
();
String
mchId
=
configMini
.
getMchID
();
String
wechatKey
=
configMini
.
getKey
();
String
resultCode
=
""
;
HashMap
<
String
,
String
>
prepayMap
=
new
HashMap
<>();
prepayMap
.
put
(
"appid"
,
appId
);
prepayMap
.
put
(
"nonce_str"
,
UUIDUtil
.
createUUID
());
prepayMap
.
put
(
"mch_id"
,
mchId
);
prepayMap
.
put
(
"notify_url"
,
refundNotifyUrl
);
prepayMap
.
put
(
"out_trade_no"
,
out_trade_no
);
prepayMap
.
put
(
"out_refund_no"
,
out_refund_no
);
total_fee
=
total_fee
.
multiply
(
new
BigDecimal
(
100
));
//重要,微信支付金额是分,前端传来是支付金额单位是元,必须扩大100倍
refund_fee
=
refund_fee
.
multiply
(
new
BigDecimal
(
100
));
//重要,微信支付金额是分,前端传来是支付金额单位是元,必须扩大100倍
prepayMap
.
put
(
"total_fee"
,
String
.
valueOf
(
total_fee
.
intValue
()));
prepayMap
.
put
(
"refund_fee"
,
String
.
valueOf
(
refund_fee
.
intValue
()));
String
s
=
MapUtil
.
FormatBizQueryParaMap
(
prepayMap
,
false
);
String
buildSign
=
s
+
"&key="
+
wechatKey
;
String
sign
=
MD5Util
.
MD5
(
buildSign
).
toUpperCase
();
prepayMap
.
put
(
"sign"
,
sign
);
logger
.
info
(
"===发起退款操作,参数=====appId"
+
appId
);
logger
.
info
(
"===发起退款操作,参数=====nonce_str"
+
prepayMap
.
get
(
"nonce_str"
));
logger
.
info
(
"===发起退款操作,参数=====mch_id"
+
prepayMap
.
get
(
"mch_id"
));
logger
.
info
(
"===发起退款操作,参数=====notify_url"
+
prepayMap
.
get
(
"notify_url"
));
logger
.
info
(
"===发起退款操作,参数=====out_trade_no"
+
prepayMap
.
get
(
"out_trade_no"
));
logger
.
info
(
"===发起退款操作,参数=====out_refund_no"
+
prepayMap
.
get
(
"out_refund_no"
));
logger
.
info
(
"===发起退款操作,参数=====total_fee"
+
prepayMap
.
get
(
"total_fee"
));
logger
.
info
(
"===发起退款操作,参数=====refund_fee"
+
prepayMap
.
get
(
"refund_fee"
));
logger
.
info
(
"===发起退款操作,参数=====sign"
+
prepayMap
.
get
(
"sign"
));
String
sendXml
=
MapUtil
.
ArrayToXml
(
prepayMap
);
try
{
String
returnXml
=
ClientCustomSSL
.
doRefund
(
new
ByteArrayInputStream
(
certData
),
WXPayConstants
.
WXREFUND_URL
,
sendXml
,
mchId
);
logger
.
info
(
"===发起退款操作,返回xml数据====="
+
returnXml
);
String
returnCode
=
ParseXmlUtil
.
parseXml2KeyValue
(
returnXml
,
"return_code"
);
resultCode
=
ParseXmlUtil
.
parseXml2KeyValue
(
returnXml
,
"result_code"
);
if
(!
"SUCCESS"
.
equals
(
resultCode
)
||
!
"SUCCESS"
.
equals
(
returnCode
))
{
throw
new
ServiceException
(
"生成退款交易单时未成功."
);
}
}
catch
(
Throwable
e
)
{
e
.
printStackTrace
();
logger
.
info
(
"=====发起退款异常===="
+
e
.
getMessage
());
throw
new
ServiceException
(
e
.
getMessage
());
}
return
resultCode
;
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/IWXPayDomain.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
/**
* 域名管理,实现主备域名自动切换
*/
public
abstract
interface
IWXPayDomain
{
/**
* 上报域名网络状况
* @param domain 域名。 比如:api.mch.weixin.qq.com
* @param elapsedTimeMillis 耗时
* @param ex 网络请求中出现的异常。
* null表示没有异常
* ConnectTimeoutException,表示建立网络连接异常
* UnknownHostException, 表示dns解析异常
*/
abstract
void
report
(
final
String
domain
,
long
elapsedTimeMillis
,
final
Exception
ex
);
/**
* 获取域名
* @param config 配置
* @return 域名
*/
abstract
DomainInfo
getDomain
(
final
WXPayConfig
config
);
static
class
DomainInfo
{
public
String
domain
;
//域名
public
boolean
primaryDomain
;
//该域名是否为主域名。例如:api.mch.weixin.qq.com为主域名
public
DomainInfo
(
String
domain
,
boolean
primaryDomain
)
{
this
.
domain
=
domain
;
this
.
primaryDomain
=
primaryDomain
;
}
@Override
public
String
toString
()
{
return
"DomainInfo{"
+
"domain='"
+
domain
+
'\''
+
", primaryDomain="
+
primaryDomain
+
'}'
;
}
}
}
\ No newline at end of file
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WXPayConfig.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
import
java.io.InputStream
;
public
abstract
class
WXPayConfig
{
/**
* 获取 App ID
*
* @return App ID
*/
public
abstract
String
getAppID
();
/**
* 获取 Mch ID
*
* @return Mch ID
*/
abstract
String
getMchID
();
/**
* 获取 API 密钥
*
* @return API密钥
*/
abstract
String
getKey
();
/**
* 获取商户证书内容
*
* @return 商户证书内容
*/
abstract
InputStream
getCertStream
();
/**
* HTTP(S) 连接超时时间,单位毫秒
*
* @return
*/
public
int
getHttpConnectTimeoutMs
()
{
return
6
*
1000
;
}
/**
* HTTP(S) 读数据超时时间,单位毫秒
*
* @return
*/
public
int
getHttpReadTimeoutMs
()
{
return
8
*
1000
;
}
/**
* 获取WXPayDomain, 用于多域名容灾自动切换
* @return
*/
abstract
IWXPayDomain
getWXPayDomain
();
/**
* 是否自动上报。
* 若要关闭自动上报,子类中实现该函数返回 false 即可。
*
* @return
*/
public
boolean
shouldAutoReport
()
{
return
true
;
}
/**
* 进行健康上报的线程的数量
*
* @return
*/
public
int
getReportWorkerNum
()
{
return
6
;
}
/**
* 健康上报缓存消息的最大数量。会有线程去独立上报
* 粗略计算:加入一条消息200B,10000消息占用空间 2000 KB,约为2MB,可以接受
*
* @return
*/
public
int
getReportQueueMaxSize
()
{
return
10000
;
}
/**
* 批量上报,一次最多上报多个数据
*
* @return
*/
public
int
getReportBatchSize
()
{
return
10
;
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WXPayConstants.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
import
org.apache.http.client.HttpClient
;
/**
* 常量
*/
public
class
WXPayConstants
{
public
static
final
String
DOMAIN_API
=
"api.mch.weixin.qq.com"
;
public
static
final
String
DOMAIN_API2
=
"api2.mch.weixin.qq.com"
;
public
static
final
String
DOMAIN_APIHK
=
"apihk.mch.weixin.qq.com"
;
public
static
final
String
DOMAIN_APIUS
=
"apius.mch.weixin.qq.com"
;
public
static
final
String
FAIL
=
"FAIL"
;
public
static
final
String
SUCCESS
=
"SUCCESS"
;
public
static
final
String
HMACSHA256
=
"HMAC-SHA256"
;
public
static
final
String
MD5
=
"MD5"
;
public
static
final
String
FIELD_SIGN
=
"sign"
;
public
static
final
String
FIELD_SIGN_TYPE
=
"sign_type"
;
public
static
final
String
WXPAYSDK_VERSION
=
"WXPaySDK/3.0.9"
;
public
static
final
String
USER_AGENT
=
WXPAYSDK_VERSION
+
" ("
+
System
.
getProperty
(
"os.arch"
)
+
" "
+
System
.
getProperty
(
"os.name"
)
+
" "
+
System
.
getProperty
(
"os.version"
)
+
") Java/"
+
System
.
getProperty
(
"java.version"
)
+
" HttpClient/"
+
HttpClient
.
class
.
getPackage
().
getImplementationVersion
();
public
static
final
String
MICROPAY_URL_SUFFIX
=
"/pay/micropay"
;
public
static
final
String
UNIFIEDORDER_URL_SUFFIX
=
"/pay/unifiedorder"
;
public
static
final
String
ORDERQUERY_URL_SUFFIX
=
"/pay/orderquery"
;
public
static
final
String
REVERSE_URL_SUFFIX
=
"/secapi/pay/reverse"
;
public
static
final
String
CLOSEORDER_URL_SUFFIX
=
"/pay/closeorder"
;
public
static
final
String
REFUND_URL_SUFFIX
=
"/secapi/pay/refund"
;
public
static
final
String
REFUNDQUERY_URL_SUFFIX
=
"/pay/refundquery"
;
public
static
final
String
DOWNLOADBILL_URL_SUFFIX
=
"/pay/downloadbill"
;
public
static
final
String
REPORT_URL_SUFFIX
=
"/payitil/report"
;
public
static
final
String
SHORTURL_URL_SUFFIX
=
"/tools/shorturl"
;
public
static
final
String
AUTHCODETOOPENID_URL_SUFFIX
=
"/tools/authcodetoopenid"
;
/**
* 退款接口链接
*/
public
static
final
String
WXREFUND_URL
=
"https://api.mch.weixin.qq.com/secapi/pay/refund"
;
/**
* 支付通知
*/
public
static
final
String
NOTIFY_URL
=
"http://39.96.19.25:8091/wechat/notify"
;
/**
* 退款通知
*/
public
static
final
String
REFUND_NOTIFY_URL
=
"http://39.96.19.25:8091/wechat/refundNotify"
;
/**
* 退款证书路径
*/
// public static final String WX_CERT_PATH = "D:\\cert\\antaitiyu\\apiclient_cert.p12";
public
static
final
String
WX_CERT_PATH
=
"/usr/deploy/cert/wechat/apiclient_cert.p12"
;
public
enum
SignType
{
MD5
,
HMACSHA256
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WXPayDomainSimpleImpl.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
import
org.apache.http.conn.ConnectTimeoutException
;
import
java.net.UnknownHostException
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
WXPayDomainSimpleImpl
implements
IWXPayDomain
{
private
final
int
MIN_SWITCH_PRIMARY_MSEC
=
3
*
60
*
1000
;
//3 minutes
private
long
switchToAlternateDomainTime
=
0
;
private
Map
<
String
,
DomainStatics
>
domainData
=
new
HashMap
<
String
,
DomainStatics
>();
private
WXPayDomainSimpleImpl
(){}
public
static
IWXPayDomain
instance
(){
return
WxpayDomainHolder
.
holder
;
}
public
synchronized
void
report
(
final
String
domain
,
long
elapsedTimeMillis
,
final
Exception
ex
)
{
DomainStatics
info
=
domainData
.
get
(
domain
);
if
(
info
==
null
){
info
=
new
DomainStatics
(
domain
);
domainData
.
put
(
domain
,
info
);
}
if
(
ex
==
null
){
//success
if
(
info
.
succCount
>=
2
){
//continue succ, clear error count
info
.
connectTimeoutCount
=
info
.
dnsErrorCount
=
info
.
otherErrorCount
=
0
;
}
else
{
++
info
.
succCount
;
}
}
else
if
(
ex
instanceof
ConnectTimeoutException
){
info
.
succCount
=
info
.
dnsErrorCount
=
0
;
++
info
.
connectTimeoutCount
;
}
else
if
(
ex
instanceof
UnknownHostException
){
info
.
succCount
=
0
;
++
info
.
dnsErrorCount
;
}
else
{
info
.
succCount
=
0
;
++
info
.
otherErrorCount
;
}
}
public
synchronized
DomainInfo
getDomain
(
final
WXPayConfig
config
)
{
DomainStatics
primaryDomain
=
domainData
.
get
(
WXPayConstants
.
DOMAIN_API
);
if
(
primaryDomain
==
null
||
primaryDomain
.
isGood
())
{
return
new
DomainInfo
(
WXPayConstants
.
DOMAIN_API
,
true
);
}
long
now
=
System
.
currentTimeMillis
();
if
(
switchToAlternateDomainTime
==
0
){
//first switch
switchToAlternateDomainTime
=
now
;
return
new
DomainInfo
(
WXPayConstants
.
DOMAIN_API2
,
false
);
}
else
if
(
now
-
switchToAlternateDomainTime
<
MIN_SWITCH_PRIMARY_MSEC
){
DomainStatics
alternateDomain
=
domainData
.
get
(
WXPayConstants
.
DOMAIN_API2
);
if
(
alternateDomain
==
null
||
alternateDomain
.
isGood
()
||
alternateDomain
.
badCount
()
<
primaryDomain
.
badCount
()){
return
new
DomainInfo
(
WXPayConstants
.
DOMAIN_API2
,
false
);
}
else
{
return
new
DomainInfo
(
WXPayConstants
.
DOMAIN_API
,
true
);
}
}
else
{
//force switch back
switchToAlternateDomainTime
=
0
;
primaryDomain
.
resetCount
();
DomainStatics
alternateDomain
=
domainData
.
get
(
WXPayConstants
.
DOMAIN_API2
);
if
(
alternateDomain
!=
null
)
alternateDomain
.
resetCount
();
return
new
DomainInfo
(
WXPayConstants
.
DOMAIN_API
,
true
);
}
}
private
static
class
WxpayDomainHolder
{
private
static
IWXPayDomain
holder
=
new
WXPayDomainSimpleImpl
();
}
static
class
DomainStatics
{
final
String
domain
;
int
succCount
=
0
;
int
connectTimeoutCount
=
0
;
int
dnsErrorCount
=
0
;
int
otherErrorCount
=
0
;
DomainStatics
(
String
domain
)
{
this
.
domain
=
domain
;
}
void
resetCount
(){
succCount
=
connectTimeoutCount
=
dnsErrorCount
=
otherErrorCount
=
0
;
}
boolean
isGood
(){
return
connectTimeoutCount
<=
2
&&
dnsErrorCount
<=
2
;
}
int
badCount
(){
return
connectTimeoutCount
+
dnsErrorCount
*
5
+
otherErrorCount
/
4
;
}
}
}
\ No newline at end of file
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WXPayReport.java
0 → 100644
View file @
3765b47f
This diff is collapsed.
Click to expand it.
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WXPayRequest.java
0 → 100644
View file @
3765b47f
This diff is collapsed.
Click to expand it.
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WechatPayMini.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
import
com.onsiteservice.miniapp.service.weixin.pay.util.WXPayUtil
;
import
java.util.Map
;
public
class
WechatPayMini
{
private
WXPayConstants
.
SignType
signType
=
WXPayConstants
.
SignType
.
MD5
;
private
boolean
autoReport
;
private
WXPayConfig
config
;
private
WXPayRequest
wxPayRequest
;
public
WechatPayMini
(){}
public
WechatPayMini
(
final
WXPayConfig
config
){
this
.
config
=
config
;
this
.
wxPayRequest
=
new
WXPayRequest
(
config
);
}
/**
* 作用:统一下单<br>
* 场景:公共号支付、扫码支付、APP支付
* @param reqData 向wxpay post的请求数据
* @return API返回数据
* @throws Exception
*/
public
Map
<
String
,
String
>
unifiedOrder
(
Map
<
String
,
String
>
reqData
)
throws
Exception
{
return
this
.
unifiedOrder
(
reqData
,
config
.
getHttpConnectTimeoutMs
(),
this
.
config
.
getHttpReadTimeoutMs
());
}
/**
* 作用:统一下单<br>
* 场景:公共号支付、扫码支付、APP支付
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 连接超时时间,单位是毫秒
* @param readTimeoutMs 读超时时间,单位是毫秒
* @return API返回数据
* @throws Exception
*/
public
Map
<
String
,
String
>
unifiedOrder
(
Map
<
String
,
String
>
reqData
,
int
connectTimeoutMs
,
int
readTimeoutMs
)
throws
Exception
{
String
url
=
WXPayConstants
.
UNIFIEDORDER_URL_SUFFIX
;
String
respXml
=
this
.
requestWithoutCert
(
url
,
this
.
fillRequestData
(
reqData
),
connectTimeoutMs
,
readTimeoutMs
);
return
this
.
processResponseXml
(
respXml
);
}
/**
* 不需要证书的请求
* @param urlSuffix String
* @param reqData 向wxpay post的请求数据
* @param connectTimeoutMs 超时时间,单位是毫秒
* @param readTimeoutMs 超时时间,单位是毫秒
* @return API返回数据
* @throws Exception
*/
public
String
requestWithoutCert
(
String
urlSuffix
,
Map
<
String
,
String
>
reqData
,
int
connectTimeoutMs
,
int
readTimeoutMs
)
throws
Exception
{
String
msgUUID
=
reqData
.
get
(
"nonce_str"
);
String
reqBody
=
WXPayUtil
.
mapToXml
(
reqData
);
String
resp
=
this
.
wxPayRequest
.
requestWithoutCert
(
urlSuffix
,
msgUUID
,
reqBody
,
connectTimeoutMs
,
readTimeoutMs
,
autoReport
);
return
resp
;
}
/**
* 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign <br>
* 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口
*
* @param reqData
* @return
* @throws Exception
*/
public
Map
<
String
,
String
>
fillRequestData
(
Map
<
String
,
String
>
reqData
)
throws
Exception
{
reqData
.
put
(
"appid"
,
config
.
getAppID
());
reqData
.
put
(
"mch_id"
,
config
.
getMchID
());
reqData
.
put
(
"nonce_str"
,
WXPayUtil
.
generateNonceStr
());
if
(
WXPayConstants
.
SignType
.
MD5
.
equals
(
this
.
signType
))
{
reqData
.
put
(
"sign_type"
,
WXPayConstants
.
MD5
);
}
else
if
(
WXPayConstants
.
SignType
.
HMACSHA256
.
equals
(
this
.
signType
))
{
reqData
.
put
(
"sign_type"
,
WXPayConstants
.
HMACSHA256
);
}
reqData
.
put
(
"sign"
,
WXPayUtil
.
generateSignature
(
reqData
,
config
.
getKey
(),
this
.
signType
));
return
reqData
;
}
/**
* 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。
* @param xmlStr API返回的XML格式数据
* @return Map类型数据
* @throws Exception
*/
public
Map
<
String
,
String
>
processResponseXml
(
String
xmlStr
)
throws
Exception
{
String
RETURN_CODE
=
"return_code"
;
String
return_code
;
Map
<
String
,
String
>
respData
=
WXPayUtil
.
xmlToMap
(
xmlStr
);
if
(
respData
.
containsKey
(
RETURN_CODE
))
{
return_code
=
respData
.
get
(
RETURN_CODE
);
}
else
{
throw
new
RuntimeException
(
String
.
format
(
"No `return_code` in XML: %s"
,
xmlStr
));
}
if
(
return_code
.
equals
(
WXPayConstants
.
FAIL
))
{
return
respData
;
}
else
if
(
return_code
.
equals
(
WXPayConstants
.
SUCCESS
))
{
if
(
this
.
isResponseSignatureValid
(
respData
))
{
return
respData
;
}
else
{
throw
new
RuntimeException
(
String
.
format
(
"Invalid sign value in XML: %s"
,
xmlStr
));
}
}
else
{
throw
new
RuntimeException
(
String
.
format
(
"return_code value %s is invalid in XML: %s"
,
return_code
,
xmlStr
));
}
}
/**
* 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。
*
* @param reqData 向wxpay post的请求数据
* @return 签名是否有效
* @throws Exception
*/
public
boolean
isResponseSignatureValid
(
Map
<
String
,
String
>
reqData
)
throws
Exception
{
// 返回数据的签名方式和请求中给定的签名方式是一致的
return
WXPayUtil
.
isSignatureValid
(
reqData
,
this
.
config
.
getKey
(),
this
.
signType
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/config/WechatPayMyConfigMini.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
config
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
/**
* @author: qiaobin
* @description:
* @date: 2019/1/22
*/
public
class
WechatPayMyConfigMini
extends
WXPayConfig
{
private
String
appID
;
private
String
mchID
;
private
String
key
;
public
WechatPayMyConfigMini
(
String
appID
,
String
mchID
,
String
key
)
{
this
.
appID
=
appID
;
this
.
mchID
=
mchID
;
this
.
key
=
key
;
}
private
byte
[]
certData
;
public
String
getAppID
()
{
return
this
.
appID
;
}
public
String
getMchID
()
{
return
this
.
mchID
;
}
public
String
getKey
()
{
return
this
.
key
;
}
public
InputStream
getCertStream
()
{
ByteArrayInputStream
certBis
=
new
ByteArrayInputStream
(
this
.
certData
);
return
certBis
;
}
public
int
getHttpConnectTimeoutMs
()
{
return
8000
;
}
public
int
getHttpReadTimeoutMs
()
{
return
10000
;
}
@Override
public
IWXPayDomain
getWXPayDomain
()
{
return
WXPayDomainSimpleImpl
.
instance
();
}
public
String
getPrimaryDomain
()
{
return
"api.mch.weixin.qq.com"
;
}
public
String
getAlternateDomain
()
{
return
"api2.mch.weixin.qq.com"
;
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/AESUtil.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
javax.crypto.Cipher
;
import
javax.crypto.spec.SecretKeySpec
;
public
class
AESUtil
{
/**
* 密钥算法
*/
private
static
final
String
ALGORITHM
=
"AES"
;
/**
* 加解密算法/工作模式/填充方式
*/
private
static
final
String
ALGORITHM_MODE_PADDING
=
"AES/ECB/PKCS5Padding"
;
/**
* AES解密
*
* @param base64Data
* @return
* @throws Exception
*/
public
static
String
decryptData
(
String
base64Data
,
String
wechatKey
)
throws
Exception
{
SecretKeySpec
key
=
new
SecretKeySpec
(
MD5Util
.
MD5Encode
(
wechatKey
,
"UTF-8"
).
toLowerCase
().
getBytes
(),
ALGORITHM
);
Cipher
cipher
=
Cipher
.
getInstance
(
ALGORITHM_MODE_PADDING
);
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
);
return
new
String
(
cipher
.
doFinal
(
Base64Util
.
decode
(
base64Data
)));
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
wechatKey
=
"9005f5ab73de0c2e10466b5459c966e7"
;
String
A
=
"o66B2HUv0rQYII6BZv2Is7Zyo7WabgeAOZbqXwzp9iBC6dfY/VKDsffUo0Wt9Q4po6U5C7blttp7dW4Z3Ya7TJn477ZOyc5QltTgh2F5uv4R/bHocFofPvtGC6tTPY9+SJaEljqgcv3m0ZgAsuNPuDDyy/jlzgSvG67B8MKE3mrnFU/V+IYPTp9jHOHjy2wHOMaFR3u8elAhgThW9MSkboJ4BmTFmdP1qnsLaQ5uv5g5GF8DyUbn+XbzEtMyGzWLqDJCbH4aTCoWbwbWemyzZVH+ngQkuBUmRXwHUzIM/N3QHuiMvH4976/xpqH/CPnCdph6BxEZj2CHLQnVwSxhvQagORtrZVKzBVr1gd1XDarr6gXMv3u4RxoX6IHkZEQmrEvetx9Huzm4DkKgdXzwR3Uu3w+LddUGJssoHHA25V0dHo/K8assCfVnoX/BX5K+YCfkcIlKAV87OnfVrIlYUwNptDCg1Und84ObF4e8ApbBYfx9hPPgaApi7sgmkWWOWZdA6AnhL2C6i/2Ndryv+kV2PrDODi/8cstnmhTcYdN3j/Kt000iQbCX/sNukEixAXE1Wre490glsRFQFVEdNVINxFfYIbIh9CbJ02oO2xWqq58/oQA/rYmTko2nzOn5I7I4mJxyWadEiPfymdMze418HD77o3uSF5aG8xzmsA+63wMkPWRlnika5mD9r0PGK3fPY7sLBnbAgd5dppNj56pVhNs+ekjEeIvjJuP0bV3lJvGR+vnNu6BeFeI0Qmoy3cGUOxxcc2bMn2pYX+TJlqqN4O1BzDXIlrvcabniIf0NDVw5K0mN/Mfpmeij2h70yPVofp5iLnBEFHmY7HNKIbdChUK7ydDo5FDcqQGhRA+IE+A0atJVOoq2p5/UOhBJawbMg2vxKFKrQpKiAVbpbKqCFgdb+TCTdNFqZ0zRQ4tz53BomETs8HYaTebDPfbNXV+O/cU8Es5DbjFVW6zOjD9mE2iYygdDyeex5HSfgXpoJdWiOd5c2d5YbAOaN1zZmEFRq6DatOM2S6Zl5mJTvsiaRVr/UgJrZD4pDDPas7E="
;
String
B
=
AESUtil
.
decryptData
(
A
,
wechatKey
);
System
.
out
.
println
(
B
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/Base64Util.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.Writer
;
public
class
Base64Util
{
private
static
final
char
S_BASE64CHAR
[]
=
{
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'+'
,
'/'
};
private
static
final
byte
S_DECODETABLE
[];
static
{
S_DECODETABLE
=
new
byte
[
128
];
for
(
int
i
=
0
;
i
<
S_DECODETABLE
.
length
;
i
++)
S_DECODETABLE
[
i
]
=
127
;
for
(
int
i
=
0
;
i
<
S_BASE64CHAR
.
length
;
i
++)
S_DECODETABLE
[
S_BASE64CHAR
[
i
]]
=
(
byte
)
i
;
}
/**
* @param ibuf
* @param obuf
* @param wp
* @return
*/
private
static
int
decode0
(
char
ibuf
[],
byte
obuf
[],
int
wp
)
{
int
outlen
=
3
;
if
(
ibuf
[
3
]
==
'='
)
outlen
=
2
;
if
(
ibuf
[
2
]
==
'='
)
outlen
=
1
;
int
b0
=
S_DECODETABLE
[
ibuf
[
0
]];
int
b1
=
S_DECODETABLE
[
ibuf
[
1
]];
int
b2
=
S_DECODETABLE
[
ibuf
[
2
]];
int
b3
=
S_DECODETABLE
[
ibuf
[
3
]];
switch
(
outlen
)
{
case
1
:
// '\001'
obuf
[
wp
]
=
(
byte
)
(
b0
<<
2
&
252
|
b1
>>
4
&
3
);
return
1
;
case
2
:
// '\002'
obuf
[
wp
++]
=
(
byte
)
(
b0
<<
2
&
252
|
b1
>>
4
&
3
);
obuf
[
wp
]
=
(
byte
)
(
b1
<<
4
&
240
|
b2
>>
2
&
15
);
return
2
;
case
3
:
// '\003'
obuf
[
wp
++]
=
(
byte
)
(
b0
<<
2
&
252
|
b1
>>
4
&
3
);
obuf
[
wp
++]
=
(
byte
)
(
b1
<<
4
&
240
|
b2
>>
2
&
15
);
obuf
[
wp
]
=
(
byte
)
(
b2
<<
6
&
192
|
b3
&
63
);
return
3
;
}
throw
new
RuntimeException
(
"Internal error"
);
}
/**
* @param data
* @param off
* @param len
* @return
*/
public
static
byte
[]
decode
(
char
data
[],
int
off
,
int
len
)
{
char
ibuf
[]
=
new
char
[
4
];
int
ibufcount
=
0
;
byte
obuf
[]
=
new
byte
[(
len
/
4
)
*
3
+
3
];
int
obufcount
=
0
;
for
(
int
i
=
off
;
i
<
off
+
len
;
i
++)
{
char
ch
=
data
[
i
];
if
(
ch
!=
'='
&&
(
ch
>=
S_DECODETABLE
.
length
||
S_DECODETABLE
[
ch
]
==
127
))
continue
;
ibuf
[
ibufcount
++]
=
ch
;
if
(
ibufcount
==
ibuf
.
length
)
{
ibufcount
=
0
;
obufcount
+=
decode0
(
ibuf
,
obuf
,
obufcount
);
}
}
if
(
obufcount
==
obuf
.
length
)
{
return
obuf
;
}
else
{
byte
ret
[]
=
new
byte
[
obufcount
];
System
.
arraycopy
(
obuf
,
0
,
ret
,
0
,
obufcount
);
return
ret
;
}
}
/**
* @param data
* @return
*/
public
static
byte
[]
decode
(
String
data
)
{
char
ibuf
[]
=
new
char
[
4
];
int
ibufcount
=
0
;
byte
obuf
[]
=
new
byte
[(
data
.
length
()
/
4
)
*
3
+
3
];
int
obufcount
=
0
;
for
(
int
i
=
0
;
i
<
data
.
length
();
i
++)
{
char
ch
=
data
.
charAt
(
i
);
if
(
ch
!=
'='
&&
(
ch
>=
S_DECODETABLE
.
length
||
S_DECODETABLE
[
ch
]
==
127
))
continue
;
ibuf
[
ibufcount
++]
=
ch
;
if
(
ibufcount
==
ibuf
.
length
)
{
ibufcount
=
0
;
obufcount
+=
decode0
(
ibuf
,
obuf
,
obufcount
);
}
}
if
(
obufcount
==
obuf
.
length
)
{
return
obuf
;
}
else
{
byte
ret
[]
=
new
byte
[
obufcount
];
System
.
arraycopy
(
obuf
,
0
,
ret
,
0
,
obufcount
);
return
ret
;
}
}
/**
* @param data
* @param off
* @param len
* @param ostream
* @throws IOException
*/
public
static
void
decode
(
char
data
[],
int
off
,
int
len
,
OutputStream
ostream
)
throws
IOException
{
char
ibuf
[]
=
new
char
[
4
];
int
ibufcount
=
0
;
byte
obuf
[]
=
new
byte
[
3
];
for
(
int
i
=
off
;
i
<
off
+
len
;
i
++)
{
char
ch
=
data
[
i
];
if
(
ch
!=
'='
&&
(
ch
>=
S_DECODETABLE
.
length
||
S_DECODETABLE
[
ch
]
==
127
))
continue
;
ibuf
[
ibufcount
++]
=
ch
;
if
(
ibufcount
==
ibuf
.
length
)
{
ibufcount
=
0
;
int
obufcount
=
decode0
(
ibuf
,
obuf
,
0
);
ostream
.
write
(
obuf
,
0
,
obufcount
);
}
}
}
/**
* @param data
* @param ostream
* @throws IOException
*/
public
static
void
decode
(
String
data
,
OutputStream
ostream
)
throws
IOException
{
char
ibuf
[]
=
new
char
[
4
];
int
ibufcount
=
0
;
byte
obuf
[]
=
new
byte
[
3
];
for
(
int
i
=
0
;
i
<
data
.
length
();
i
++)
{
char
ch
=
data
.
charAt
(
i
);
if
(
ch
!=
'='
&&
(
ch
>=
S_DECODETABLE
.
length
||
S_DECODETABLE
[
ch
]
==
127
))
continue
;
ibuf
[
ibufcount
++]
=
ch
;
if
(
ibufcount
==
ibuf
.
length
)
{
ibufcount
=
0
;
int
obufcount
=
decode0
(
ibuf
,
obuf
,
0
);
ostream
.
write
(
obuf
,
0
,
obufcount
);
}
}
}
/**
* @param data
* @return
*/
public
static
String
encode
(
byte
data
[])
{
return
encode
(
data
,
0
,
data
.
length
);
}
/**
* @param data
* @param off
* @param len
* @return
*/
public
static
String
encode
(
byte
data
[],
int
off
,
int
len
)
{
if
(
len
<=
0
)
return
""
;
char
out
[]
=
new
char
[(
len
/
3
)
*
4
+
4
];
int
rindex
=
off
;
int
windex
=
0
;
int
rest
;
for
(
rest
=
len
-
off
;
rest
>=
3
;
rest
-=
3
)
{
int
i
=
((
data
[
rindex
]
&
255
)
<<
16
)
+
((
data
[
rindex
+
1
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
2
]
&
255
);
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
18
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
12
&
63
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
6
&
63
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
&
63
];
rindex
+=
3
;
}
if
(
rest
==
1
)
{
int
i
=
data
[
rindex
]
&
255
;
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
2
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
<<
4
&
63
];
out
[
windex
++]
=
'='
;
out
[
windex
++]
=
'='
;
}
else
if
(
rest
==
2
)
{
int
i
=
((
data
[
rindex
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
1
]
&
255
);
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
10
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
>>
4
&
63
];
out
[
windex
++]
=
S_BASE64CHAR
[
i
<<
2
&
63
];
out
[
windex
++]
=
'='
;
}
return
new
String
(
out
,
0
,
windex
);
}
/**
* @param data
* @param off
* @param len
* @param ostream
* @throws IOException
*/
public
static
void
encode
(
byte
data
[],
int
off
,
int
len
,
OutputStream
ostream
)
throws
IOException
{
if
(
len
<=
0
)
return
;
byte
out
[]
=
new
byte
[
4
];
int
rindex
=
off
;
int
rest
;
for
(
rest
=
len
-
off
;
rest
>=
3
;
rest
-=
3
)
{
int
i
=
((
data
[
rindex
]
&
255
)
<<
16
)
+
((
data
[
rindex
+
1
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
2
]
&
255
);
out
[
0
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
18
];
out
[
1
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
12
&
63
];
out
[
2
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
6
&
63
];
out
[
3
]
=
(
byte
)
S_BASE64CHAR
[
i
&
63
];
ostream
.
write
(
out
,
0
,
4
);
rindex
+=
3
;
}
if
(
rest
==
1
)
{
int
i
=
data
[
rindex
]
&
255
;
out
[
0
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
2
];
out
[
1
]
=
(
byte
)
S_BASE64CHAR
[
i
<<
4
&
63
];
out
[
2
]
=
61
;
out
[
3
]
=
61
;
ostream
.
write
(
out
,
0
,
4
);
}
else
if
(
rest
==
2
)
{
int
i
=
((
data
[
rindex
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
1
]
&
255
);
out
[
0
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
10
];
out
[
1
]
=
(
byte
)
S_BASE64CHAR
[
i
>>
4
&
63
];
out
[
2
]
=
(
byte
)
S_BASE64CHAR
[
i
<<
2
&
63
];
out
[
3
]
=
61
;
ostream
.
write
(
out
,
0
,
4
);
}
}
/**
* @param data
* @param off
* @param len
* @param writer
* @throws IOException
*/
public
static
void
encode
(
byte
data
[],
int
off
,
int
len
,
Writer
writer
)
throws
IOException
{
if
(
len
<=
0
)
return
;
char
out
[]
=
new
char
[
4
];
int
rindex
=
off
;
int
rest
=
len
-
off
;
int
output
=
0
;
do
{
if
(
rest
<
3
)
break
;
int
i
=
((
data
[
rindex
]
&
255
)
<<
16
)
+
((
data
[
rindex
+
1
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
2
]
&
255
);
out
[
0
]
=
S_BASE64CHAR
[
i
>>
18
];
out
[
1
]
=
S_BASE64CHAR
[
i
>>
12
&
63
];
out
[
2
]
=
S_BASE64CHAR
[
i
>>
6
&
63
];
out
[
3
]
=
S_BASE64CHAR
[
i
&
63
];
writer
.
write
(
out
,
0
,
4
);
rindex
+=
3
;
rest
-=
3
;
if
((
output
+=
4
)
%
76
==
0
)
writer
.
write
(
"\n"
);
}
while
(
true
);
if
(
rest
==
1
)
{
int
i
=
data
[
rindex
]
&
255
;
out
[
0
]
=
S_BASE64CHAR
[
i
>>
2
];
out
[
1
]
=
S_BASE64CHAR
[
i
<<
4
&
63
];
out
[
2
]
=
'='
;
out
[
3
]
=
'='
;
writer
.
write
(
out
,
0
,
4
);
}
else
if
(
rest
==
2
)
{
int
i
=
((
data
[
rindex
]
&
255
)
<<
8
)
+
(
data
[
rindex
+
1
]
&
255
);
out
[
0
]
=
S_BASE64CHAR
[
i
>>
10
];
out
[
1
]
=
S_BASE64CHAR
[
i
>>
4
&
63
];
out
[
2
]
=
S_BASE64CHAR
[
i
<<
2
&
63
];
out
[
3
]
=
'='
;
writer
.
write
(
out
,
0
,
4
);
}
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/ClientCustomSSL.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
org.apache.http.HttpEntity
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.apache.http.client.methods.HttpPost
;
import
org.apache.http.conn.ssl.SSLConnectionSocketFactory
;
import
org.apache.http.conn.ssl.SSLContexts
;
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
javax.net.ssl.SSLContext
;
import
java.io.InputStream
;
import
java.security.KeyStore
;
/**
* @author wang jianguo
* @date 2020/10/20 15:15
* @email qizhi1a440@outlook.com
* @description:
*/
public
class
ClientCustomSSL
{
/**
* @param url 微信接口路径
* @param data
* @param mchIdStr
* @return
* @throws Exception
*/
public
static
String
doRefund
(
InputStream
wxCert
,
String
url
,
String
data
,
String
mchIdStr
)
throws
Exception
{
/**
* 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
*/
char
[]
mchId
=
mchIdStr
.
toCharArray
();
KeyStore
keyStore
=
KeyStore
.
getInstance
(
"PKCS12"
);
//FileInputStream instream = new FileInputStream(new File(wxCertPath));//P12文件在服务器磁盘中的目录
try
{
/**
* 此处要改成你的MCHID
* */
keyStore
.
load
(
wxCert
,
mchId
);
//这里写密码..默认是你的MCHID
}
finally
{
wxCert
.
close
();
}
// Trust own CA and all self-signed certs
/**
* 此处要改成你的MCHID
* */
SSLContext
sslcontext
=
SSLContexts
.
custom
()
.
loadKeyMaterial
(
keyStore
,
mchId
)
//这里也是写密码的
.
build
();
SSLConnectionSocketFactory
sslsf
=
new
SSLConnectionSocketFactory
(
sslcontext
,
new
String
[]{
"TLSv1"
},
null
,
SSLConnectionSocketFactory
.
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
);
CloseableHttpClient
httpclient
=
HttpClients
.
custom
()
.
setSSLSocketFactory
(
sslsf
)
.
build
();
try
{
HttpPost
httpost
=
new
HttpPost
(
url
);
// 设置响应头信息
httpost
.
addHeader
(
"Connection"
,
"keep-alive"
);
httpost
.
addHeader
(
"Accept"
,
"*/*"
);
httpost
.
addHeader
(
"Content-Type"
,
"application/x-www-form-urlencoded; charset=UTF-8"
);
httpost
.
addHeader
(
"Host"
,
"api.mch.weixin.qq.com"
);
httpost
.
addHeader
(
"X-Requested-With"
,
"XMLHttpRequest"
);
httpost
.
addHeader
(
"Cache-Control"
,
"max-age=0"
);
httpost
.
addHeader
(
"User-Agent"
,
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "
);
httpost
.
setEntity
(
new
StringEntity
(
data
,
"UTF-8"
));
CloseableHttpResponse
response
=
httpclient
.
execute
(
httpost
);
try
{
HttpEntity
entity
=
response
.
getEntity
();
String
jsonStr
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"UTF-8"
);
EntityUtils
.
consume
(
entity
);
return
jsonStr
;
}
finally
{
response
.
close
();
}
}
finally
{
httpclient
.
close
();
}
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/IPUtil.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
com.common.util.Utils
;
import
javax.servlet.http.HttpServletRequest
;
/**
*
* @description 获取客户端IP
* @author wangyu
*
*/
public
class
IPUtil
{
public
static
String
getIpAddress
(
HttpServletRequest
request
)
{
return
Utils
.
getIpAddress
(
request
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/MD5Util.java
0 → 100644
View file @
3765b47f
This diff is collapsed.
Click to expand it.
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/MapKeyComparator.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
java.util.Comparator
;
//比较器类
public
class
MapKeyComparator
implements
Comparator
<
String
>
{
public
int
compare
(
String
str1
,
String
str2
)
{
return
str1
.
compareTo
(
str2
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/MapUtil.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
java.net.URLEncoder
;
import
java.util.*
;
import
java.util.Map.Entry
;
public
class
MapUtil
{
/**
* 使用 Map按key进行排序
* @param map
* @return
*/
public
static
Map
<
String
,
String
>
sortMapByKey
(
Map
<
String
,
String
>
map
)
{
if
(
map
==
null
||
map
.
isEmpty
())
{
return
null
;
}
Map
<
String
,
String
>
sortMap
=
new
TreeMap
<
String
,
String
>(
new
MapKeyComparator
());
sortMap
.
putAll
(
map
);
return
sortMap
;
}
/**
* 将map内的数据按key的顺序排序并拼接字符串
* @param paraMap
* @param urlencode
* @return
* @throws Exception
*/
public
static
String
FormatBizQueryParaMap
(
Map
<
String
,
String
>
paraMap
,
boolean
urlencode
)
throws
Exception
{
String
buff
=
""
;
try
{
List
<
Entry
<
String
,
String
>>
infoIds
=
new
ArrayList
<
Entry
<
String
,
String
>>(
paraMap
.
entrySet
());
Collections
.
sort
(
infoIds
,
new
Comparator
<
Entry
<
String
,
String
>>()
{
public
int
compare
(
Entry
<
String
,
String
>
o1
,
Entry
<
String
,
String
>
o2
)
{
return
(
o1
.
getKey
()).
toString
().
compareTo
(
o2
.
getKey
());
}
});
for
(
int
i
=
0
;
i
<
infoIds
.
size
();
i
++)
{
Entry
<
String
,
String
>
item
=
infoIds
.
get
(
i
);
//System.out.println(item.getKey());
if
(
item
.
getKey
()
!=
""
)
{
String
key
=
item
.
getKey
();
String
val
=
item
.
getValue
();
if
(
urlencode
)
{
val
=
URLEncoder
.
encode
(
val
,
"utf-8"
);
}
buff
+=
key
+
"="
+
val
+
"&"
;
}
}
if
(
buff
.
isEmpty
()
==
false
)
{
buff
=
buff
.
substring
(
0
,
buff
.
length
()
-
1
);
}
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
.
getMessage
());
}
return
buff
;
}
/**
* HashMap转成xml类型的String
* @param arr
* @return
*/
public
static
String
ArrayToXml
(
HashMap
<
String
,
String
>
arr
)
{
String
xml
=
"<xml>"
;
Iterator
<
Entry
<
String
,
String
>>
iter
=
arr
.
entrySet
().
iterator
();
while
(
iter
.
hasNext
())
{
Entry
<
String
,
String
>
entry
=
iter
.
next
();
String
key
=
entry
.
getKey
();
String
val
=
entry
.
getValue
();
if
(
IsNumeric
(
val
))
{
xml
+=
"<"
+
key
+
">"
+
val
+
"</"
+
key
+
">"
;
}
else
xml
+=
"<"
+
key
+
"><![CDATA["
+
val
+
"]]></"
+
key
+
">"
;
}
xml
+=
"</xml>"
;
return
xml
;
}
public
static
boolean
IsNumeric
(
String
str
)
{
if
(
str
.
matches
(
"\\d *"
))
{
return
true
;
}
else
{
return
false
;
}
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/ParseXmlUtil.java
0 → 100644
View file @
3765b47f
/*
* Copyright (c) 2015. xitai information and technology company
*/
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentHelper
;
import
org.dom4j.Element
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* Created by peter on 15/5/12.
*/
public
class
ParseXmlUtil
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ParseXmlUtil
.
class
);
/**
* 解析得到相应键的值
*
* @param xml,key
* @return
* @throws Exception
*/
public
static
String
parseXml2KeyValue
(
String
xml
,
String
key
)
throws
Exception
{
Document
doc
=
null
;
doc
=
DocumentHelper
.
parseText
(
xml
);
// 将字符串转为XML
Element
rootElt
=
doc
.
getRootElement
();
// 获取根节点
Element
keyValue
=
rootElt
.
element
(
key
);
String
Value
=
keyValue
.
getText
();
return
Value
;
}
/***
* 解析xml转换成Map
*
* @param xmlStr
* @return
* @throws Exception
*/
public
static
Map
<
String
,
String
>
parseXml2Map
(
String
xml
)
throws
Exception
{
// 解析结果存储在HashMap
Map
<
String
,
String
>
map
=
new
HashMap
<
String
,
String
>();
Document
reader
=
DocumentHelper
.
parseText
(
xml
);
// 得到xml根元素
Element
root
=
reader
.
getRootElement
();
// 得到根元素的所有子节点
List
<
Element
>
elementList
=
root
.
elements
();
// 遍历所有子节点
for
(
Element
e
:
elementList
)
{
map
.
put
(
e
.
getName
(),
e
.
getText
());
}
return
map
;
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/UUIDGenerator.java
0 → 100644
View file @
3765b47f
/*
* Copyright (c) 2015. xitai information and technology company
*/
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
java.net.InetAddress
;
/**
* 生成UUID字符串
* @author wangyu
*
*/
public
class
UUIDGenerator
{
/** The Constant IP. */
private
static
final
int
IP
;
/** The Constant JVM. */
private
static
final
int
JVM
=
(
int
)
(
System
.
currentTimeMillis
()
>>>
8
);
/** The counter. */
private
static
short
counter
=
(
short
)
0
;
static
{
int
ipadd
;
try
{
byte
[]
ip
=
InetAddress
.
getLocalHost
().
getAddress
();
ipadd
=
((((
int
)
ip
[
0
])
<<
24
)
&
0xFF000000
)
|
((((
int
)
ip
[
1
])
<<
16
)
&
0x00FF0000
)
|
((((
int
)
ip
[
2
])
<<
8
)
&
0x0000FF00
)
|
(((
int
)
ip
[
3
])
&
0x000000FF
);
}
catch
(
Exception
e
)
{
ipadd
=
0
;
}
IP
=
ipadd
;
}
/**
* Gets the hi time.
*
* @return the hi time
*/
protected
static
short
getHiTime
()
{
return
(
short
)
(
System
.
currentTimeMillis
()
>>>
32
);
}
/**
* Gets the lo time.
*
* @return the lo time
*/
protected
static
int
getLoTime
()
{
return
(
int
)
System
.
currentTimeMillis
();
}
/**
* Format.
*
* @param intval
* the intval
* @return the string
*/
protected
static
String
format
(
int
intval
)
{
String
formatted
=
Integer
.
toHexString
(
intval
);
StringBuffer
buf
=
new
StringBuffer
(
"00000000"
);
buf
.
replace
(
8
-
formatted
.
length
(),
8
,
formatted
);
return
buf
.
toString
();
}
/**
* Format.
*
* @param shortval
* the shortval
* @return the string
*/
protected
static
String
format
(
short
shortval
)
{
String
formatted
=
Integer
.
toHexString
(
shortval
);
StringBuffer
buf
=
new
StringBuffer
(
"0000"
);
buf
.
replace
(
4
-
formatted
.
length
(),
4
,
formatted
);
return
buf
.
toString
();
}
/**
* 产生一个32个字符长的UUID.
*
* @return the string
*/
public
static
synchronized
String
generate
()
{
return
new
StringBuffer
(
20
).
append
(
format
(
IP
)).
append
(
format
(
JVM
)).
append
(
format
(
getHiTime
())).
append
(
format
(
getLoTime
()))
.
append
(
format
(
counter
++)).
toString
();
}
/**
* Generate8 hex.
*
* @return the string
*/
public
static
synchronized
String
generate8Hex
()
{
return
format
(
getLoTime
());
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/UUIDUtil.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
java.util.UUID
;
/**
* @author wang jianguo
* @date 2020/10/20 15:14
* @email qizhi1a440@outlook.com
* @description:
*/
public
class
UUIDUtil
{
public
static
String
createUUID
()
{
return
UUID
.
randomUUID
().
toString
().
replaceAll
(
"-"
,
""
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/WXPayUtil.java
0 → 100644
View file @
3765b47f
This diff is collapsed.
Click to expand it.
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/pay/util/WXPayXmlUtil.java
0 → 100644
View file @
3765b47f
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
.
pay
.
util
;
import
org.w3c.dom.Document
;
import
javax.xml.XMLConstants
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
/**
* 2018/7/3
*/
public
final
class
WXPayXmlUtil
{
public
static
DocumentBuilder
newDocumentBuilder
()
throws
ParserConfigurationException
{
DocumentBuilderFactory
documentBuilderFactory
=
DocumentBuilderFactory
.
newInstance
();
documentBuilderFactory
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
documentBuilderFactory
.
setFeature
(
"http://xml.org/sax/features/external-general-entities"
,
false
);
documentBuilderFactory
.
setFeature
(
"http://xml.org/sax/features/external-parameter-entities"
,
false
);
documentBuilderFactory
.
setFeature
(
"http://apache.org/xml/features/nonvalidating/load-external-dtd"
,
false
);
documentBuilderFactory
.
setFeature
(
XMLConstants
.
FEATURE_SECURE_PROCESSING
,
true
);
documentBuilderFactory
.
setXIncludeAware
(
false
);
documentBuilderFactory
.
setExpandEntityReferences
(
false
);
return
documentBuilderFactory
.
newDocumentBuilder
();
}
public
static
Document
newDocument
()
throws
ParserConfigurationException
{
return
newDocumentBuilder
().
newDocument
();
}
}
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