mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-18 07:53:41 +08:00
refactor: 对逻辑进行一些重构和优化
- 读取配置后对流进行关闭操作 - 代金券、优惠券批次类型现在是枚举类型 - 时间戳优化
This commit is contained in:
@@ -32,10 +32,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author felord.cn
|
* @author felord.cn
|
||||||
@@ -78,9 +75,12 @@ public class AliPayConfiguration {
|
|||||||
|
|
||||||
|
|
||||||
private String appRSAPrivateKey(String classPath) {
|
private String appRSAPrivateKey(String classPath) {
|
||||||
|
ClassPathResource resource = new ClassPathResource(classPath);
|
||||||
try {
|
try {
|
||||||
File file = new ClassPathResource(classPath).getFile();
|
FileReader in = new FileReader(resource.getFile());
|
||||||
return new BufferedReader(new FileReader(file)).readLine();
|
try(BufferedReader bufferedReader = new BufferedReader(in)){
|
||||||
|
return bufferedReader.readLine();
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("ali pay app private key is required ,{}", e.getMessage());
|
log.error("ali pay app private key is required ,{}", e.getMessage());
|
||||||
throw new PayException("ali pay app private key is required");
|
throw new PayException("ali pay app private key is required");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ package cn.felord.payment.wechat.enumeration;
|
|||||||
* 未完成约定原因
|
* 未完成约定原因
|
||||||
* <p>
|
* <p>
|
||||||
* 当订单守约状态为{@link ContractStatus#UNFINISHED},返回此字段
|
* 当订单守约状态为{@link ContractStatus#UNFINISHED},返回此字段
|
||||||
*
|
* @author felord.cn
|
||||||
* @since 1.0.3.RELEASE
|
* @since 1.0.3.RELEASE
|
||||||
*/
|
*/
|
||||||
public enum UnfinishedReason {
|
public enum UnfinishedReason {
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
package cn.felord.payment.wechat.v3;
|
package cn.felord.payment.wechat.v3;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.felord.payment.PayException;
|
||||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||||
import cn.felord.payment.PayException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
@@ -46,6 +46,8 @@ import java.security.*;
|
|||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -115,7 +117,7 @@ public class SignatureProvider {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public String requestSign(String tenantId, String method, String canonicalUrl, String body) {
|
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()
|
String nonceStr = nonceStrGenerator.generateId()
|
||||||
.toString()
|
.toString()
|
||||||
.replaceAll("-", "");
|
.replaceAll("-", "");
|
||||||
|
|||||||
@@ -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.PayParams;
|
||||||
import cn.felord.payment.wechat.v3.model.TransactionQueryParams;
|
import cn.felord.payment.wechat.v3.model.TransactionQueryParams;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.RequestEntity;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
@@ -33,6 +32,8 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,40 +65,38 @@ public class WechatDirectPayApi extends AbstractApi {
|
|||||||
this.client().withType(WechatPayV3Type.APP, payParams)
|
this.client().withType(WechatPayV3Type.APP, payParams)
|
||||||
.function(this::payFunction)
|
.function(this::payFunction)
|
||||||
.consumer(responseEntity -> {
|
.consumer(responseEntity -> {
|
||||||
int httpStatus = HttpStatus.BAD_REQUEST.value();
|
ObjectNode body = responseEntity.getBody();
|
||||||
ObjectNode body = null;
|
if (Objects.isNull(body)) {
|
||||||
if (Objects.nonNull(responseEntity)) {
|
throw new PayException("response body cannot be resolved");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
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);
|
wechatResponseEntity.setBody(body);
|
||||||
})
|
})
|
||||||
.request();
|
.request();
|
||||||
@@ -115,37 +114,35 @@ public class WechatDirectPayApi extends AbstractApi {
|
|||||||
this.client().withType(WechatPayV3Type.JSAPI, payParams)
|
this.client().withType(WechatPayV3Type.JSAPI, payParams)
|
||||||
.function(this::payFunction)
|
.function(this::payFunction)
|
||||||
.consumer(responseEntity -> {
|
.consumer(responseEntity -> {
|
||||||
int httpStatus = HttpStatus.BAD_REQUEST.value();
|
ObjectNode body = responseEntity.getBody();
|
||||||
ObjectNode body = null;
|
if (Objects.isNull(body)) {
|
||||||
if (Objects.nonNull(responseEntity)) {
|
throw new PayException("response body cannot be resolved");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
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);
|
wechatResponseEntity.setBody(body);
|
||||||
})
|
})
|
||||||
.request();
|
.request();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package cn.felord.payment.wechat.v3.model;
|
package cn.felord.payment.wechat.v3.model;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.enumeration.StockType;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -62,8 +63,10 @@ public class StocksCreateParams {
|
|||||||
private Boolean noCash;
|
private Boolean noCash;
|
||||||
/**
|
/**
|
||||||
* 批次类型
|
* 批次类型
|
||||||
|
*
|
||||||
|
* @since 1.0.4.RELEASE
|
||||||
*/
|
*/
|
||||||
private String stockType = "NORMAL";
|
private StockType stockType = StockType.NORMAL;
|
||||||
/**
|
/**
|
||||||
* 商户单据号
|
* 商户单据号
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user