mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-14 05:43:46 +08:00
移除过滤器
This commit is contained in:
@@ -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<PayFilter> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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*/
|
||||
<T> void doFilter(WechatRequestEntity<T> requestEntity, PayFilterChain chain);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 <M> Executor<M> 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<ResponseEntity<ObjectNode>> responseBodyConsumer;
|
||||
private Consumer<ResponseEntity<ObjectNode>> 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 <T> the type parameter
|
||||
* @param requestEntity the request entity
|
||||
*/
|
||||
private <T> WechatRequestEntity<T> header(WechatRequestEntity<T> 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 <T> void doExecute(WechatRequestEntity<T> requestEntity) {
|
||||
|
||||
ResponseEntity<ObjectNode> 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<ResponseEntity<ObjectNode>> responseConsumer = requestEntity.getResponseBodyConsumer();
|
||||
if (Objects.nonNull(responseConsumer)) {
|
||||
// 验证通过消费
|
||||
responseConsumer.accept(responseEntity);
|
||||
}
|
||||
} else {
|
||||
throw new PayException("wechat pay signature failed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 <T> void doFilter(WechatRequestEntity<T> 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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 <T> void doFilter(WechatRequestEntity<T> requestEntity, PayFilterChain chain) {
|
||||
|
||||
ResponseEntity<ObjectNode> 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<ResponseEntity<ObjectNode>> responseConsumer = requestEntity.getResponseBodyConsumer();
|
||||
if (Objects.nonNull(responseConsumer)) {
|
||||
// 验证通过消费
|
||||
responseConsumer.accept(responseEntity);
|
||||
}
|
||||
} else {
|
||||
throw new PayException("wechat pay signature failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@@ -22,7 +22,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-boot.version>2.3.4.RELEASE</spring-boot.version>
|
||||
<spring-boot.version>2.1.14.RELEASE</spring-boot.version>
|
||||
<aliy-pay-sdk.version>4.10.167.ALL</aliy-pay-sdk.version>
|
||||
<oss-starter.version>1.0.0.RELEASE</oss-starter.version>
|
||||
<lombok.verison>1.18.12</lombok.verison>
|
||||
|
||||
Reference in New Issue
Block a user