支付模块-下单接口修改以及支付结果回溯接口修改

This commit is contained in:
2024-12-26 10:20:18 +08:00
parent 4760dba312
commit efd0fa1e44
18 changed files with 498 additions and 222 deletions

View File

@ -1,6 +1,6 @@
package com.fastbee.common.utils.pay;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@ -10,37 +10,26 @@ import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author xy-peng
*/
public class AesUtil {
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final int KEY_LENGTH_BYTE = 32;
private static final int TAG_LENGTH_BIT = 128;
static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;
private final byte[] aesKey;
public AesUtil(byte[] key) {
if (key.length != KEY_LENGTH_BYTE) {
throw new IllegalArgumentException("无效的ApiV3Key长度必须为32个字节");
}
this.aesKey = key;
}
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
throws GeneralSecurityException {
throws GeneralSecurityException, IOException {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
cipher.updateAAD(associatedData);
return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);
String result=new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
return result;
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(e);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {

View File

@ -0,0 +1,51 @@
package com.fastbee.common.utils.pay;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil {
/**
* 验签方法
* @param wechatpaySignature Wechatpay-Signature 响应头中的签名
* @param wechatpayTimestamp Wechatpay-Timestamp 响应头中的时间戳
* @param wechatpayNonce Wechatpay-Nonce 响应头中的随机串
* @param responseBody 应答报文主体
* @param publicKey 微信支付公钥PEM 格式,去掉头尾并解码为二进制)
* @return 是否验签成功
* @throws Exception
*/
public static boolean verifySignature(String wechatpaySignature,
String wechatpayTimestamp,
String wechatpayNonce,
String responseBody,
String publicKey) throws Exception {
// 构造验签名串:应答时间戳\n应答随机串\n应答报文主体\n
String message = wechatpayTimestamp + "\n" +
wechatpayNonce + "\n" +
responseBody + "\n";
// 解码微信支付公钥Base64 格式)
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey rsaPublicKey = keyFactory.generatePublic(keySpec);
// 初始化 Signature 对象,指定算法为 SHA256withRSA
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(rsaPublicKey);
// 更新验签名串
signature.update(message.getBytes(StandardCharsets.UTF_8));
// 验证签名
byte[] signatureBytes = Base64.getDecoder().decode(wechatpaySignature);
return signature.verify(signatureBytes);
}
}

View File

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4zej1cqugGQtVSY2Ah8RMCKcr2UpZ8Npo+5Ja9xpFPYkWHaF1Gjrn3d5kcwAFuHHcfdc3yxDYx6+9grvJnCA2zQzWjzVRa3BJ5LTMj6yqvhEmtvjO9D1xbFTA2m3kyjxlaIar/RYHZSslT4VmjIatW9KJCDKkwpM6x/RIWL8wwfFwgz2q3Zcrff1y72nB8p8P12ndH7GSLoY6d2Tv0OB2+We2Kyy2+QzfGXOmLp7UK/pFQjJjzhSf9jxaWJXYKIBxpGlddbRZj9PqvFPTiep8rvfKGNZF9Q6QaMYTpTp/uKQ3YvpDlyeQlYe4rRFauH3mOE6j56QlYQWivknDX9VrwIDAQAB
-----END PUBLIC KEY-----

View File

@ -3,12 +3,28 @@ package com.fastbee.common.utils.pay;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class wxPayConfig {
// 获取微信支付公钥
public static String getPublicKey(String publicKeyPath) {
try {
// 读取私钥文件内容
String publicKeyContent = readFile(publicKeyPath);
// 去除私钥文件中的头尾信息
publicKeyContent = publicKeyContent.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s+", "");
return publicKeyContent;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 获取商户私钥
public static PrivateKey getPrivateKey(String privateKeyPath) {