refactor: 现在app支付、小程序支付返回所有客户端拉起支付的参数,不再需要用户再进行签名操作了

This commit is contained in:
felord.cn
2021-01-11 14:32:07 +08:00
parent b10e2702ce
commit edbf4dcbc7
2 changed files with 109 additions and 12 deletions

View File

@@ -70,7 +70,7 @@ public class SignatureProvider {
/** /**
* The constant ID_GENERATOR. * The constant ID_GENERATOR.
*/ */
private static final IdGenerator ID_GENERATOR = new AlternativeJdkIdGenerator(); private final IdGenerator nonceStrGenerator = new AlternativeJdkIdGenerator();
/** /**
* The constant SCHEMA. * The constant SCHEMA.
*/ */
@@ -114,18 +114,14 @@ 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) {
Signature signer = Signature.getInstance("SHA256withRSA");
WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId);
signer.initSign(wechatMetaBean.getKeyPair().getPrivate());
long timestamp = System.currentTimeMillis() / 1000; long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = ID_GENERATOR.generateId() String nonceStr = nonceStrGenerator.generateId()
.toString() .toString()
.replaceAll("-", ""); .replaceAll("-", "");
final String signatureStr = createSign(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body); WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId);
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8)); PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate();
String encode = Base64Utils.encodeToString(signer.sign()); String encode = this.doRequestSign(privateKey, method, canonicalUrl, String.valueOf(timestamp), nonceStr, body);
// 序列号 // 序列号
String serialNo = wechatMetaBean.getSerialNumber(); String serialNo = wechatMetaBean.getSerialNumber();
// 生成token // 生成token
@@ -135,6 +131,24 @@ public class SignatureProvider {
return SCHEMA.concat(token); return SCHEMA.concat(token);
} }
/**
* Do request sign.
*
* @param privateKey the private key
* @param orderedComponents the orderedComponents
* @return the string
* @since 1.0.4.RELEASE
*/
@SneakyThrows
public String doRequestSign(PrivateKey privateKey, String... orderedComponents) {
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(privateKey);
final String signatureStr = createSign(orderedComponents);
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
return Base64Utils.encodeToString(signer.sign());
}
/** /**
* 我方对响应验签,和应答签名做比较,使用微信平台证书. * 我方对响应验签,和应答签名做比较,使用微信平台证书.
* *
@@ -257,6 +271,16 @@ public class SignatureProvider {
return wechatMetaContainer; return wechatMetaContainer;
} }
/**
* Nonce generator.
*
* @return the id generator
* @since 1.0.4.RELEASE
*/
public IdGenerator nonceStrGenerator() {
return nonceStrGenerator;
}
/** /**
* 请求时设置签名 组件 * 请求时设置签名 组件
* *

View File

@@ -18,18 +18,22 @@
*/ */
package cn.felord.payment.wechat.v3; package cn.felord.payment.wechat.v3;
import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.PayException;
import cn.felord.payment.wechat.WechatPayProperties; import cn.felord.payment.wechat.WechatPayProperties;
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.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;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI; import java.net.URI;
import java.security.PrivateKey;
import java.util.Objects;
/** /**
* 普通支付-直连模式. * 普通支付-直连模式.
@@ -59,7 +63,43 @@ public class WechatDirectPayApi extends AbstractApi {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>(); WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.APP, payParams) this.client().withType(WechatPayV3Type.APP, payParams)
.function(this::payFunction) .function(this::payFunction)
.consumer(wechatResponseEntity::convert) .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);
}
wechatResponseEntity.setHttpStatus(httpStatus);
wechatResponseEntity.setBody(body);
})
.request(); .request();
return wechatResponseEntity; return wechatResponseEntity;
} }
@@ -74,7 +114,40 @@ public class WechatDirectPayApi extends AbstractApi {
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>(); WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
this.client().withType(WechatPayV3Type.JSAPI, payParams) this.client().withType(WechatPayV3Type.JSAPI, payParams)
.function(this::payFunction) .function(this::payFunction)
.consumer(wechatResponseEntity::convert) .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);
}
wechatResponseEntity.setHttpStatus(httpStatus);
wechatResponseEntity.setBody(body);
})
.request(); .request();
return wechatResponseEntity; return wechatResponseEntity;
} }