引入的SDK版本
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
加密config(pem文件在resources下)
private Config getConfig() {
if(config == null){
PrivateKey privateKey = getPrivateKey("wechatpay/apiclient_key.pem");
config = new RSAAutoCertificateConfig.Builder()
.merchantId(properties.getMch().getMchId())
.privateKey(privateKey)
.merchantSerialNumber(properties.getMch().getMchSn())
.apiV3Key(properties.getMch().getApiV3Key())
.build();
}
return config;
}
解密config(pem文件在resources下)
public NotificationConfig getNotificationConfig() {
if(notificationConfig == null){
PrivateKey privateKey = getPrivateKey("wechatpay/apiclient_key.pem");
notificationConfig = new RSAAutoCertificateConfig.Builder()
.merchantId(properties.getMch().getMchId())
.privateKey(privateKey)
.merchantSerialNumber(properties.getMch().getMchSn())
.apiV3Key(properties.getMch().getApiV3Key())
.build();
}
return notificationConfig;
}
***问题:
测试环境:用natapp内网穿透映射的回调地址,回调解密正常
生产环境:用nginx代理的回调地址,回调解密失败
错误信息(****是我打的码):
com.wechat.pay.java.core.exception.ValidationException: Processing WechatPay notification,signature verification failed,signType[WECHATPAY2-SHA256-RSA2048] serial[7D816CEC414164CF1C9899187865763F3******] message[1725464137
1kfL1LvqkBsHt715Tvr54Iz******
{"id":"2954fad7-e7d0-51e9-baf9-6ca*******","create_time":"2024-09-04T23:35:37+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"鏀粯鎴愬姛","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"6zJ+yFafNx+Rr3Z3qn2W1Na4gvhHSMdKl5NlDO1Up5BI1JP7hW0uiJd2EMkq/7Xem3y9b2jteJXxuhDN/aeoss2lXB1WlXHedOVq3W0ZOMbWZp5oqnF/S1fPFgbrPCRe8k2011xUAmTaHZEzjZd9mDm0iuDQTjx4W2Am9hfH8vCNlE9TJPF2yyFji7A6ue0Xf3sWAQJi2Wla1AxtoOOZVRvnH4Ook3cj1lkKOnhDqHQJNyeoDiRvGsHW/I3axTkSGAJUT3UEmhArfqvD5IeubQLCXPVUD2dATmnWtb0HMVdO+ZTlgT62RTMJ0EAmN4xvTQMxqAJW9/YJ/44siBWpT84Wa6P4g427r5KnRtrGK0Lr+Ny6kuV+mEG4RE76jsHbized6YiB1CgKogBG52psX7RTBGg9IdRufQ791yhGXx1frc28k6uCyJUG***********xhyB
iI+96+QQ9AXHqKJq0UY+04qfo1Xs7yzXZVPnCiqpv+LN1PY3*******","associated_data":"transaction","nonce":"6uiyqNHQ****"}}
] sign[C1JY8Jf+VeYmbALKx9qcUSBF8Vsj430YK8o+TonodqkNRegv7X**********3RAOd1Gu+K+DCJLg+D847v2pcoF7cv6tm0f+ES2a+86acT3XDELVYFIGV8ZbODg4vKoahLC2BfvKzPPayo+KUh2845nz0N1vhY4SHRUqV3hXbukuLljaaniDljRl24iXtrZkSn1FKH0aq8T1/hIILU6zNxkDjQGcBl8rMktARCRx0JUmAJwkwCZOcGiJ+NyrIO9R++YJGbET9uAm1iOuOJUwLOneeLUh+nDVpL9IvyUlBAtHF1LNtH5sAOWpbTFtLHYD/5+gYPY8IAmDw==]
summary字段乱码了导致的,编码问题导致
* 【微信支付】回调地址
* <p>
* request 请求体
* response 响应体
*/
@RequestMapping(value = "callback")
public ResponseEntity.BodyBuilder callBack(HttpServletRequest request) throws IOException {
//读取请求体的信息
ServletInputStream inputStream = request.getInputStream();
StringBuffer stringBuffer = new StringBuffer();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s;
//读取回调请求体
while ((s = bufferedReader.readLine()) != null) {
stringBuffer.append(s);
}
String requestBody = stringBuffer.toString();
String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
String nonce = request.getHeader(WECHAT_PAY_NONCE);
String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
//请求参数
RequestParam requestParam = new RequestParam.Builder()
.signType("WECHATPAY2-SHA256-RSA2048")
.serialNumber(serialNo)
.nonce(nonce)
.signature(signature)
.timestamp(timestamp)
.body(requestBody)
.build();
// 初始化 NotificationParser
NotificationParser parser = new NotificationParser(wechatPayService.getNotificationConfig());
try {
// 以支付通知回调为例,验签、解密并转换成 Transaction
Transaction transaction = parser.parse(requestParam, Transaction.class);
StaticLog.info("【微信支付回调】回调信息:"+transaction);
if(transaction != null){
WechatPayCallbackPO callbackPO = new WechatPayCallbackPO();
BeanUtil.copyProperties(transaction, callbackPO);
callbackPO.setCreateTime(new Date());
wechatPayCallbackService.save(callbackPO);
}
WechatPayOrderPO order = wechatPayOrderService.findById(transaction.getOutTradeNo());
if(order == null){
StaticLog.error("【微信支付回调】异常:订单不存在");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
switch (transaction.getTradeState()){
case SUCCESS:
order.setWechatOrderId(transaction.getTransactionId());
order.setPayTime(DateUtil.parseUTC(transaction.getSuccessTime()));
order.setPayStatus(WechatPayOrderStatusEnum.支付成功);
StaticLog.info("【微信支付回调】订单:{}=支付成功",order.getWechatOrderId());
if(order.getBusiness() != null){
switch (order.getBusiness()){
case 订货订单:
OrderDetailPO orderDetail = orderDetailService.findById(order.getBusinessId());
if(orderDetail == null){
StaticLog.error("【微信支付回调】异常:订货订单不存在");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
orderDetail.setOrderPayAmount(order.getPayAmount());
orderDetail.setAmountReceivable(order.getPayAmount());
orderDetail.setConfirmStatus(OrderStatusEnum.审核通过);
orderDetailService.save(orderDetail);
StaticLog.info("【微信支付回调】订货订单:{}=更新成功",orderDetail.getOrderCode());
break;
default:
break;
}
}
break;
case NOTPAY:
order.setPayStatus(WechatPayOrderStatusEnum.未支付);
StaticLog.info("【微信支付回调】订单:{}=未支付",order.getWechatOrderId());
break;
case CLOSED:
order.setPayStatus(WechatPayOrderStatusEnum.已关闭);
StaticLog.info("【微信支付回调】订单:{}=已关闭",order.getWechatOrderId());
break;
case PAYERROR:
order.setPayStatus(WechatPayOrderStatusEnum.支付失败);
StaticLog.info("【微信支付回调】订单:{}=支付失败",order.getWechatOrderId());
break;
}
wechatPayOrderService.save(order);
} catch (ValidationException e) {
// 签名验证失败,返回 401 UNAUTHORIZED 状态码
e.printStackTrace();
return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
}
// 处理成功,返回 200 OK 状态码
return ResponseEntity.status(HttpStatus.OK);
}