From c96e0142732d14b6c56e9437b0e95dcc69502c10 Mon Sep 17 00:00:00 2001 From: "felord.cn" Date: Sat, 16 Jan 2021 23:38:29 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=AF=B9=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=B8=80=E4=BA=9B=E9=87=8D=E6=9E=84=E5=92=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20-=20=E8=AF=BB=E5=8F=96=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=90=8E=E5=AF=B9=E6=B5=81=E8=BF=9B=E8=A1=8C=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=20-=20=E4=BB=A3=E9=87=91=E5=88=B8=E3=80=81?= =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=E6=89=B9=E6=AC=A1=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E6=98=AF=E6=9E=9A=E4=B8=BE=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20-=20=E6=97=B6=E9=97=B4=E6=88=B3=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/alipay/AliPayConfiguration.java | 12 +- .../payment/wechat/enumeration/StockType.java | 44 ++++++ .../wechat/enumeration/UnfinishedReason.java | 2 +- .../payment/wechat/v3/SignatureProvider.java | 6 +- .../payment/wechat/v3/WechatDirectPayApi.java | 125 +++++++++--------- .../wechat/v3/model/StocksCreateParams.java | 5 +- 6 files changed, 120 insertions(+), 74 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockType.java diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java index 110f64c..564089c 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/alipay/AliPayConfiguration.java @@ -32,10 +32,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; +import java.io.*; /** * @author felord.cn @@ -78,9 +75,12 @@ public class AliPayConfiguration { private String appRSAPrivateKey(String classPath) { + ClassPathResource resource = new ClassPathResource(classPath); try { - File file = new ClassPathResource(classPath).getFile(); - return new BufferedReader(new FileReader(file)).readLine(); + FileReader in = new FileReader(resource.getFile()); + try(BufferedReader bufferedReader = new BufferedReader(in)){ + return bufferedReader.readLine(); + } } catch (IOException e) { log.error("ali pay app private key is required ,{}", e.getMessage()); throw new PayException("ali pay app private key is required"); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockType.java new file mode 100644 index 0000000..9f9c78f --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockType.java @@ -0,0 +1,44 @@ +/* + * 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.enumeration; + +/** + * 代金券、商家券批次类型 + * + * @author felord.cn + * @since 1.0.4.RELEASE + */ +public enum StockType { + /** + * 固定面额满减券批次 + * + * @since 1.0.4.RELEASE + */ + NORMAL, + /** + * 折扣券批次 + * + * @since 1.0.4.RELEASE + */ + DISCOUNT, + /** + * 换购券批次 + * + * @since 1.0.4.RELEASE + */ + EXCHANGE; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/UnfinishedReason.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/UnfinishedReason.java index f705629..a00692e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/UnfinishedReason.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/UnfinishedReason.java @@ -21,7 +21,7 @@ package cn.felord.payment.wechat.enumeration; * 未完成约定原因 *

* 当订单守约状态为{@link ContractStatus#UNFINISHED},返回此字段 - * + * @author felord.cn * @since 1.0.3.RELEASE */ public enum UnfinishedReason { 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 900ec7c..1397578 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 @@ -19,10 +19,10 @@ package cn.felord.payment.wechat.v3; +import cn.felord.payment.PayException; import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WechatPayV3Type; import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams; -import cn.felord.payment.PayException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -46,6 +46,8 @@ import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Arrays; import java.util.Collections; import java.util.Map; @@ -115,7 +117,7 @@ public class SignatureProvider { @SneakyThrows public String requestSign(String tenantId, String method, String canonicalUrl, String body) { - long timestamp = System.currentTimeMillis() / 1000; + long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")); String nonceStr = nonceStrGenerator.generateId() .toString() .replaceAll("-", ""); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatDirectPayApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatDirectPayApi.java index 64cb11d..c537ab4 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatDirectPayApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatDirectPayApi.java @@ -25,7 +25,6 @@ import cn.felord.payment.wechat.enumeration.WechatPayV3Type; import cn.felord.payment.wechat.v3.model.PayParams; import cn.felord.payment.wechat.v3.model.TransactionQueryParams; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -33,6 +32,8 @@ import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; import java.security.PrivateKey; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Objects; /** @@ -64,40 +65,38 @@ public class WechatDirectPayApi extends AbstractApi { this.client().withType(WechatPayV3Type.APP, payParams) .function(this::payFunction) .consumer(responseEntity -> { - int httpStatus = HttpStatus.BAD_REQUEST.value(); - ObjectNode body = null; - if (Objects.nonNull(responseEntity)) { - httpStatus = responseEntity.getStatusCodeValue(); - body = responseEntity.getBody(); - if (Objects.isNull(body)) { - throw new PayException("response body cannot be resolved"); - } - String timestamp = String.valueOf(System.currentTimeMillis() / 1000); - - SignatureProvider signatureProvider = this.client().signatureProvider(); - String nonceStr = signatureProvider.nonceStrGenerator() - .generateId() - .toString() - .replaceAll("-", ""); - - WechatMetaContainer wechatMetaContainer = signatureProvider.wechatMetaContainer(); - - WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId()); - PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate(); - String appId = wechatMetaBean.getV3().getAppId(); - String prepayId = body.get("prepay_id").asText(); - String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, prepayId); - body.put("appid", appId); - String mchId = wechatMetaBean.getV3().getMchId(); - body.put("partnerid", mchId); - body.put("prepayid", prepayId); - body.put("package", "Sign=WXPay"); - body.put("nonceStr", nonceStr); - body.put("timeStamp", timestamp); - body.put("signType", "RSA"); - body.put("paySign", paySign); + ObjectNode body = responseEntity.getBody(); + if (Objects.isNull(body)) { + throw new PayException("response body cannot be resolved"); } - wechatResponseEntity.setHttpStatus(httpStatus); + + SignatureProvider signatureProvider = this.client().signatureProvider(); + WechatMetaContainer wechatMetaContainer = signatureProvider.wechatMetaContainer(); + WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId()); + PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate(); + + String appId = wechatMetaBean.getV3().getAppId(); + long epochSecond = LocalDateTime.now() + .toEpochSecond(ZoneOffset.of("+8")); + String timestamp = String.valueOf(epochSecond); + String nonceStr = signatureProvider.nonceStrGenerator() + .generateId() + .toString() + .replaceAll("-", ""); + String prepayId = body.get("prepay_id").asText(); + String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, prepayId); + String mchId = wechatMetaBean.getV3().getMchId(); + + body.put("appid", appId); + body.put("partnerid", mchId); + body.put("prepayid", prepayId); + body.put("package", "Sign=WXPay"); + body.put("nonceStr", nonceStr); + body.put("timeStamp", timestamp); + body.put("signType", "RSA"); + body.put("paySign", paySign); + + wechatResponseEntity.setHttpStatus(responseEntity.getStatusCodeValue()); wechatResponseEntity.setBody(body); }) .request(); @@ -115,37 +114,35 @@ public class WechatDirectPayApi extends AbstractApi { this.client().withType(WechatPayV3Type.JSAPI, payParams) .function(this::payFunction) .consumer(responseEntity -> { - int httpStatus = HttpStatus.BAD_REQUEST.value(); - ObjectNode body = null; - if (Objects.nonNull(responseEntity)) { - httpStatus = responseEntity.getStatusCodeValue(); - body = responseEntity.getBody(); - if (Objects.isNull(body)) { - throw new PayException("response body cannot be resolved"); - } - String timestamp = String.valueOf(System.currentTimeMillis() / 1000); - - SignatureProvider signatureProvider = this.client().signatureProvider(); - String nonceStr = signatureProvider.nonceStrGenerator() - .generateId() - .toString() - .replaceAll("-", ""); - - String packageStr = "prepay_id=" + body.get("prepay_id").asText(); - WechatMetaContainer wechatMetaContainer = signatureProvider.wechatMetaContainer(); - - WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId()); - PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate(); - String appId = wechatMetaBean.getV3().getAppId(); - String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, packageStr); - body.put("appId", appId); - body.put("timeStamp", timestamp); - body.put("nonceStr", nonceStr); - body.put("package", packageStr); - body.put("signType", "RSA"); - body.put("paySign", paySign); + ObjectNode body = responseEntity.getBody(); + if (Objects.isNull(body)) { + throw new PayException("response body cannot be resolved"); } - wechatResponseEntity.setHttpStatus(httpStatus); + + SignatureProvider signatureProvider = this.client().signatureProvider(); + WechatMetaContainer wechatMetaContainer = signatureProvider.wechatMetaContainer(); + WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId()); + PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate(); + + String appId = wechatMetaBean.getV3().getAppId(); + long epochSecond = LocalDateTime.now() + .toEpochSecond(ZoneOffset.of("+8")); + String timestamp = String.valueOf(epochSecond); + String nonceStr = signatureProvider.nonceStrGenerator() + .generateId() + .toString() + .replaceAll("-", ""); + String packageStr = "prepay_id=" + body.get("prepay_id").asText(); + String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, packageStr); + + body.put("appId", appId); + body.put("timeStamp", timestamp); + body.put("nonceStr", nonceStr); + body.put("package", packageStr); + body.put("signType", "RSA"); + body.put("paySign", paySign); + + wechatResponseEntity.setHttpStatus(responseEntity.getStatusCodeValue()); wechatResponseEntity.setBody(body); }) .request(); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/StocksCreateParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/StocksCreateParams.java index dae859b..6ae6dee 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/StocksCreateParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/StocksCreateParams.java @@ -17,6 +17,7 @@ */ package cn.felord.payment.wechat.v3.model; +import cn.felord.payment.wechat.enumeration.StockType; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -62,8 +63,10 @@ public class StocksCreateParams { private Boolean noCash; /** * 批次类型 + * + * @since 1.0.4.RELEASE */ - private String stockType = "NORMAL"; + private StockType stockType = StockType.NORMAL; /** * 商户单据号 */