Files
hfb_sys/docs/多商户支付配置系统设计.md
2026-06-06 17:49:22 +08:00

317 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多商户支付配置系统设计方案
## 📋 概述
将单商户硬编码的乐刷支付配置改造为支持多商户、可动态管理的数据库配置方案。
---
## 🎯 设计目标
✅ 支持多个乐刷商户号
✅ 支持不同业务场景使用不同商户
✅ 后台 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. **高可用** - 兜底机制保证服务不中断
---
## 📝 下一步工作
- [ ] 执行数据库迁移
- [ ] 注册路由和依赖注入
- [ ] 实现前端管理界面
- [ ] 集成到支付模块
- [ ] 测试多商户切换
- [ ] 编写单元测试
- [ ] 更新部署文档