# 多商户支付配置系统设计方案 ## 📋 概述 将单商户硬编码的乐刷支付配置改造为支持多商户、可动态管理的数据库配置方案。 --- ## 🎯 设计目标 ✅ 支持多个乐刷商户号 ✅ 支持不同业务场景使用不同商户 ✅ 后台 GUI 管理(增删改查) ✅ 密钥加密存储(AES-256-GCM) ✅ 支持启用/禁用商户 ✅ 支持设置默认商户 ✅ 支持测试环境和生产环境 ✅ 使用统计和审计日志 ✅ 平滑迁移,向后兼容 --- ## 📊 数据库设计 ### 1. 支付商户配置表 `payment_merchant_configs` ```sql CREATE TABLE payment_merchant_configs ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, name VARCHAR(128) NOT NULL, -- 商户名称 provider VARCHAR(32) NOT NULL, -- leshua/mock merchant_id VARCHAR(128) NOT NULL, -- 商户号 gateway_url VARCHAR(512) NOT NULL DEFAULT '', -- 网关地址 sign_key VARCHAR(512) NOT NULL DEFAULT '', -- 签名密钥(加密) notify_key VARCHAR(512) NOT NULL DEFAULT '', -- 通知密钥(加密) notify_url VARCHAR(512) NOT NULL DEFAULT '', -- 回调地址 jump_url VARCHAR(512) NOT NULL DEFAULT '', -- 跳转地址 pay_way VARCHAR(32) NOT NULL DEFAULT 'ZFBZF', jspay_flag VARCHAR(8) NOT NULL DEFAULT '2', sign_type VARCHAR(16) NOT NULL DEFAULT 'MD5', extra_config JSON NULL, -- 扩展配置 is_default TINYINT(1) NOT NULL DEFAULT 0, -- 是否默认 status VARCHAR(32) NOT NULL DEFAULT 'active', -- active/disabled/testing environment VARCHAR(16) NOT NULL DEFAULT 'production', -- production/sandbox business_tags JSON NULL, -- 业务场景标签 total_transactions BIGINT NOT NULL DEFAULT 0, total_amount_cent BIGINT NOT NULL DEFAULT 0, last_used_at DATETIME NULL, created_by BIGINT UNSIGNED NULL, updated_by BIGINT UNSIGNED NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_payment_merchant_configs_provider (provider, status), KEY idx_payment_merchant_configs_default (provider, is_default) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` ### 2. 配置使用日志表 `payment_config_usage_logs`(可选) 用于审计和统计分析。 --- ## 🏗️ 后端架构 ### 目录结构 ``` backend/internal/modules/paymentconfig/ ├── dto.go # 数据传输对象、请求响应结构 ├── encryptor.go # AES-GCM 加密器 ├── repository.go # 数据库操作层 ├── service.go # 业务逻辑层 └── handler.go # HTTP 处理层 ``` ### 核心功能 1. **加密存储** - 使用 AES-256-GCM 对称加密 - 密钥从环境变量 `PAYMENT_CONFIG_ENCRYPTION_KEY` 读取(32字节) - 自动加密 `sign_key` 和 `notify_key` 2. **权限控制** - `payment_config:list` - 查看配置列表 - `payment_config:create` - 创建配置 - `payment_config:update` - 更新配置 - `payment_config:delete` - 删除配置 - `payment_config:view_secret` - 查看密钥明文 3. **默认商户管理** - 每个 `provider` 只能有一个默认商户 - 设置新默认时自动取消旧默认 - 支付模块优先使用默认商户 4. **使用统计** - 自动记录交易笔数、总金额 - 记录最后使用时间 - 可选:记录详细使用日志 --- ## 🔌 API 接口 ### 管理后台接口 ``` GET /admin/payment-configs # 获取配置列表 GET /admin/payment-configs/:id # 获取单个配置 POST /admin/payment-configs # 创建配置 PUT /admin/payment-configs/:id # 更新配置 DELETE /admin/payment-configs/:id # 删除配置 ``` ### 请求示例 **创建配置** ```json POST /admin/payment-configs { "name": "乐刷生产商户1", "provider": "leshua", "merchant_id": "123456789", "gateway_url": "https://paygate.leshuazf.com/cgi-bin/lepos_pay_gateway.cgi", "sign_key": "your-sign-key", "notify_key": "your-notify-key", "notify_url": "https://your-domain.com/api/payment/leshua/notify", "jump_url": "https://your-domain.com/payment/result", "pay_way": "ZFBZF", "jspay_flag": "2", "sign_type": "MD5", "is_default": true, "status": "active", "environment": "production", "business_tags": ["order_pay", "wallet_recharge"] } ``` **查询配置(包含密钥)** ``` GET /admin/payment-configs/1?include_secret=true ``` --- ## 🔄 支付模块集成 ### 修改 payment 模块 1. **注入 paymentconfig.Service** ```go type Repository struct { db *gorm.DB cfg config.PaymentConfig // 保留作为兜底 paymentConfigSvc *paymentconfig.Service // 新增 orderRepo *order.Repository walletRepo *wallet.Repository leshua *leshua.Client provider string isMockMode bool } ``` 2. **动态获取配置** ```go func (r *Repository) getLeshuaConfig() (config.LeshuaPaymentConfig, error) { // 优先从数据库获取默认配置 if r.paymentConfigSvc != nil { dto, err := r.paymentConfigSvc.GetDefaultConfig("leshua") if err == nil { return config.LeshuaPaymentConfig{ GatewayURL: dto.GatewayURL, MerchantID: dto.MerchantID, SignKey: dto.SignKey, NotifyKey: dto.NotifyKey, NotifyURL: dto.NotifyURL, JumpURL: dto.JumpURL, PayWay: dto.PayWay, JSPayFlag: dto.JSPayFlag, SignType: dto.SignType, }, nil } } // 兜底:使用 .env 配置 return r.cfg.Leshua, nil } ``` 3. **支付时使用动态配置** ```go func (r *Repository) Start(userID uint64, orderID uint64, req StartPaymentRequest, clientIP string) (*PaymentDTO, error) { // ... leshuaConfig, err := r.getLeshuaConfig() if err != nil { return nil, err } client := leshua.NewClient(leshuaConfig) resp, rawReq, err := client.CreatePayment(ctx, ...) // ... } ``` --- ## 🎨 前端管理界面 ### 功能列表 1. **配置列表** - 显示所有支付配置 - 筛选:服务商、状态、环境 - 标识默认商户 - 显示使用统计 2. **创建/编辑配置** - 表单验证 - 密钥输入(敏感) - 默认商户切换 - 状态管理 3. **查看密钥** - 需要 `payment_config:view_secret` 权限 - 点击"查看密钥"按钮后调用API 4. **删除配置** - 确认对话框 - 检查是否正在使用 ### 路由 ```typescript { path: '/admin/payment-configs', component: () => import('@/features/admin/views/AdminPaymentConfigsView.vue'), meta: { requiresAuth: true, requiresAdmin: true } } ``` --- ## 🔐 安全考虑 1. **密钥加密** - 数据库存储加密密文 - 传输使用 HTTPS - 日志不记录明文密钥 2. **权限控制** - 只有财务和超管可以管理 - 查看密钥需要额外权限 3. **审计日志** - 记录所有配置变更 - 记录查看密钥操作 --- ## 🚀 部署步骤 ### 1. 环境变量配置 ```bash # .env 添加加密密钥(32字节) PAYMENT_CONFIG_ENCRYPTION_KEY=your-32-byte-key-here-abcdefgh ``` 生成密钥: ```bash openssl rand -hex 16 ``` 示例结果:`a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6`(32个十六进制字符) ### 2. 数据库迁移 ```bash ./scripts/dev.sh --reset-db # 或手动执行迁移 mysql < backend/migrations/000002_add_payment_merchant_configs.sql ``` ### 3. 初始化配置 通过后台管理界面添加第一个商户配置,或者应用启动时自动从 `.env` 迁移。 ### 4. 向后兼容 如果数据库中没有配置,支付模块会回退使用 `.env` 中的配置。 --- ## ✅ 优势 1. **灵活性** - 支持多商户、多场景 2. **安全性** - 密钥加密存储 3. **可维护性** - GUI 管理,无需重启 4. **可扩展性** - 易于支持其他支付渠道 5. **可审计** - 完整的操作日志 6. **高可用** - 兜底机制保证服务不中断 --- ## 📝 下一步工作 - [ ] 执行数据库迁移 - [ ] 注册路由和依赖注入 - [ ] 实现前端管理界面 - [ ] 集成到支付模块 - [ ] 测试多商户切换 - [ ] 编写单元测试 - [ ] 更新部署文档