#!/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 -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 <商户号> <私钥路径> <证书序列号> "); 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 "$@"