355 lines
10 KiB
Bash
Executable File
355 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 微信支付证书自动化管理脚本
|
||
# 使用RSAAutoCertificateConfig自动下载和管理证书
|
||
# 作者: 科技小王子
|
||
# 日期: 2024-07-26
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 日志函数
|
||
log_info() {
|
||
echo -e "${BLUE}[INFO]${NC} $1"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
# 配置参数
|
||
MERCHANT_ID=""
|
||
API_V3_KEY=""
|
||
MERCHANT_SERIAL_NUMBER=""
|
||
PRIVATE_KEY_PATH=""
|
||
OUTPUT_DIR=""
|
||
|
||
# 显示使用说明
|
||
show_usage() {
|
||
echo "微信支付证书自动化管理脚本"
|
||
echo ""
|
||
echo "使用方法:"
|
||
echo " $0 auto -m <商户号> -k <APIv3密钥> -s <证书序列号> -p <私钥路径> [-o <输出目录>]"
|
||
echo " $0 test # 测试现有证书配置"
|
||
echo " $0 status # 检查证书状态"
|
||
echo ""
|
||
echo "参数说明:"
|
||
echo " -m, --merchant-id 微信支付商户号"
|
||
echo " -k, --api-v3-key APIv3密钥"
|
||
echo " -s, --serial-number 商户证书序列号"
|
||
echo " -p, --private-key 商户私钥文件路径"
|
||
echo " -o, --output-dir 输出目录(可选,默认为当前目录)"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " $0 auto -m 1723321338 -k 0kF5OlPr482EZwtn9zGufUcqa7ovgxRL -s 2B933F7C35014A1C363642623E4A62364B34C4EB -p ./apiclient_key.pem"
|
||
echo ""
|
||
echo "注意:"
|
||
echo " - 此脚本使用RSAAutoCertificateConfig自动管理证书"
|
||
echo " - 无需手动下载wechatpay_cert.pem,系统会自动获取"
|
||
echo " - 确保商户平台已开启API安全功能"
|
||
}
|
||
|
||
# 解析命令行参数
|
||
parse_args() {
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-m|--merchant-id)
|
||
MERCHANT_ID="$2"
|
||
shift 2
|
||
;;
|
||
-k|--api-v3-key)
|
||
API_V3_KEY="$2"
|
||
shift 2
|
||
;;
|
||
-s|--serial-number)
|
||
MERCHANT_SERIAL_NUMBER="$2"
|
||
shift 2
|
||
;;
|
||
-p|--private-key)
|
||
PRIVATE_KEY_PATH="$2"
|
||
shift 2
|
||
;;
|
||
-o|--output-dir)
|
||
OUTPUT_DIR="$2"
|
||
shift 2
|
||
;;
|
||
*)
|
||
log_error "未知参数: $1"
|
||
show_usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
# 验证参数
|
||
validate_args() {
|
||
if [[ -z "$MERCHANT_ID" ]]; then
|
||
log_error "缺少商户号参数 (-m)"
|
||
return 1
|
||
fi
|
||
|
||
if [[ -z "$API_V3_KEY" ]]; then
|
||
log_error "缺少APIv3密钥参数 (-k)"
|
||
return 1
|
||
fi
|
||
|
||
if [[ -z "$MERCHANT_SERIAL_NUMBER" ]]; then
|
||
log_error "缺少证书序列号参数 (-s)"
|
||
return 1
|
||
fi
|
||
|
||
if [[ -z "$PRIVATE_KEY_PATH" ]]; then
|
||
log_error "缺少私钥路径参数 (-p)"
|
||
return 1
|
||
fi
|
||
|
||
if [[ ! -f "$PRIVATE_KEY_PATH" ]]; then
|
||
log_error "私钥文件不存在: $PRIVATE_KEY_PATH"
|
||
return 1
|
||
fi
|
||
|
||
if [[ -z "$OUTPUT_DIR" ]]; then
|
||
OUTPUT_DIR="."
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# 创建Java测试程序
|
||
create_test_program() {
|
||
local test_file="WechatCertTest.java"
|
||
|
||
cat > "$test_file" << 'EOF'
|
||
import com.wechat.pay.java.core.Config;
|
||
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||
|
||
public class WechatCertTest {
|
||
public static void main(String[] args) {
|
||
if (args.length != 4) {
|
||
System.err.println("用法: java WechatCertTest <商户号> <私钥路径> <证书序列号> <APIv3密钥>");
|
||
System.exit(1);
|
||
}
|
||
|
||
String merchantId = args[0];
|
||
String privateKeyPath = args[1];
|
||
String serialNumber = args[2];
|
||
String apiV3Key = args[3];
|
||
|
||
try {
|
||
System.out.println("正在创建RSAAutoCertificateConfig...");
|
||
Config config = new RSAAutoCertificateConfig.Builder()
|
||
.merchantId(merchantId)
|
||
.privateKeyFromPath(privateKeyPath)
|
||
.merchantSerialNumber(serialNumber)
|
||
.apiV3Key(apiV3Key)
|
||
.build();
|
||
|
||
System.out.println("✅ 证书配置创建成功!");
|
||
System.out.println("商户号: " + merchantId);
|
||
System.out.println("证书序列号: " + serialNumber);
|
||
System.out.println("私钥路径: " + privateKeyPath);
|
||
System.out.println("");
|
||
System.out.println("🎉 RSAAutoCertificateConfig 已成功初始化");
|
||
System.out.println("📋 系统将自动管理微信支付平台证书");
|
||
System.out.println("🔄 证书过期时将自动更新");
|
||
|
||
} catch (Exception e) {
|
||
System.err.println("❌ 证书配置失败: " + e.getMessage());
|
||
e.printStackTrace();
|
||
System.exit(1);
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
|
||
echo "$test_file"
|
||
}
|
||
|
||
# 自动配置证书
|
||
auto_configure() {
|
||
log_info "开始自动配置微信支付证书..."
|
||
|
||
# 验证参数
|
||
if ! validate_args; then
|
||
exit 1
|
||
fi
|
||
|
||
log_info "配置信息:"
|
||
log_info "商户号: $MERCHANT_ID"
|
||
log_info "证书序列号: $MERCHANT_SERIAL_NUMBER"
|
||
log_info "私钥路径: $PRIVATE_KEY_PATH"
|
||
log_info "输出目录: $OUTPUT_DIR"
|
||
|
||
# 检查是否有Java环境
|
||
if ! command -v java &> /dev/null; then
|
||
log_error "未找到Java环境,请先安装Java"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查是否有微信支付SDK
|
||
local classpath="."
|
||
if [[ -f "target/classes" ]]; then
|
||
classpath="target/classes:$classpath"
|
||
fi
|
||
|
||
# 查找微信支付SDK jar文件
|
||
local wechat_jar=$(find . -name "*wechatpay*" -name "*.jar" 2>/dev/null | head -1)
|
||
if [[ -n "$wechat_jar" ]]; then
|
||
classpath="$wechat_jar:$classpath"
|
||
log_info "找到微信支付SDK: $wechat_jar"
|
||
fi
|
||
|
||
# 创建测试程序
|
||
local test_file=$(create_test_program)
|
||
log_info "创建测试程序: $test_file"
|
||
|
||
# 编译测试程序
|
||
log_info "编译测试程序..."
|
||
if ! javac -cp "$classpath" "$test_file" 2>/dev/null; then
|
||
log_warning "编译失败,尝试使用项目环境..."
|
||
|
||
# 使用Maven编译项目
|
||
if [[ -f "pom.xml" ]]; then
|
||
log_info "使用Maven编译项目..."
|
||
mvn compile -q
|
||
classpath="target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout)"
|
||
fi
|
||
fi
|
||
|
||
# 运行测试
|
||
log_info "测试证书配置..."
|
||
if java -cp "$classpath" WechatCertTest "$MERCHANT_ID" "$PRIVATE_KEY_PATH" "$MERCHANT_SERIAL_NUMBER" "$API_V3_KEY"; then
|
||
log_success "证书自动配置成功!"
|
||
log_info ""
|
||
log_info "🎯 推荐使用方式:"
|
||
log_info "1. 在您的应用中使用 RSAAutoCertificateConfig"
|
||
log_info "2. 系统会自动下载和管理微信支付平台证书"
|
||
log_info "3. 无需手动下载 wechatpay_cert.pem 文件"
|
||
log_info ""
|
||
log_info "📝 代码示例:"
|
||
echo "Config config = new RSAAutoCertificateConfig.Builder()"
|
||
echo " .merchantId(\"$MERCHANT_ID\")"
|
||
echo " .privateKeyFromPath(\"$PRIVATE_KEY_PATH\")"
|
||
echo " .merchantSerialNumber(\"$MERCHANT_SERIAL_NUMBER\")"
|
||
echo " .apiV3Key(\"$API_V3_KEY\")"
|
||
echo " .build();"
|
||
else
|
||
log_error "证书配置测试失败"
|
||
exit 1
|
||
fi
|
||
|
||
# 清理临时文件
|
||
rm -f "$test_file" "${test_file%.java}.class"
|
||
}
|
||
|
||
# 检查证书状态
|
||
check_status() {
|
||
log_info "检查证书状态..."
|
||
|
||
# 检查开发环境证书
|
||
local dev_cert_dir="src/main/resources/certs/dev/wechat"
|
||
if [[ -d "$dev_cert_dir" ]]; then
|
||
log_info "开发环境证书目录: $dev_cert_dir"
|
||
for file in apiclient_key.pem apiclient_cert.pem; do
|
||
if [[ -f "$dev_cert_dir/$file" ]]; then
|
||
log_success "✓ $file"
|
||
else
|
||
log_warning "✗ $file (不存在)"
|
||
fi
|
||
done
|
||
fi
|
||
|
||
# 检查生产环境证书
|
||
local prod_cert_dir="certs/wechat"
|
||
if [[ -d "$prod_cert_dir" ]]; then
|
||
log_info "生产环境证书目录: $prod_cert_dir"
|
||
for file in apiclient_key.pem apiclient_cert.pem; do
|
||
if [[ -f "$prod_cert_dir/$file" ]]; then
|
||
log_success "✓ $file"
|
||
else
|
||
log_warning "✗ $file (不存在)"
|
||
fi
|
||
done
|
||
fi
|
||
|
||
log_info ""
|
||
log_info "💡 提示:"
|
||
log_info "使用 RSAAutoCertificateConfig 时,只需要以下文件:"
|
||
log_info "- apiclient_key.pem (商户私钥)"
|
||
log_info "- 商户号、证书序列号、APIv3密钥"
|
||
log_info "- wechatpay_cert.pem 将自动下载和管理"
|
||
}
|
||
|
||
# 测试现有配置
|
||
test_config() {
|
||
log_info "测试现有证书配置..."
|
||
|
||
# 从配置文件读取参数
|
||
local config_file="src/main/resources/application.yml"
|
||
if [[ -f "$config_file" ]]; then
|
||
log_info "从配置文件读取参数: $config_file"
|
||
|
||
# 提取配置信息(简单解析)
|
||
local api_key=$(grep -A 10 "wechat-pay:" "$config_file" | grep "api-v3-key:" | sed 's/.*: *"\(.*\)".*/\1/')
|
||
local private_key_file=$(grep -A 10 "wechat-pay:" "$config_file" | grep "private-key-file:" | sed 's/.*: *"\(.*\)".*/\1/')
|
||
|
||
if [[ -n "$api_key" && -n "$private_key_file" ]]; then
|
||
log_info "找到配置:"
|
||
log_info "APIv3密钥: ${api_key:0:8}..."
|
||
log_info "私钥文件: $private_key_file"
|
||
|
||
local full_private_key_path="src/main/resources/certs/dev/wechat/$private_key_file"
|
||
if [[ -f "$full_private_key_path" ]]; then
|
||
log_success "私钥文件存在: $full_private_key_path"
|
||
log_info ""
|
||
log_info "✅ 配置看起来正常,可以使用 RSAAutoCertificateConfig"
|
||
else
|
||
log_warning "私钥文件不存在: $full_private_key_path"
|
||
fi
|
||
else
|
||
log_warning "未能从配置文件解析到完整信息"
|
||
fi
|
||
else
|
||
log_warning "配置文件不存在: $config_file"
|
||
fi
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
case "${1:-}" in
|
||
"auto")
|
||
shift
|
||
parse_args "$@"
|
||
auto_configure
|
||
;;
|
||
"test")
|
||
test_config
|
||
;;
|
||
"status")
|
||
check_status
|
||
;;
|
||
*)
|
||
show_usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# 执行主函数
|
||
main "$@"
|