diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/InMemoryWechatTenantService.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/InMemoryWechatTenantService.java index e35272b..a43b186 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/InMemoryWechatTenantService.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/InMemoryWechatTenantService.java @@ -23,8 +23,10 @@ import lombok.AllArgsConstructor; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import org.springframework.util.CollectionUtils; import org.springframework.util.ResourceUtils; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -39,27 +41,32 @@ import java.util.stream.Collectors; public class InMemoryWechatTenantService implements WechatTenantService { private final WechatPayProperties wechatPayProperties; private final ResourceLoader resourceLoader; + private final Set cache = new HashSet<>(); @Override public Set loadTenants() { - Map v3Map = wechatPayProperties.getV3(); - KeyPairFactory keyPairFactory = new KeyPairFactory(); - return v3Map.entrySet() - .stream() - .map(entry -> { - WechatPayProperties.V3 v3 = entry.getValue(); - String tenantId = entry.getKey(); - String certPath = v3.getCertPath(); - String certAbsolutePath = v3.getCertAbsolutePath(); - String mchId = v3.getMchId(); - Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) : - resourceLoader.getResource(certPath == null ? "classpath:wechat/apiclient_cert.p12" : - certPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? certPath : ResourceUtils.CLASSPATH_URL_PREFIX + certPath); - WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, mchId); - wechatMetaBean.setV3(v3); - wechatMetaBean.setTenantId(tenantId); - return wechatMetaBean; - }) - .collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(cache)) { + Map v3Map = wechatPayProperties.getV3(); + KeyPairFactory keyPairFactory = new KeyPairFactory(); + Set beans = v3Map.entrySet() + .stream() + .map(entry -> { + WechatPayProperties.V3 v3 = entry.getValue(); + String tenantId = entry.getKey(); + String certPath = v3.getCertPath(); + String certAbsolutePath = v3.getCertAbsolutePath(); + String mchId = v3.getMchId(); + Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) : + resourceLoader.getResource(certPath == null ? "classpath:wechat/apiclient_cert.p12" : + certPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? certPath : ResourceUtils.CLASSPATH_URL_PREFIX + certPath); + WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, mchId); + wechatMetaBean.setV3(v3); + wechatMetaBean.setTenantId(tenantId); + return wechatMetaBean; + }) + .collect(Collectors.toSet()); + cache.addAll(beans); + } + return cache; } } 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 2a88ef8..c683574 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 @@ -27,11 +27,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.util.AlternativeJdkIdGenerator; @@ -54,8 +50,7 @@ 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.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -135,7 +130,7 @@ public class SignatureProvider { @SneakyThrows public String requestSign(String tenantId, String method, String canonicalUrl, String body) { - long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")); + long timestamp = Instant.now().getEpochSecond(); String nonceStr = nonceStrGenerator.generateId() .toString() .replaceAll("-", ""); @@ -175,7 +170,6 @@ public class SignatureProvider { * @param params the params * @return the boolean */ - @SneakyThrows public boolean responseSignVerify(ResponseSignVerifyParams params) { String wechatpaySerial = params.getWechatpaySerial(); @@ -190,13 +184,15 @@ public class SignatureProvider { .orElseThrow(() -> new PayException("cannot obtain the certificate")); }); - - final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody()); - Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER); - signer.initVerify(certificate.getX509Certificate()); - signer.update(signatureStr.getBytes(StandardCharsets.UTF_8)); - - return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature())); + try { + final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody()); + Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER); + signer.initVerify(certificate.getX509Certificate()); + signer.update(signatureStr.getBytes(StandardCharsets.UTF_8)); + return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature())); + }catch (Exception e){ + throw new PayException("An exception occurred during the response verification, the cause: "+e.getMessage()); + } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMetaContainer.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMetaContainer.java index d82c0ca..f9e7def 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMetaContainer.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMetaContainer.java @@ -20,9 +20,12 @@ package cn.felord.payment.wechat.v3; import cn.felord.payment.wechat.WechatTenantService; import lombok.AllArgsConstructor; -import java.util.*; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; +import java.util.stream.Collectors; /** * 配置容器 @@ -33,7 +36,6 @@ import java.util.concurrent.ConcurrentSkipListSet; @AllArgsConstructor public class WechatMetaContainer { private final Map wechatMetaBeanMap = new ConcurrentHashMap<>(); - private final Set tenantIds = new ConcurrentSkipListSet<>(); private final WechatTenantService wechatTenantService; /** @@ -47,22 +49,9 @@ public class WechatMetaContainer { private void addMeta(WechatMetaBean wechatMetaBean) { String tenantId = wechatMetaBean.getTenantId(); - tenantIds.add(tenantId); wechatMetaBeanMap.put(tenantId, wechatMetaBean); } - - /** - * Remove wechat meta wechat meta bean. - * - * @param tenantId the tenantId - * @return the wechat meta bean - */ - public WechatMetaBean removeWechatMeta(String tenantId) { - tenantIds.remove(tenantId); - return this.wechatMetaBeanMap.remove(tenantId); - } - /** * Gets wechat meta. * @@ -86,6 +75,9 @@ public class WechatMetaContainer { * @return the properties keys */ public Set getTenantIds() { - return tenantIds; + return wechatTenantService.loadTenants() + .stream() + .map(WechatMetaBean::getTenantId) + .collect(Collectors.toSet()); } }