日期 版本 作者 说明
2023-10-17 V-1.0 孔留锋 文档新建。

微信小程序支付开发

简介

背景

​ 现有微信小程序,添加会员卡付费模块(延长使用时间),需要对接微信支付。

官网文档

微信支付官网

https://pay.weixin.qq.com/

微信小程序官网

https://mp.weixin.qq.com/

微信小程序支付文档

https://pay.weixin.qq.com/docs/merchant/products/mini-program-payment/introduction.html

数据准备

商户号

商户号:1654589714

微信商户平台-》账户中心-》商户信息

image-20231017134308489

小程序ID(AppID)

小程序ID:wxe**

小程序后台-》设置-》基本设置-》账号信息

image-20231017134959867

API证书申请

微信商户平台-》API安全-》下载证书工具-》安装-》解压

image-20231017141335161

image-20231017141506875

image-20231017142219205

生产后 本地D:\Mac\2_CodeCompiller\WXCertUtil\cert 下有对应密钥文件

1654589714_20231017_cert.zip

解压后文件如下

  • apiclient_cert.p12
  • apiclient_cert.pem
  • apiclient_key.pem
  • 证书使用说明.txt

APIv3密钥设置

随机密码生成器

FzgK

以上所有API密钥和证书需要妥善保管防止泄漏

商户证书序列号

微信商户平台-》API安全-》证书号

开发流程

流程图

6_2

重要步骤说明

  • 步骤4:用户下单发起支付,商户可通过JSAPI下单创建支付订单。
  • 步骤9:商户小程序内使用小程序调起支付API(wx.requestPayment)发起微信支付,详见小程序API文档
  • 步骤16:用户支付成功后,商户可接收到微信支付支付结果通知支付通知API
  • 步骤21:商户在没有接收到微信支付结果通知的情况下需要主动调用查询订单API查询支付结果。

小程序支付相关接口

商户平台小程序支付 官方文档

  • JSAPI下单 :通过本接口提交微信支付小程序支付订单。
  • 查询订单:通过此接口查询订单状态。
  • 关闭订单:通过此接口关闭待支付订单。
  • 小程序调起支付:通过小程序下单接口获取到发起支付的必要参数prepay_id,可以按照接口定义中的规则,调起小程序支付。
  • 支付通知:微信支付通过支付通知接口将用户支付成功消息通知给商户。
  • 申请退款:商户可以通过该接口将支付金额退还给买家。
  • 查询单笔退款:提交退款申请后,通过调用该接口查询退款状态 。
  • 退款结果通知:微信支付通过退款通知接口将用户退款成功消息通知给商户。
  • 申请交易账单:商户可以通过该接口获取交易账单文件的下载地址。
  • 申请资金账单:商户可以通过该接口获取资金账单文件的下载地址。
  • 下载账单:通过申请交易/资金账单获取到download_url在该接口获取到对应的账单。

JSAPI下单API

​ 商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按Native、JSAPI、APP等不同场景生成交易串调起支付。

​ 地址:JSAPI下单

注意:

  • 应用ID(微信生成的应用ID,全局唯一)
  • 直连商户号(直连商户的商户号,由微信支付生成并下发) 参考 接入准备中
  • 商户订单号(商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一),需要结合系统自己定义
  • 通知地址(异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 公网域名必须为https,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用http)

查询订单API

​ 商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。查询订单状态可通过微信支付订单号商户订单号两种方式查询,两种查询方式返回结果相同。

需要调用查询接口的情况

  • 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知。
  • 调用支付接口后,返回系统错误或未知交易状态情况。
  • 调用付款码支付API,返回USERPAYING的状态。
  • 调用关单或撤销接口API之前,需确认支付状态。

​ 地址:查询订单

注意:

  • 直连商户号 参考 接入准备中

关闭订单API

​ 以下情况需要调用关单接口:

  • 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付

  • 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。

    ​ 地址:关闭订单

注意:

  • 关单没有时间限制,建议在订单生成后**间隔几分钟(最短5分钟)**再调用关单接口,避免出现订单状态同步不及时导致关单失败。

小程序调起支付API

​ 通过JSAPI下单接口获取到发起支付的必要参数prepay_id,然后使用微信支付提供的小程序方法调起小程序支付。

​ 地址:小程序调起支付

注意:

  • 小程序调起支付的参数需要按照签名规则进行签名计算

支付通知API

​ 微信支付通过支付通知接口将用户支付成功消息通知给商户。

注意:

  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
  • 如果在所有通知频率后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。

特别提醒:商户系统对于开启结果通知的内容一定要做签名验证,并校验通知的信息是否与商户侧的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。

申请退款API

​ 当交易发生之后一年内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付金额退还给买家,微信支付将在收到退款请求并且验证成功之后,将支付款按原路退还至买家账号上。

​ 地址:申请退款

注意:

  • 交易时间超过一年的订单无法提交退款

  • 微信支付退款支持单笔交易分多次退款(不超50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号

  • 错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次

  • 每个支付订单的部分退款次数不能超过50次

  • 如果同一个用户有多笔退款,建议分不同批次进行退款,避免并发退款导致退款失败

  • 申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过退款查询接口获取结果

  • 一个月之前的订单申请退款频率限制为:5000/min

  • 同一笔订单多次退款的请求需相隔1分钟

查询单笔退款API

​ 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,建议在提交退款申请后1分钟发起查询退款状态,一般来说零钱支付的退款5分钟内到账,银行卡支付的退款1-3个工作日到账。

​ 地址:查询单笔退款

退款结果通知API

​ 退款状态改变后,微信会把相关退款结果发送给商户。
​ 地址:退款结果通知

注意:

  • 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功
  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
  • 如果在所有通知频率后没有收到微信侧回调。商户应调用查询订单接口确认订单状态。

申请交易账单API

​ 微信支付按天提供交易账单文件,商户可以通过该接口获取账单文件的下载地址。文件内包含交易相关的金额、时间、营销等信息,供商户核对订单、退款、银行到账等情况。

​ 地址:申请交易账单

注意:

  • 微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致;

  • 对账单中涉及金额的字段单位为“元”;

  • 对账单接口只能下载三个月以内的账单。

申请资金账单API

​ 微信支付按天提供微信支付账户的资金流水账单文件,商户可以通过该接口获取账单文件的下载地址。文件内包含该账户资金操作相关的业务单号、收支金额、记账时间等信息,供商户进行核对。

​ 地址:申请资金账单

注意:

  • 资金账单中的数据反映的是商户微信支付账户资金变动情况;
  • 对账单中涉及金额的字段单位为“元”。

下载账单API

​ 下载账单API为通用接口,交易/资金账单都可以通过该接口获取到对应的账单。

​ 地址:下载账单

注意:

  • 账单文件的下载地址的有效时间为30s。
  • 强烈建议商户将实际账单文件的哈希值和之前从接口获取到的哈希值进行比对,以确认数据的完整性。
  • 该接口响应的信息请求头中不包含微信接口响应的签名值,因此需要跳过验签的流程。
  • 微信在次日9点启动生成前一天的对账单,建议商户10点后再获取。

代码开发

官网sdk引用

wechatpay-sdk

1
2
3
4
5
6
<!-- 微信支付 -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>

配置文件

1
2
3
4
5
6
7
wxpay:
merchantId: 16********
merchantSerialNumber: 204AC***********************************
privateKeyPath: D:/Mac/2_CodeCompiller/WXCertUtil/cert/apiclient_key.pem
apiV3Key: Fzg*****************************
appid: wxe***************
notifyUrl: https://********.*****.cn/api/pay/notify

WxPayConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.wechat.pay.java.core.Config;

/**
* @author kongliufeng
* @create 2023-10-18
*/
@Configuration
@Data
@ConfigurationProperties("wxpay")
public class WxPayConfig {
/**
* 商户号
*/
private String merchantId;

/**
* 商户证书序列号
*/
private String merchantSerialNumber ;

/**
* 商户API私钥路径
*/
private String privateKeyPath;

/**
* 商户APIV3密钥
*/
private String apiV3Key;

/**
* APPID
*/
private String appid;

/**
* 【通知地址】步接收微信支付结果通知的回调地址
*/
private String notifyUrl;


/**
* @description 微信配置初始
*
* @author kongliufeng
* @Date 2023-10-20
*/
@Bean("WechatConfig")
public Config getWechatConfig(){
return new RSAAutoCertificateConfig.Builder()
.merchantId(merchantId)
.privateKeyFromPath(privateKeyPath)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3Key)
.build();
}

/**
* @description
*
* @author kongliufeng 微信服务client端
* @Date 2023-10-20
*/
@Bean
public JsapiServiceExtension getJsapiServiceExtension(Config wechatConfig){
return new JsapiServiceExtension.Builder()
.config(wechatConfig).build();
}

/**
* @description 回调解析
*
* @author kongliufeng
* @Date 2023-10-21
*/
@Bean
public NotificationParser getNotificationParser(Config wechatConfig){
return new NotificationParser((NotificationConfig)wechatConfig);
}
}

核心接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
@RequestMapping("/api/applets/")
@RestController
@Slf4j
public class PayApi {
@Autowired
private WxPayConfig wxPayConfig;
@Autowired
private JsapiServiceExtension jsapiServiceExtension;
@Autowired
private IVipProductService iVipProductService;
@Autowired
private IVipOrderInfoService iVipOrderInfoService;
@Autowired
private IVipUserInfoService iVipUserInfoService;
@Autowired
private AuthRequestEnhanceFactory factory;
@Autowired
private IVipPaymentInfoService iVipPaymentInfoService;

/**
* @description 获取商品展示列表
*
* @author kongliufeng
* @Date 2023-10-20
*/
@RequestMapping("/produce/list")
public Result getProduceList(){
List<ProduceVO> result = iVipProductService.getAppletsShowList();
return Result.OK(result);
}

/**
* @description 获取opendId
*
* @author kongliufeng
* @Date 2023-10-20
*/
@GetMapping({"/openId/{code}"})
@Log(title = "小程序-权限判断", businessType = BusinessType.APPLETS)
@Transactional
public @ResponseBody Result openId(@PathVariable String code){
// VipUserInfo 非空随用户新建初始化
VipUserInfo byIdEx = iVipUserInfoService.getByIdEx();
if(StringUtils.isEmpty(byIdEx.getOpenId())){
//不存在
log.info("openId 不存在获取新的{}");
//获取新的
AuthWechatAppletsOauthRequest authRequest = (AuthWechatAppletsOauthRequest)factory.get(AppletConstant.APPLETS_OAUTH_KEY);
AuthCallback authCallback = new AuthCallback();
authCallback.setCode(code);
authCallback.setAuthorization_code(AppletConstant.AGENT_UUID);
AuthUser login = authRequest.login(authRequest.getAccessToken(authCallback));

VipUserInfo update = new VipUserInfo();
update.setUserId(byIdEx.getUserId());
update.setOpenId(login.getUuid());
iVipUserInfoService.updateByIdEx(update);
log.info("openId 不存在获取新的{}",login.getUuid());
return Result.OK(login.getUuid());
}
return Result.OK(byIdEx.getOpenId());
}

/**
* @description 下单
* @param code : 商品编码
*
* @author kongliufeng
* @Date 2023-10-20
*/
@RequestMapping("/order/create")
@Transactional
public Result createOrder(String code,String openId){
log.info("小程序发起下单请求code:[{}],openId:[{}]",code,openId);
//1.获取用户信息生成本地商品
VipProduct vo = iVipProductService.getByCode(code);
if(vo==null){
return Result.error500("商品编码不存在");
}
//2.生成订单信息并保持本地
VipOrderInfo orderInfo = new VipOrderInfo();
orderInfo.setId(IdWorker.getId());
orderInfo.setTitle(vo.getTitle());
orderInfo.setUserId(SecurityUtils.getUserId());
orderInfo.setProductCode(code);
orderInfo.setRealPrice(vo.getRealPrice());
orderInfo.setCreateTime(DateUtil.now());
iVipOrderInfoService.saveEx(orderInfo);

//3.调用微信支付-成预支付交易单
PrepayRequest request = new PrepayRequest();
request.setAppid(wxPayConfig.getAppid());
request.setMchid(wxPayConfig.getMerchantId());
request.setDescription(orderInfo.getTitle());
request.setOutTradeNo(orderInfo.getId().toString());
request.setNotifyUrl(wxPayConfig.getNotifyUrl());
//订单金额
Amount amount = new Amount();
amount.setTotal(vo.getRealPrice());
request.setAmount(amount);
//支付者
Payer payer = new Payer();
payer.setOpenid(openId);
request.setPayer(payer);
PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse =null;
log.info("小程序发起下单-微信调用请求信息:[{}]",request.toString());
try{
prepayWithRequestPaymentResponse = jsapiServiceExtension.prepayWithRequestPayment(request);
}catch (HttpException e){
e.printStackTrace();
log.info("发送HTTP请求失败:error [{}]",e.getHttpRequest());
}catch (ServiceException e) {
log.info("服务返回状态小于200或大于等于300:error [{}]",e.getResponseBody());
} catch (MalformedMessageException e) {
log.info("务返回成功,返回体类型不合法,或者解析返回体失败:error [{}]",e.getMessage());
}
String result = JSON.toJSONString(prepayWithRequestPaymentResponse);
log.info("微信调用返回信息:[{}]",JSON.toJSONString(result));

//4.生成交易信息并保留
VipPaymentInfo paymentInfo = new VipPaymentInfo();
paymentInfo.setOrderId(orderInfo.getId().toString());
paymentInfo.setTradeState(Transaction.TradeStateEnum.NOTPAY.name());
paymentInfo.setCreateBy(SecurityUtils.getUsername());
paymentInfo.setPrepayResponseContent(result);
paymentInfo.setCreateTime(DateUtil.now());
iVipPaymentInfoService.saveEx(paymentInfo);

prepayWithRequestPaymentResponse.setAppId(paymentInfo.getOrderId());
return Result.OK(prepayWithRequestPaymentResponse);
}

/**
* @description 手动查看订单状态
*
* @author kongliufeng
* @Date 2023-10-21
*/
@RequestMapping("/order/status")
@Transactional
public Result queryOrder(String orderId){
log.info("订单常态查询更新->orderId:[{}]",orderId);
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setOutTradeNo(orderId);
request.setMchid(wxPayConfig.getMerchantId());
Transaction parse = jsapiServiceExtension.queryOrderByOutTradeNo(request);
//返回结果
if(parse.getTradeState().name().equals(Transaction.TradeStateEnum.SUCCESS.name())){
//更新支付信息
String payTime = DateUtil.parseUTC(parse.getSuccessTime()).toString();
VipPaymentInfo paymentInfo = iVipPaymentInfoService.getByOrderId(parse.getOutTradeNo());
paymentInfo.setTransactionId(parse.getTransactionId());
paymentInfo.setTradeType(parse.getTradeType().name());
paymentInfo.setTradeState(parse.getTradeState().name());
paymentInfo.setPayerTime(payTime);
paymentInfo.setPayerTotal(parse.getAmount().getPayerTotal());
paymentInfo.setContent(JSON.toJSONString(parse));
paymentInfo.setUpdateBy("微信支付回调");
paymentInfo.setUpdateTime(DateUtil.now());
iVipPaymentInfoService.updateByIdEx(paymentInfo);

//更新支付信息
VipOrderInfo vipOrderInfo = new VipOrderInfo();
vipOrderInfo.setId(Long.valueOf(parse.getOutTradeNo()));
vipOrderInfo.setOrderStatus(1);
vipOrderInfo.setPayTime(payTime);
vipOrderInfo.setUpdateBy("微信支付回调");
vipOrderInfo.setUpdateTime(DateUtil.now());
iVipOrderInfoService.updateByIdEx(vipOrderInfo);

//设置用户时长 TODO
}
return Result.OK("修改成功");
}

/**
* @description 获取完成订单
*
* @author kongliufeng
* @Date 2023-10-20
*/
@RequestMapping("/order/list")
@Transactional
public Result orderList(@RequestParam(required = false,defaultValue = "1") Integer status){
LambdaQueryWrapper<VipOrderInfo> eq = Wrappers.lambdaQuery(VipOrderInfo.class).eq(VipOrderInfo::getOrderStatus, status)
.eq(VipOrderInfo::getUserId, SecurityUtils.getUserId());
List<VipOrderInfo> list = iVipOrderInfoService.listEx(eq);
List<VipOrderInfoVo> rows = new ArrayList<>();
for (VipOrderInfo vipOrderInfo : list) {
VipOrderInfoVo vo = new VipOrderInfoVo();
BeanUtils.copyProperties(vipOrderInfo,vo);
vo.setId(vipOrderInfo.getId().toString());
vo.setStatus(vipOrderInfo.getOrderStatus());
rows.add(vo);
}
return Result.OK(rows);
}
}

微信回调接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@RequestMapping("/api/")
@Controller
@Slf4j
public class PayNotificationApi {

@Autowired
private NotificationParser notificationParser;
@Autowired
private IVipPaymentInfoService iVipPaymentInfoService;
@Autowired
private IVipOrderInfoService iVipOrderInfoService;


/**
* @description 微信支付成功回调
*
* @author kongliufeng
* @Date 2023-10-21
*/
@RequestMapping("/pay/notify")
public Object payNotify(HttpServletRequest request){
log.info("微信回调开始");
try{
//1.解析微信返回内容
String requestBody = IOUtil.toString(request.getInputStream());
log.info("微信回调开始-->requestBody :{}",requestBody);
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(request.getHeader(WechatPayNotificationKey.Serial.getKey()))
.nonce(request.getHeader(WechatPayNotificationKey.Nonce.getKey()))
.signature(request.getHeader(WechatPayNotificationKey.Signature.getKey()))
.timestamp(request.getHeader(WechatPayNotificationKey.Timestamp.getKey()))
.body(requestBody)
.build();
Transaction parse = notificationParser.parse(requestParam, Transaction.class);
String content = JSON.toJSONString(parse);
log.info("微信回调解析结果-->parse data :{}", content);

//2.业务处理-支付成功情况下
if(parse.getTradeState().name().equals(Transaction.TradeStateEnum.SUCCESS.name())){
//更新支付信息
String payTime = DateUtil.parse(parse.getSuccessTime()).toString();
VipPaymentInfo paymentInfo = iVipPaymentInfoService.getByOrderId(parse.getOutTradeNo());
if(paymentInfo!=null){
//已经被执行
paymentInfo.setTransactionId(parse.getTransactionId());
paymentInfo.setTradeType(parse.getTradeType().name());
paymentInfo.setTradeState(parse.getTradeState().name());
paymentInfo.setPayerTime(payTime);
paymentInfo.setPayerTotal(parse.getAmount().getPayerTotal());
paymentInfo.setContent(content);
paymentInfo.setUpdateBy("微信支付回调");
paymentInfo.setUpdateTime(DateUtil.now());
iVipPaymentInfoService.updateByIdEx(paymentInfo);

//更新支付信息
VipOrderInfo vipOrderInfo = new VipOrderInfo();
vipOrderInfo.setId(Long.valueOf(parse.getOutTradeNo()));
vipOrderInfo.setOrderStatus(1);
vipOrderInfo.setPayTime(payTime);
vipOrderInfo.setUpdateBy("微信支付回调");
vipOrderInfo.setUpdateTime(DateUtil.now());
iVipOrderInfoService.updateByIdEx(vipOrderInfo);
}
}
}catch (ValidationException e){
log.error("签名验证失败", e);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
}catch (Exception e){
log.error("业务处理失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
// 处理成功,返回 200 OK 状态码
return ResponseEntity.status(HttpStatus.OK);
}
}

异常记录

Illegal key size

1
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.wechat.pay.java.core.Config]: nested exception is java.lang.IllegalArgumentException: java.security.InvalidKeyException: Illegal key size

查阅资料发现密钥长度受限制,原因JDK版本小于1.8_150的有影响。

1
2
3
4
C:\Users\Iduohua>java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

安装更新高版本JDK 1.8.0_361

1
2
3
4
C:\Users\Iduohua>java -version
java version "1.8.0_361"
Java(TM) SE Runtime Environment (build 1.8.0_361-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.361-b09, mixed mode)