From 92104e67ecc57d076558f03903165afff0a9e94b Mon Sep 17 00:00:00 2001 From: "felord.cn" Date: Fri, 5 Feb 2021 09:38:25 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=AF=81=E4=B9=A6=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../felord/payment/wechat/v3/AbstractApi.java | 33 ++++++++++++++- .../payment/wechat/v3/SignatureProvider.java | 22 ++++++---- .../wechat/v3/WechatBatchTransferApi.java | 16 +++++--- .../wechat/v3/X509WechatCertificateInfo.java | 40 +++++++++++++++++++ 4 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/X509WechatCertificateInfo.java diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java index 50e3a8f..94b84f1 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/AbstractApi.java @@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; @@ -155,6 +156,25 @@ public abstract class AbstractApi { } } + /** + * 构建Post请求对象. + * + * @param uri the uri + * @param params the params + * @param httpHeaders the http headers + * @return request entity + */ + protected RequestEntity Post(URI uri, Object params, HttpHeaders httpHeaders) { + try { + return RequestEntity.post(uri) + .header("Pay-TenantId", tenantId) + .headers(httpHeaders) + .body(mapper.writeValueAsString(params)); + } catch (JsonProcessingException e) { + throw new PayException("wechat app pay json failed"); + } + } + /** * 构建Get请求对象. * @@ -165,7 +185,18 @@ public abstract class AbstractApi { return RequestEntity.get(uri).header("Pay-TenantId", tenantId) .build(); } - + /** + * 构建Get请求对象. + * + * @param uri the uri + * @return the request entity + */ + protected RequestEntity Get(URI uri, HttpHeaders httpHeaders) { + return RequestEntity.get(uri) + .header("Pay-TenantId", tenantId) + .headers(httpHeaders) + .build(); + } /** * 对账单内容下载,非流文件。 diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java index 9428498..fb66c98 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java @@ -37,7 +37,6 @@ import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import sun.security.x509.X509CertImpl; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; @@ -46,11 +45,16 @@ import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.security.*; -import java.security.cert.*; import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.time.LocalDateTime; import java.time.ZoneOffset; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -219,7 +223,7 @@ public class SignatureProvider { ArrayNode certificates = bodyObjectNode.withArray("data"); if (certificates.isArray() && certificates.size() > 0) { CERTIFICATE_MAP.clear(); - final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); + final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509",BC_PROVIDER); certificates.forEach(objectNode -> { JsonNode encryptCertificate = objectNode.get("encrypt_certificate"); String associatedData = encryptCertificate.get("associated_data").asText(); @@ -275,6 +279,7 @@ public class SignatureProvider { * 对请求敏感字段进行加密 * * @param message the message + * @param certificate the certificate * @return encrypt message * @since 1.0.6.RELEASE */ @@ -292,12 +297,15 @@ public class SignatureProvider { } } - public X509CertImpl getCertificate(){ + public X509WechatCertificateInfo getCertificate(){ for (String serial : CERTIFICATE_MAP.keySet()) { - X509CertImpl x509Cert = (X509CertImpl) CERTIFICATE_MAP.get(serial); + X509Certificate x509Cert = (X509Certificate) CERTIFICATE_MAP.get(serial); try { x509Cert.checkValidity(); - return x509Cert; + X509WechatCertificateInfo x509WechatCertificateInfo = new X509WechatCertificateInfo(); + x509WechatCertificateInfo.setWechatPaySerial(serial); + x509WechatCertificateInfo.setX509Certificate(x509Cert); + return x509WechatCertificateInfo; } catch (Exception e) { log.warn("the wechat certificate is invalid , {}", e.getMessage()); // Async? diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java index c2d66b6..5cf77af 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatBatchTransferApi.java @@ -24,6 +24,7 @@ import cn.felord.payment.wechat.v3.model.batchtransfer.QueryBatchTransferDetailP import cn.felord.payment.wechat.v3.model.batchtransfer.QueryBatchTransferParams; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; @@ -31,9 +32,9 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.util.UriComponentsBuilder; -import sun.security.x509.X509CertImpl; import java.net.URI; +import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -76,15 +77,16 @@ public class WechatBatchTransferApi extends AbstractApi { List transferDetailList = createBatchTransferParams.getTransferDetailList(); SignatureProvider signatureProvider = this.client().signatureProvider(); - final X509CertImpl certificate = signatureProvider.getCertificate(); + final X509WechatCertificateInfo certificate = signatureProvider.getCertificate(); List encrypted = transferDetailList.stream() .peek(transferDetailListItem -> { String userName = transferDetailListItem.getUserName(); - String encryptedUserName = signatureProvider.encryptRequestMessage(userName, certificate); + X509Certificate x509Certificate = certificate.getX509Certificate(); + String encryptedUserName = signatureProvider.encryptRequestMessage(userName, x509Certificate); transferDetailListItem.setUserName(encryptedUserName); String userIdCard = transferDetailListItem.getUserIdCard(); if (StringUtils.hasText(userIdCard)) { - String encryptedUserIdCard = signatureProvider.encryptRequestMessage(userIdCard, certificate); + String encryptedUserIdCard = signatureProvider.encryptRequestMessage(userIdCard, x509Certificate); transferDetailListItem.setUserIdCard(encryptedUserIdCard); } }).collect(Collectors.toList()); @@ -93,7 +95,9 @@ public class WechatBatchTransferApi extends AbstractApi { URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) .build() .toUri(); - return Post(uri, createBatchTransferParams); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Wechatpay-Serial", certificate.getWechatPaySerial()); + return Post(uri, createBatchTransferParams, httpHeaders); } /** @@ -249,7 +253,7 @@ public class WechatBatchTransferApi extends AbstractApi { .consumer(wechatResponseEntity::convert) .request(); String downloadUrl = wechatResponseEntity.getBody().get("download_url").asText(); - Assert.hasText(downloadUrl,"download url has no text"); + Assert.hasText(downloadUrl, "download url has no text"); return this.billResource(downloadUrl); } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/X509WechatCertificateInfo.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/X509WechatCertificateInfo.java new file mode 100644 index 0000000..7d62e5e --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/X509WechatCertificateInfo.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2021 felord.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * Website: + * https://felord.cn + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.felord.payment.wechat.v3; + +import lombok.Data; + +import java.security.cert.X509Certificate; + +/** + * 微信X509证书 + * + * @author felord.cn + * @since 1.0.6.RELEASE + */ +@Data +public class X509WechatCertificateInfo { + /** + * wechatPaySerial + */ + private String wechatPaySerial; + /** + * X509Certificate + */ + private X509Certificate x509Certificate; +}