diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/DefaultPayFilterChain.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/DefaultPayFilterChain.java deleted file mode 100644 index d688bfb..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/DefaultPayFilterChain.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.enongm.dianji.payment.wechat.v3; - - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Dax - * @since 16:16 - */ -public class DefaultPayFilterChain implements PayFilterChain { - private int pos = 0; - private final List filters = new ArrayList<>(); - - @Override - public void register(PayFilter filter) { - filters.add(filter); - } - - @Override - public void doChain(WechatRequestEntity requestEntity) { - int size = filters.size(); - if (pos < size) { - PayFilter payFilter = filters.get(pos++); - payFilter.doFilter(requestEntity, this); - } - } - -} diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilter.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilter.java deleted file mode 100644 index aae5799..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilter.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.enongm.dianji.payment.wechat.v3; - - -/** - * The interface Pay filter. - * - * @author Dax - * @since 15 :08 - */ -public interface PayFilter { - - /** - * Do filter. - * @param requestEntity the request entity - * @param chain the chain*/ - void doFilter(WechatRequestEntity requestEntity, PayFilterChain chain); - -} diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilterChain.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilterChain.java deleted file mode 100644 index 0930b9f..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/PayFilterChain.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.enongm.dianji.payment.wechat.v3; - - -/** - * The interface Pay filter chain. - * - * @author Dax - * @since 16 :11 - */ -public interface PayFilterChain { - - /** - * Do chain. - * - * @param requestEntity the request entity - */ - void doChain(WechatRequestEntity requestEntity); - - /** - * Register. - * - * @param filter the filter - */ - void register(PayFilter filter); -} diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/WechatPayClient.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/WechatPayClient.java index 7431c80..104bc03 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/WechatPayClient.java +++ b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/WechatPayClient.java @@ -1,14 +1,21 @@ package com.enongm.dianji.payment.wechat.v3; +import com.enongm.dianji.payment.PayException; +import com.enongm.dianji.payment.wechat.WechatPayResponseErrorHandler; import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type; -import com.enongm.dianji.payment.wechat.v3.filter.HeaderFilter; -import com.enongm.dianji.payment.wechat.v3.filter.HttpRequestFilter; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.SneakyThrows; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; +import org.springframework.util.Assert; +import org.springframework.web.client.DefaultResponseErrorHandler; +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 java.util.Collections; +import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -19,7 +26,7 @@ import java.util.function.Consumer; * @since 11 :43 */ public class WechatPayClient { - private final PayFilterChain payFilterChain; + private final SignatureProvider signatureProvider; /** * Instantiates a new Wechat pay service. @@ -27,12 +34,7 @@ public class WechatPayClient { * @param signatureProvider the signature provider */ public WechatPayClient(SignatureProvider signatureProvider) { - DefaultPayFilterChain defaultPayFilterChain = new DefaultPayFilterChain(); - // 构造私钥签名 - defaultPayFilterChain.register(new HeaderFilter(signatureProvider)); - // 向微信支付服务器发起请求 - defaultPayFilterChain.register(new HttpRequestFilter(signatureProvider)); - this.payFilterChain = defaultPayFilterChain; + this.signatureProvider = signatureProvider; } @@ -45,7 +47,7 @@ public class WechatPayClient { * @return the executor */ public Executor withType(WechatPayV3Type wechatPayV3Type, M m) { - return new Executor<>(wechatPayV3Type,m ,this.payFilterChain); + return new Executor<>(wechatPayV3Type, m, this.signatureProvider); } @@ -59,11 +61,8 @@ public class WechatPayClient { * The V 3 pay type. */ private final WechatPayV3Type wechatPayV3Type; - - /** - * The Pay filter chain. - */ - private final PayFilterChain payFilterChain; + private final RestOperations restOperations; + private final SignatureProvider signatureProvider; private final M model; /** @@ -74,21 +73,25 @@ public class WechatPayClient { /** * The Response body consumer. */ - private Consumer> responseBodyConsumer; + private Consumer> responseBodyConsumer; /** * Instantiates a new Executor. * - * @param wechatPayV3Type the v 3 pay type - * @param model the model - * @param payFilterChain the pay filter chain + * @param wechatPayV3Type the v 3 pay type + * @param model the model + * @param signatureProvider the signature provider */ public Executor(WechatPayV3Type wechatPayV3Type, M model, - PayFilterChain payFilterChain) { + SignatureProvider signatureProvider) { this.wechatPayV3Type = wechatPayV3Type; this.model = model; - this.payFilterChain = payFilterChain; + this.signatureProvider = signatureProvider; + RestTemplate restTemplate = new RestTemplate(); + DefaultResponseErrorHandler errorHandler = new WechatPayResponseErrorHandler(); + restTemplate.setErrorHandler(errorHandler); + this.restOperations = restTemplate; } /** @@ -120,8 +123,83 @@ public class WechatPayClient { @SneakyThrows public void request() { RequestEntity requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model); - payFilterChain.doChain(WechatRequestEntity.of(requestEntity, this.responseBodyConsumer)); + WechatRequestEntity wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer); + this.doExecute(this.header(wechatRequestEntity)); } + + + /** + * 构造私钥签名. + * + * @param the type parameter + * @param requestEntity the request entity + */ + private WechatRequestEntity header(WechatRequestEntity requestEntity) { + + UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build(); + String canonicalUrl = uri.getPath(); + String encodedQuery = uri.getQuery(); + + if (encodedQuery != null) { + canonicalUrl += "?" + encodedQuery; + } + // 签名 + HttpMethod httpMethod = requestEntity.getMethod(); + Assert.notNull(httpMethod, "httpMethod is required"); + + String body = requestEntity.hasBody() ? Objects.requireNonNull(requestEntity.getBody()).toString() : ""; + String authorization = signatureProvider.requestSign(httpMethod.name(), canonicalUrl, body); + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.addAll(requestEntity.getHeaders()); + httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + // 兼容图片上传,自定义优先级最高 + if (Objects.isNull(httpHeaders.getContentType())) { + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + } + httpHeaders.add("Authorization", authorization); + httpHeaders.add("User-Agent", "X-Pay-Service"); + + return requestEntity.headers(httpHeaders); + + } + + + private void doExecute(WechatRequestEntity requestEntity) { + + ResponseEntity responseEntity = restOperations.exchange(requestEntity, ObjectNode.class); + HttpHeaders headers = responseEntity.getHeaders(); + ObjectNode body = responseEntity.getBody(); + + if (Objects.isNull(body)) { + throw new IllegalStateException("cant obtain response body"); + } + // 微信请求回调id + // String RequestId = response.header("Request-ID"); + // 微信平台证书序列号 用来取微信平台证书 + String wechatpaySerial = headers.getFirst("Wechatpay-Serial"); + //获取应答签名 + String wechatpaySignature = headers.getFirst("Wechatpay-Signature"); + //构造验签名串 + String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp"); + String wechatpayNonce = headers.getFirst("Wechatpay-Nonce"); + + // 验证微信服务器签名 + if (signatureProvider.responseSignVerify(wechatpaySerial, + wechatpaySignature, + wechatpayTimestamp, + wechatpayNonce, + body.toString())) { + Consumer> responseConsumer = requestEntity.getResponseBodyConsumer(); + if (Objects.nonNull(responseConsumer)) { + // 验证通过消费 + responseConsumer.accept(responseEntity); + } + } else { + throw new PayException("wechat pay signature failed"); + } + } + } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HeaderFilter.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HeaderFilter.java deleted file mode 100644 index d977441..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HeaderFilter.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.enongm.dianji.payment.wechat.v3.filter; - - -import com.enongm.dianji.payment.wechat.v3.PayFilter; -import com.enongm.dianji.payment.wechat.v3.PayFilterChain; -import com.enongm.dianji.payment.wechat.v3.SignatureProvider; -import com.enongm.dianji.payment.wechat.v3.WechatRequestEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.util.Assert; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -import java.util.Collections; -import java.util.Objects; - -/** - * 微信支付 给请求添加必要的请求头. - * 3 - * - * @author Dax - * @since 15 :12 - */ -public class HeaderFilter implements PayFilter { - private final SignatureProvider signatureProvider; - - public HeaderFilter(SignatureProvider signatureProvider) { - this.signatureProvider = signatureProvider; - } - - @Override - public void doFilter(WechatRequestEntity requestEntity, PayFilterChain chain) { - - UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build(); - String canonicalUrl = uri.getPath(); - String encodedQuery = uri.getQuery(); - - if (encodedQuery != null) { - canonicalUrl += "?" + encodedQuery; - } - // 签名 - HttpMethod httpMethod = requestEntity.getMethod(); - Assert.notNull(httpMethod, "httpMethod is required"); - - String body = requestEntity.hasBody() ? Objects.requireNonNull(requestEntity.getBody()).toString() : ""; - String authorization = signatureProvider.requestSign(httpMethod.name(), canonicalUrl, body); - - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.addAll(requestEntity.getHeaders()); - httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - // 兼容图片上传,自定义优先级最高 - if (Objects.isNull(httpHeaders.getContentType())) { - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - } - httpHeaders.add("Authorization", authorization); - httpHeaders.add("User-Agent", "X-Pay-Service"); - - chain.doChain(requestEntity.headers(httpHeaders)); - } - - -} diff --git a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HttpRequestFilter.java b/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HttpRequestFilter.java deleted file mode 100644 index c3cc5ba..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/com/enongm/dianji/payment/wechat/v3/filter/HttpRequestFilter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.enongm.dianji.payment.wechat.v3.filter; - - -import com.enongm.dianji.payment.PayException; -import com.enongm.dianji.payment.wechat.WechatPayResponseErrorHandler; -import com.enongm.dianji.payment.wechat.v3.PayFilter; -import com.enongm.dianji.payment.wechat.v3.PayFilterChain; -import com.enongm.dianji.payment.wechat.v3.SignatureProvider; -import com.enongm.dianji.payment.wechat.v3.WechatRequestEntity; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestOperations; -import org.springframework.web.client.RestTemplate; - -import java.util.Objects; -import java.util.function.Consumer; - -/** - * 微信支付用来请求微信支付服务器 - * - * @author Dax - * @since 10:42 - */ -@Slf4j -public class HttpRequestFilter implements PayFilter { - private final RestOperations restOperations; - private final SignatureProvider signatureProvider; - - - public HttpRequestFilter(SignatureProvider signatureProvider) { - this.signatureProvider = signatureProvider; - RestTemplate restTemplate = new RestTemplate(); - DefaultResponseErrorHandler errorHandler = new WechatPayResponseErrorHandler(); - restTemplate.setErrorHandler(errorHandler); - this.restOperations = restTemplate; - } - - @Override - public void doFilter(WechatRequestEntity requestEntity, PayFilterChain chain) { - - ResponseEntity responseEntity = restOperations.exchange(requestEntity, ObjectNode.class); - HttpHeaders headers = responseEntity.getHeaders(); - ObjectNode body = responseEntity.getBody(); - - if (Objects.isNull(body)) { - throw new IllegalStateException("cant obtain response body"); - } - // 微信请求回调id - // String RequestId = response.header("Request-ID"); - // 微信平台证书序列号 用来取微信平台证书 - String wechatpaySerial = headers.getFirst("Wechatpay-Serial"); - //获取应答签名 - String wechatpaySignature = headers.getFirst("Wechatpay-Signature"); - //构造验签名串 - String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp"); - String wechatpayNonce = headers.getFirst("Wechatpay-Nonce"); - - // 验证微信服务器签名 - if (signatureProvider.responseSignVerify(wechatpaySerial, - wechatpaySignature, - wechatpayTimestamp, - wechatpayNonce, - body.toString())) { - Consumer> responseConsumer = requestEntity.getResponseBodyConsumer(); - if (Objects.nonNull(responseConsumer)) { - // 验证通过消费 - responseConsumer.accept(responseEntity); - } - } else { - throw new PayException("wechat pay signature failed"); - } - } -} diff --git a/pom.xml b/pom.xml index 1d8ca0b..fbecff3 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ UTF-8 UTF-8 1.8 - 2.3.4.RELEASE + 2.1.14.RELEASE 4.10.167.ALL 1.0.0.RELEASE 1.18.12