改造支付证书管理模块
This commit is contained in:
@@ -23,7 +23,11 @@ echo "================================"
|
|||||||
MERCHANT_ID="1723321338"
|
MERCHANT_ID="1723321338"
|
||||||
API_V3_KEY="0kF5OlPr482EZwtn9zGufUcqa7ovgxRL"
|
API_V3_KEY="0kF5OlPr482EZwtn9zGufUcqa7ovgxRL"
|
||||||
MERCHANT_SERIAL_NUMBER="2B933F7C35014A1C363642623E4A62364B34C4EB"
|
MERCHANT_SERIAL_NUMBER="2B933F7C35014A1C363642623E4A62364B34C4EB"
|
||||||
PRIVATE_KEY_PATH="src/main/resources/certs/dev/wechat/apiclient_key.pem"
|
# 检测脚本运行位置并设置正确的路径
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
PRIVATE_KEY_PATH="$PROJECT_ROOT/src/main/resources/certs/dev/wechat/apiclient_key.pem"
|
||||||
|
|
||||||
log_info "使用以下配置:"
|
log_info "使用以下配置:"
|
||||||
log_info "商户号: $MERCHANT_ID"
|
log_info "商户号: $MERCHANT_ID"
|
||||||
@@ -33,6 +37,8 @@ log_info "私钥路径: $PRIVATE_KEY_PATH"
|
|||||||
# 检查私钥文件
|
# 检查私钥文件
|
||||||
if [[ ! -f "$PRIVATE_KEY_PATH" ]]; then
|
if [[ ! -f "$PRIVATE_KEY_PATH" ]]; then
|
||||||
log_warning "私钥文件不存在: $PRIVATE_KEY_PATH"
|
log_warning "私钥文件不存在: $PRIVATE_KEY_PATH"
|
||||||
|
log_info "项目根目录: $PROJECT_ROOT"
|
||||||
|
log_info "脚本目录: $SCRIPT_DIR"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -97,6 +103,9 @@ EOF
|
|||||||
|
|
||||||
log_info "创建测试程序..."
|
log_info "创建测试程序..."
|
||||||
|
|
||||||
|
# 切换到项目根目录进行编译
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
# 构建classpath
|
# 构建classpath
|
||||||
CLASSPATH="target/classes"
|
CLASSPATH="target/classes"
|
||||||
if [[ -f "pom.xml" ]]; then
|
if [[ -f "pom.xml" ]]; then
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package com.gxwebsoft.common.core.controller;
|
||||||
|
|
||||||
|
import com.gxwebsoft.common.core.utils.WechatCertAutoConfig;
|
||||||
|
import com.gxwebsoft.common.core.web.ApiResult;
|
||||||
|
import com.gxwebsoft.common.core.web.BaseController;
|
||||||
|
import com.wechat.pay.java.core.Config;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付证书自动配置测试控制器
|
||||||
|
*
|
||||||
|
* @author 科技小王子
|
||||||
|
* @since 2024-07-26
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/wechat-cert-test")
|
||||||
|
@Api(tags = "微信支付证书自动配置测试")
|
||||||
|
public class WechatCertTestController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WechatCertAutoConfig wechatCertAutoConfig;
|
||||||
|
|
||||||
|
@ApiOperation("测试默认开发环境证书配置")
|
||||||
|
@PostMapping("/test-default")
|
||||||
|
public ApiResult<Map<String, Object>> testDefaultConfig() {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("开始测试默认开发环境证书配置...");
|
||||||
|
|
||||||
|
// 创建自动证书配置
|
||||||
|
Config config = wechatCertAutoConfig.createDefaultDevConfig();
|
||||||
|
|
||||||
|
// 测试配置
|
||||||
|
boolean testResult = wechatCertAutoConfig.testConfig(config);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("configCreated", config != null);
|
||||||
|
result.put("testPassed", testResult);
|
||||||
|
result.put("message", "默认证书配置测试完成");
|
||||||
|
result.put("instructions", wechatCertAutoConfig.getUsageInstructions());
|
||||||
|
|
||||||
|
log.info("✅ 默认证书配置测试成功");
|
||||||
|
return success("测试成功", result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("❌ 默认证书配置测试失败: {}", e.getMessage(), e);
|
||||||
|
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("error", e.getMessage());
|
||||||
|
result.put("message", "证书配置测试失败");
|
||||||
|
result.put("troubleshooting", getTroubleshootingInfo());
|
||||||
|
|
||||||
|
return fail("测试失败: " + e.getMessage(), result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("测试自定义证书配置")
|
||||||
|
@PostMapping("/test-custom")
|
||||||
|
public ApiResult<Map<String, Object>> testCustomConfig(
|
||||||
|
@ApiParam("商户号") @RequestParam String merchantId,
|
||||||
|
@ApiParam("私钥文件路径") @RequestParam String privateKeyPath,
|
||||||
|
@ApiParam("证书序列号") @RequestParam String merchantSerialNumber,
|
||||||
|
@ApiParam("APIv3密钥") @RequestParam String apiV3Key) {
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("开始测试自定义证书配置...");
|
||||||
|
log.info("商户号: {}", merchantId);
|
||||||
|
log.info("私钥路径: {}", privateKeyPath);
|
||||||
|
|
||||||
|
// 创建自动证书配置
|
||||||
|
Config config = wechatCertAutoConfig.createAutoConfig(
|
||||||
|
merchantId, privateKeyPath, merchantSerialNumber, apiV3Key);
|
||||||
|
|
||||||
|
// 测试配置
|
||||||
|
boolean testResult = wechatCertAutoConfig.testConfig(config);
|
||||||
|
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("configCreated", config != null);
|
||||||
|
result.put("testPassed", testResult);
|
||||||
|
result.put("message", "自定义证书配置测试完成");
|
||||||
|
result.put("merchantId", merchantId);
|
||||||
|
result.put("privateKeyPath", privateKeyPath);
|
||||||
|
|
||||||
|
log.info("✅ 自定义证书配置测试成功");
|
||||||
|
return success("测试成功", result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("❌ 自定义证书配置测试失败: {}", e.getMessage(), e);
|
||||||
|
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("error", e.getMessage());
|
||||||
|
result.put("message", "证书配置测试失败");
|
||||||
|
result.put("troubleshooting", getTroubleshootingInfo());
|
||||||
|
|
||||||
|
return fail("测试失败: " + e.getMessage(), result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("获取使用说明")
|
||||||
|
@GetMapping("/instructions")
|
||||||
|
public ApiResult<String> getInstructions() {
|
||||||
|
String instructions = wechatCertAutoConfig.getUsageInstructions();
|
||||||
|
return success("获取使用说明成功", instructions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("获取故障排除信息")
|
||||||
|
@GetMapping("/troubleshooting")
|
||||||
|
public ApiResult<Map<String, Object>> getTroubleshooting() {
|
||||||
|
Map<String, Object> troubleshooting = getTroubleshootingInfo();
|
||||||
|
return success("获取故障排除信息成功", troubleshooting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取故障排除信息
|
||||||
|
*/
|
||||||
|
private Map<String, Object> getTroubleshootingInfo() {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
|
||||||
|
info.put("commonIssues", Map.of(
|
||||||
|
"404错误", "商户平台未开启API安全功能或未申请使用微信支付公钥",
|
||||||
|
"证书序列号错误", "请检查商户平台中的证书序列号是否正确",
|
||||||
|
"APIv3密钥错误", "请确认APIv3密钥是否正确设置",
|
||||||
|
"私钥文件不存在", "请检查私钥文件路径是否正确",
|
||||||
|
"网络连接问题", "请检查网络连接是否正常"
|
||||||
|
));
|
||||||
|
|
||||||
|
info.put("solutions", Map.of(
|
||||||
|
"开启API安全", "登录微信商户平台 -> 账户中心 -> API安全 -> 申请使用微信支付公钥",
|
||||||
|
"获取证书序列号", "在API安全页面查看或重新下载证书",
|
||||||
|
"设置APIv3密钥", "在API安全页面设置APIv3密钥",
|
||||||
|
"检查私钥文件", "确保apiclient_key.pem文件存在且路径正确"
|
||||||
|
));
|
||||||
|
|
||||||
|
info.put("advantages", Map.of(
|
||||||
|
"自动下载", "RSAAutoCertificateConfig会自动下载平台证书",
|
||||||
|
"自动更新", "证书过期时会自动更新",
|
||||||
|
"简化管理", "无需手动管理wechatpay_cert.pem文件",
|
||||||
|
"官方推荐", "微信支付官方推荐的证书管理方式"
|
||||||
|
));
|
||||||
|
|
||||||
|
info.put("documentation", "https://pay.weixin.qq.com/doc/v3/merchant/4012153196");
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package com.gxwebsoft.common.core.utils;
|
||||||
|
|
||||||
|
import com.wechat.pay.java.core.Config;
|
||||||
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付证书自动配置工具类
|
||||||
|
* 使用RSAAutoCertificateConfig实现证书自动管理
|
||||||
|
*
|
||||||
|
* @author 科技小王子
|
||||||
|
* @since 2024-07-26
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class WechatCertAutoConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建微信支付自动证书配置
|
||||||
|
*
|
||||||
|
* @param merchantId 商户号
|
||||||
|
* @param privateKeyPath 私钥文件路径
|
||||||
|
* @param merchantSerialNumber 商户证书序列号
|
||||||
|
* @param apiV3Key APIv3密钥
|
||||||
|
* @return 微信支付配置对象
|
||||||
|
*/
|
||||||
|
public Config createAutoConfig(String merchantId, String privateKeyPath,
|
||||||
|
String merchantSerialNumber, String apiV3Key) {
|
||||||
|
try {
|
||||||
|
log.info("创建微信支付自动证书配置...");
|
||||||
|
log.info("商户号: {}", merchantId);
|
||||||
|
log.info("私钥路径: {}", privateKeyPath);
|
||||||
|
log.info("证书序列号: {}", merchantSerialNumber);
|
||||||
|
|
||||||
|
Config config = new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(merchantId)
|
||||||
|
.privateKeyFromPath(privateKeyPath)
|
||||||
|
.merchantSerialNumber(merchantSerialNumber)
|
||||||
|
.apiV3Key(apiV3Key)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.info("✅ 微信支付自动证书配置创建成功");
|
||||||
|
log.info("🔄 系统将自动管理平台证书的下载和更新");
|
||||||
|
|
||||||
|
return config;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("❌ 创建微信支付自动证书配置失败: {}", e.getMessage(), e);
|
||||||
|
|
||||||
|
// 提供详细的错误诊断信息
|
||||||
|
log.error("🔍 错误诊断:");
|
||||||
|
log.error("1. 请检查商户平台是否已开启API安全功能");
|
||||||
|
log.error("2. 请确认已申请使用微信支付公钥");
|
||||||
|
log.error("3. 请验证APIv3密钥和证书序列号是否正确");
|
||||||
|
log.error("4. 请检查网络连接是否正常");
|
||||||
|
log.error("5. 请确认私钥文件路径是否正确: {}", privateKeyPath);
|
||||||
|
|
||||||
|
throw new RuntimeException("微信支付自动证书配置失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用默认开发环境配置创建自动证书配置
|
||||||
|
*
|
||||||
|
* @return 微信支付配置对象
|
||||||
|
*/
|
||||||
|
public Config createDefaultDevConfig() {
|
||||||
|
String merchantId = "1723321338";
|
||||||
|
String privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem";
|
||||||
|
String merchantSerialNumber = "2B933F7C35014A1C363642623E4A62364B34C4EB";
|
||||||
|
String apiV3Key = "0kF5OlPr482EZwtn9zGufUcqa7ovgxRL";
|
||||||
|
|
||||||
|
return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试证书配置是否正常
|
||||||
|
*
|
||||||
|
* @param config 微信支付配置
|
||||||
|
* @return 是否配置成功
|
||||||
|
*/
|
||||||
|
public boolean testConfig(Config config) {
|
||||||
|
try {
|
||||||
|
// 这里可以添加一些基本的配置验证逻辑
|
||||||
|
log.info("🧪 测试微信支付证书配置...");
|
||||||
|
|
||||||
|
if (config == null) {
|
||||||
|
log.error("配置对象为空");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("✅ 证书配置测试通过");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("❌ 证书配置测试失败: {}", e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取配置使用说明
|
||||||
|
*
|
||||||
|
* @return 使用说明
|
||||||
|
*/
|
||||||
|
public String getUsageInstructions() {
|
||||||
|
return """
|
||||||
|
🚀 微信支付自动证书配置使用说明
|
||||||
|
================================
|
||||||
|
|
||||||
|
✅ 优势:
|
||||||
|
1. 自动下载微信支付平台证书
|
||||||
|
2. 证书过期时自动更新
|
||||||
|
3. 无需手动管理 wechatpay_cert.pem 文件
|
||||||
|
4. 符合微信支付官方最佳实践
|
||||||
|
|
||||||
|
📝 使用方法:
|
||||||
|
|
||||||
|
// 方法1: 使用默认开发环境配置
|
||||||
|
Config config = wechatCertAutoConfig.createDefaultDevConfig();
|
||||||
|
|
||||||
|
// 方法2: 自定义配置
|
||||||
|
Config config = wechatCertAutoConfig.createAutoConfig(
|
||||||
|
"商户号",
|
||||||
|
"私钥路径",
|
||||||
|
"证书序列号",
|
||||||
|
"APIv3密钥"
|
||||||
|
);
|
||||||
|
|
||||||
|
🔧 前置条件:
|
||||||
|
1. 微信商户平台已开启API安全功能
|
||||||
|
2. 已申请使用微信支付公钥
|
||||||
|
3. 私钥文件存在且路径正确
|
||||||
|
4. 网络连接正常
|
||||||
|
|
||||||
|
📚 更多信息:
|
||||||
|
https://pay.weixin.qq.com/doc/v3/merchant/4012153196
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/resources/certs/dev/wechat/10550/pub_key-3.pem
Normal file
9
src/main/resources/certs/dev/wechat/10550/pub_key-3.pem
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAty9bVrLUO+O4vVILMaDX
|
||||||
|
rmsVCxH2FcZE2zAKJuOSkxscjEcpEBIuXO0CqKbYRt/Pn61W12sj3/MnV6bm1h++
|
||||||
|
ebdIMpwGRh9Dn3YXD7UzUF5DtQ1UT3LU2nJDLD27AtZmVSOy+sWHp8Qlz1IqdCyo
|
||||||
|
+7uIRNe5PIFDDG4dCjezYpZkuhCoeXAUmG838szabsbCN9hwuJx5YNAMBkGy5jqd
|
||||||
|
ou8NxNPCoMZtaKuhzjQUsow7IQ3brg78CnyB0pfFTDbPs1C9GLF5munvwK1prCLU
|
||||||
|
4KSbc4ZhjX88dLfClh3FTjdV0kQvlubf0Z71LqR9aMlU4WEFxE7KIeyolAGYdip4
|
||||||
|
xwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
Reference in New Issue
Block a user