577 lines
18 KiB
Markdown
577 lines
18 KiB
Markdown
# 订阅支付系统重新设计方案
|
||
|
||
## 📊 问题分析
|
||
|
||
### 现有系统的问题
|
||
|
||
1. **价格配置混乱**
|
||
- 季付和月付价格相同(配置错误)
|
||
- `monthly_price` 和 `yearly_price` 字段命名不清晰
|
||
- 缺少季付、半年付等周期的价格配置
|
||
|
||
2. **升级逻辑复杂且不合理**
|
||
- 计算剩余价值折算(按天计算 `remaining_value`)
|
||
- 用户难以理解升级价格
|
||
- 续费用户和新用户价格不一致
|
||
- 逻辑复杂,容易出错
|
||
|
||
3. **按钮文案不清晰**
|
||
- 已订阅用户应显示"续费 Pro"/"续费 Max"
|
||
- 而不是"升级至 Pro"/"切换至 Pro"
|
||
|
||
4. **数据库表设计问题**
|
||
- `SubscriptionUpgrade` 表记录升级,但逻辑过于复杂
|
||
- `PaymentOrder` 表缺少必要字段
|
||
- 价格配置分散在多个字段
|
||
|
||
---
|
||
|
||
## ✨ 新设计方案
|
||
|
||
### 核心原则
|
||
|
||
1. **简化续费逻辑**: **续费用户与新用户价格完全一致**,不做任何折算
|
||
2. **清晰的价格体系**: 每个套餐每个周期都有明确的价格
|
||
3. **统一的用户体验**: 无论是新购还是续费,价格透明一致
|
||
4. **独立的订阅记录**: 每次支付都创建新的订阅记录(历史可追溯)
|
||
|
||
---
|
||
|
||
## 📐 数据库表设计
|
||
|
||
### 1. `subscription_plans` - 订阅套餐表(重构)
|
||
|
||
```sql
|
||
CREATE TABLE subscription_plans (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
plan_code VARCHAR(20) NOT NULL UNIQUE COMMENT '套餐代码: pro, max',
|
||
plan_name VARCHAR(50) NOT NULL COMMENT '套餐名称: Pro专业版, Max旗舰版',
|
||
description TEXT COMMENT '套餐描述',
|
||
features JSON COMMENT '功能列表',
|
||
|
||
-- 价格配置(所有周期价格)
|
||
price_monthly DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '月付价格',
|
||
price_quarterly DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '季付价格(3个月)',
|
||
price_semiannual DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '半年付价格(6个月)',
|
||
price_yearly DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '年付价格(12个月)',
|
||
|
||
-- 状态字段
|
||
is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
|
||
display_order INT DEFAULT 0 COMMENT '展示顺序',
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_plan_code (plan_code),
|
||
INDEX idx_active_order (is_active, display_order)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订阅套餐配置表';
|
||
```
|
||
|
||
**示例数据**:
|
||
```sql
|
||
INSERT INTO subscription_plans (plan_code, plan_name, description, price_monthly, price_quarterly, price_semiannual, price_yearly) VALUES
|
||
('pro', 'Pro 专业版', '为专业投资者打造', 299.00, 799.00, 1499.00, 2699.00),
|
||
('max', 'Max 旗舰版', '旗舰级体验', 599.00, 1599.00, 2999.00, 5399.00);
|
||
```
|
||
|
||
---
|
||
|
||
### 2. `user_subscriptions` - 用户订阅记录表(重构)
|
||
|
||
```sql
|
||
CREATE TABLE user_subscriptions (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
user_id INT NOT NULL COMMENT '用户ID',
|
||
subscription_id VARCHAR(32) UNIQUE NOT NULL COMMENT '订阅ID(唯一标识)',
|
||
|
||
-- 订阅基本信息
|
||
plan_code VARCHAR(20) NOT NULL COMMENT '套餐代码: pro, max',
|
||
billing_cycle VARCHAR(20) NOT NULL COMMENT '计费周期: monthly, quarterly, semiannual, yearly',
|
||
|
||
-- 订阅时间
|
||
start_date DATETIME NOT NULL COMMENT '订阅开始时间',
|
||
end_date DATETIME NOT NULL COMMENT '订阅结束时间',
|
||
|
||
-- 订阅状态
|
||
status VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态: active(有效), expired(已过期), cancelled(已取消)',
|
||
is_current BOOLEAN DEFAULT FALSE COMMENT '是否为当前生效的订阅',
|
||
|
||
-- 支付信息
|
||
payment_order_id INT COMMENT '关联的支付订单ID',
|
||
paid_amount DECIMAL(10,2) NOT NULL COMMENT '实际支付金额',
|
||
original_price DECIMAL(10,2) NOT NULL COMMENT '原价',
|
||
discount_amount DECIMAL(10,2) DEFAULT 0 COMMENT '优惠金额',
|
||
|
||
-- 订阅类型
|
||
subscription_type VARCHAR(20) DEFAULT 'new' COMMENT '订阅类型: new(新购), renew(续费)',
|
||
previous_subscription_id VARCHAR(32) COMMENT '上一个订阅ID(续费时记录)',
|
||
|
||
-- 自动续费
|
||
auto_renew BOOLEAN DEFAULT FALSE COMMENT '是否自动续费',
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_user_id (user_id),
|
||
INDEX idx_subscription_id (subscription_id),
|
||
INDEX idx_user_current (user_id, is_current),
|
||
INDEX idx_status (status),
|
||
INDEX idx_end_date (end_date),
|
||
|
||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户订阅记录表';
|
||
```
|
||
|
||
**设计说明**:
|
||
- 每次支付都创建新的订阅记录
|
||
- 通过 `is_current` 标识当前生效的订阅
|
||
- 支持订阅历史追溯
|
||
- 续费时记录 `previous_subscription_id` 形成订阅链
|
||
|
||
---
|
||
|
||
### 3. `payment_orders` - 支付订单表(重构)
|
||
|
||
```sql
|
||
CREATE TABLE payment_orders (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
order_no VARCHAR(32) UNIQUE NOT NULL COMMENT '订单号',
|
||
user_id INT NOT NULL COMMENT '用户ID',
|
||
|
||
-- 订阅信息
|
||
plan_code VARCHAR(20) NOT NULL COMMENT '套餐代码',
|
||
billing_cycle VARCHAR(20) NOT NULL COMMENT '计费周期',
|
||
subscription_type VARCHAR(20) DEFAULT 'new' COMMENT '订阅类型: new(新购), renew(续费)',
|
||
|
||
-- 价格信息
|
||
original_price DECIMAL(10,2) NOT NULL COMMENT '原价',
|
||
discount_amount DECIMAL(10,2) DEFAULT 0 COMMENT '优惠金额',
|
||
final_amount DECIMAL(10,2) NOT NULL COMMENT '实付金额',
|
||
|
||
-- 优惠码
|
||
promo_code_id INT COMMENT '优惠码ID',
|
||
promo_code VARCHAR(50) COMMENT '优惠码',
|
||
|
||
-- 支付信息
|
||
payment_method VARCHAR(20) DEFAULT 'wechat' COMMENT '支付方式: wechat, alipay',
|
||
payment_channel VARCHAR(50) COMMENT '支付渠道详情',
|
||
transaction_id VARCHAR(64) COMMENT '第三方交易号',
|
||
qr_code_url TEXT COMMENT '支付二维码URL',
|
||
|
||
-- 订单状态
|
||
status VARCHAR(20) DEFAULT 'pending' COMMENT '状态: pending(待支付), paid(已支付), expired(已过期), cancelled(已取消)',
|
||
|
||
-- 时间信息
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
paid_at TIMESTAMP NULL COMMENT '支付时间',
|
||
expired_at TIMESTAMP NULL COMMENT '过期时间',
|
||
|
||
-- 备注
|
||
remark TEXT COMMENT '备注信息',
|
||
|
||
INDEX idx_order_no (order_no),
|
||
INDEX idx_user_id (user_id),
|
||
INDEX idx_status (status),
|
||
INDEX idx_created_at (created_at),
|
||
|
||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||
FOREIGN KEY (promo_code_id) REFERENCES promo_codes(id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表';
|
||
```
|
||
|
||
---
|
||
|
||
### 4. `promo_codes` - 优惠码表(保持不变,微调)
|
||
|
||
```sql
|
||
CREATE TABLE promo_codes (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
code VARCHAR(50) UNIQUE NOT NULL COMMENT '优惠码',
|
||
description VARCHAR(200) COMMENT '描述',
|
||
|
||
-- 折扣类型
|
||
discount_type VARCHAR(20) NOT NULL COMMENT '折扣类型: percentage(百分比), fixed_amount(固定金额)',
|
||
discount_value DECIMAL(10,2) NOT NULL COMMENT '折扣值',
|
||
|
||
-- 适用范围
|
||
applicable_plans JSON COMMENT '适用套餐: ["pro", "max"] 或 null(全部)',
|
||
applicable_cycles JSON COMMENT '适用周期: ["monthly", "yearly"] 或 null(全部)',
|
||
min_amount DECIMAL(10,2) COMMENT '最低消费金额',
|
||
|
||
-- 使用限制
|
||
max_total_uses INT COMMENT '最大使用次数(总)',
|
||
max_uses_per_user INT DEFAULT 1 COMMENT '每用户最大使用次数',
|
||
current_uses INT DEFAULT 0 COMMENT '当前使用次数',
|
||
|
||
-- 有效期
|
||
valid_from TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '生效时间',
|
||
valid_until TIMESTAMP NULL COMMENT '过期时间',
|
||
|
||
-- 状态
|
||
is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_code (code),
|
||
INDEX idx_active (is_active),
|
||
INDEX idx_valid_period (valid_from, valid_until)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优惠码表';
|
||
```
|
||
|
||
---
|
||
|
||
### 5. `promo_code_usage` - 优惠码使用记录表(保持不变)
|
||
|
||
```sql
|
||
CREATE TABLE promo_code_usage (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
promo_code_id INT NOT NULL,
|
||
user_id INT NOT NULL,
|
||
order_id INT NOT NULL,
|
||
discount_amount DECIMAL(10,2) NOT NULL COMMENT '实际优惠金额',
|
||
used_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_promo_code (promo_code_id),
|
||
INDEX idx_user_id (user_id),
|
||
INDEX idx_order_id (order_id),
|
||
|
||
FOREIGN KEY (promo_code_id) REFERENCES promo_codes(id) ON DELETE CASCADE,
|
||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||
FOREIGN KEY (order_id) REFERENCES payment_orders(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优惠码使用记录表';
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 删除不必要的表
|
||
|
||
**删除 `subscription_upgrades` 表** - 不再需要复杂的升级逻辑
|
||
|
||
---
|
||
|
||
## 💡 业务逻辑设计
|
||
|
||
### 1. 价格计算逻辑(简化版)
|
||
|
||
```python
|
||
def calculate_subscription_price(plan_code, billing_cycle, promo_code=None):
|
||
"""
|
||
计算订阅价格(新购和续费价格完全一致)
|
||
|
||
Args:
|
||
plan_code: 套餐代码 (pro/max)
|
||
billing_cycle: 计费周期 (monthly/quarterly/semiannual/yearly)
|
||
promo_code: 优惠码(可选)
|
||
|
||
Returns:
|
||
dict: {
|
||
'plan_code': 'pro',
|
||
'billing_cycle': 'yearly',
|
||
'original_price': 2699.00,
|
||
'discount_amount': 0,
|
||
'final_amount': 2699.00,
|
||
'promo_code': None,
|
||
'promo_error': None
|
||
}
|
||
"""
|
||
# 1. 查询套餐价格
|
||
plan = SubscriptionPlan.query.filter_by(plan_code=plan_code, is_active=True).first()
|
||
if not plan:
|
||
return {'error': '套餐不存在'}
|
||
|
||
# 2. 获取对应周期的价格
|
||
price_field = f'price_{billing_cycle}'
|
||
original_price = getattr(plan, price_field, 0)
|
||
|
||
if original_price <= 0:
|
||
return {'error': '价格配置错误'}
|
||
|
||
result = {
|
||
'plan_code': plan_code,
|
||
'plan_name': plan.plan_name,
|
||
'billing_cycle': billing_cycle,
|
||
'original_price': float(original_price),
|
||
'discount_amount': 0,
|
||
'final_amount': float(original_price),
|
||
'promo_code': None,
|
||
'promo_error': None
|
||
}
|
||
|
||
# 3. 应用优惠码(如果有)
|
||
if promo_code:
|
||
promo, error = validate_promo_code(promo_code, plan_code, billing_cycle, original_price, user_id)
|
||
if promo:
|
||
discount = calculate_discount(promo, original_price)
|
||
result['discount_amount'] = float(discount)
|
||
result['final_amount'] = float(original_price - discount)
|
||
result['promo_code'] = promo.code
|
||
elif error:
|
||
result['promo_error'] = error
|
||
|
||
return result
|
||
```
|
||
|
||
**关键点**:
|
||
- ✅ 不再计算 `remaining_value`(剩余价值)
|
||
- ✅ 不再区分新购/续费价格
|
||
- ✅ 逻辑简单,易于维护
|
||
- ✅ 用户体验清晰透明
|
||
|
||
---
|
||
|
||
### 2. 创建订单逻辑
|
||
|
||
```python
|
||
def create_subscription_order(user_id, plan_code, billing_cycle, promo_code=None):
|
||
"""
|
||
创建订阅支付订单
|
||
"""
|
||
# 1. 计算价格
|
||
price_result = calculate_subscription_price(plan_code, billing_cycle, promo_code)
|
||
if 'error' in price_result:
|
||
return {'success': False, 'error': price_result['error']}
|
||
|
||
# 2. 判断是新购还是续费
|
||
current_sub = get_current_subscription(user_id)
|
||
|
||
subscription_type = 'new'
|
||
if current_sub and current_sub.plan_code in ['pro', 'max']:
|
||
subscription_type = 'renew'
|
||
|
||
# 3. 创建支付订单
|
||
order = PaymentOrder(
|
||
order_no=generate_order_no(user_id),
|
||
user_id=user_id,
|
||
plan_code=plan_code,
|
||
billing_cycle=billing_cycle,
|
||
subscription_type=subscription_type,
|
||
original_price=price_result['original_price'],
|
||
discount_amount=price_result['discount_amount'],
|
||
final_amount=price_result['final_amount'],
|
||
promo_code=promo_code,
|
||
status='pending',
|
||
expired_at=datetime.now() + timedelta(minutes=30)
|
||
)
|
||
|
||
db.session.add(order)
|
||
db.session.commit()
|
||
|
||
# 4. 生成支付二维码(微信支付)
|
||
qr_code_url = generate_wechat_qr_code(order)
|
||
order.qr_code_url = qr_code_url
|
||
db.session.commit()
|
||
|
||
return {'success': True, 'order': order.to_dict()}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 支付成功后的订阅激活逻辑
|
||
|
||
```python
|
||
def activate_subscription_after_payment(order_id):
|
||
"""
|
||
支付成功后激活订阅
|
||
"""
|
||
order = PaymentOrder.query.get(order_id)
|
||
if not order or order.status != 'paid':
|
||
return {'success': False, 'error': '订单状态错误'}
|
||
|
||
user_id = order.user_id
|
||
plan_code = order.plan_code
|
||
billing_cycle = order.billing_cycle
|
||
|
||
# 1. 计算订阅周期
|
||
cycle_days = {
|
||
'monthly': 30,
|
||
'quarterly': 90,
|
||
'semiannual': 180,
|
||
'yearly': 365
|
||
}
|
||
days = cycle_days.get(billing_cycle, 30)
|
||
|
||
# 2. 获取当前订阅
|
||
current_sub = UserSubscription.query.filter_by(
|
||
user_id=user_id,
|
||
is_current=True
|
||
).first()
|
||
|
||
# 3. 计算开始和结束时间
|
||
now = datetime.now()
|
||
|
||
if current_sub and current_sub.end_date > now:
|
||
# 续费:从当前订阅结束时间开始
|
||
start_date = current_sub.end_date
|
||
else:
|
||
# 新购:从当前时间开始
|
||
start_date = now
|
||
|
||
end_date = start_date + timedelta(days=days)
|
||
|
||
# 4. 创建新订阅记录
|
||
new_subscription = UserSubscription(
|
||
user_id=user_id,
|
||
subscription_id=generate_subscription_id(),
|
||
plan_code=plan_code,
|
||
billing_cycle=billing_cycle,
|
||
start_date=start_date,
|
||
end_date=end_date,
|
||
status='active',
|
||
is_current=True,
|
||
payment_order_id=order.id,
|
||
paid_amount=order.final_amount,
|
||
original_price=order.original_price,
|
||
discount_amount=order.discount_amount,
|
||
subscription_type=order.subscription_type,
|
||
previous_subscription_id=current_sub.subscription_id if current_sub else None
|
||
)
|
||
|
||
# 5. 将旧订阅标记为非当前
|
||
if current_sub:
|
||
current_sub.is_current = False
|
||
|
||
db.session.add(new_subscription)
|
||
db.session.commit()
|
||
|
||
return {'success': True, 'subscription': new_subscription.to_dict()}
|
||
```
|
||
|
||
**关键特性**:
|
||
- ✅ 续费时从**当前订阅结束时间**开始,避免浪费
|
||
- ✅ 每次支付都创建新的订阅记录
|
||
- ✅ 保留历史订阅记录(通过 `previous_subscription_id` 形成链)
|
||
- ✅ 逻辑清晰,易于理解
|
||
|
||
---
|
||
|
||
### 4. 按钮文案逻辑
|
||
|
||
```python
|
||
def get_subscription_button_text(user, plan_code, billing_cycle):
|
||
"""
|
||
获取订阅按钮文字
|
||
|
||
Args:
|
||
user: 用户对象
|
||
plan_code: 套餐代码 (pro/max)
|
||
billing_cycle: 计费周期
|
||
|
||
Returns:
|
||
str: 按钮文字
|
||
"""
|
||
current_sub = get_current_subscription(user.id)
|
||
|
||
# 1. 如果没有订阅或订阅已过期
|
||
if not current_sub or current_sub.plan_code == 'free' or current_sub.status != 'active':
|
||
return f"选择 {get_plan_display_name(plan_code)}"
|
||
|
||
# 2. 如果是当前套餐且周期相同
|
||
if current_sub.plan_code == plan_code and current_sub.billing_cycle == billing_cycle:
|
||
return f"续费 {get_plan_display_name(plan_code)}"
|
||
|
||
# 3. 如果是当前套餐但周期不同
|
||
if current_sub.plan_code == plan_code:
|
||
return f"切换至{get_cycle_display_name(billing_cycle)}"
|
||
|
||
# 4. 如果是不同套餐
|
||
return f"选择 {get_plan_display_name(plan_code)}"
|
||
|
||
def get_plan_display_name(plan_code):
|
||
names = {'pro': 'Pro 专业版', 'max': 'Max 旗舰版'}
|
||
return names.get(plan_code, plan_code)
|
||
|
||
def get_cycle_display_name(billing_cycle):
|
||
names = {
|
||
'monthly': '月付',
|
||
'quarterly': '季付',
|
||
'semiannual': '半年付',
|
||
'yearly': '年付'
|
||
}
|
||
return names.get(billing_cycle, billing_cycle)
|
||
```
|
||
|
||
**示例**:
|
||
- 免费用户看 Pro 年付: "选择 Pro 专业版"
|
||
- Pro 月付用户看 Pro 年付: "切换至年付"
|
||
- Pro 年付用户看 Pro 年付: "续费 Pro 专业版"
|
||
- Pro 用户看 Max 年付: "选择 Max 旗舰版"
|
||
|
||
---
|
||
|
||
## 📊 价格配置示例
|
||
|
||
### Pro 专业版价格设定
|
||
|
||
| 计费周期 | 价格 | 原价 | 折扣 | 月均价格 |
|
||
|---------|------|------|------|---------|
|
||
| 月付 | ¥299 | - | - | ¥299 |
|
||
| 季付(3个月) | ¥799 | ¥897 | 11% | ¥266 |
|
||
| 半年付(6个月) | ¥1499 | ¥1794 | 16% | ¥250 |
|
||
| 年付(12个月) | ¥2699 | ¥3588 | 25% | ¥225 |
|
||
|
||
### Max 旗舰版价格设定
|
||
|
||
| 计费周期 | 价格 | 原价 | 折扣 | 月均价格 |
|
||
|---------|------|------|------|---------|
|
||
| 月付 | ¥599 | - | - | ¥599 |
|
||
| 季付(3个月) | ¥1599 | ¥1797 | 11% | ¥533 |
|
||
| 半年付(6个月) | ¥2999 | ¥3594 | 17% | ¥500 |
|
||
| 年付(12个月) | ¥5399 | ¥7188 | 25% | ¥450 |
|
||
|
||
---
|
||
|
||
## 🔄 迁移方案
|
||
|
||
### 数据迁移 SQL
|
||
|
||
参见 `database_migration.sql`
|
||
|
||
### 代码迁移步骤
|
||
|
||
1. **备份现有数据库**
|
||
2. **执行数据库迁移 SQL**
|
||
3. **更新数据库模型** (`models.py`)
|
||
4. **更新价格计算逻辑** (`calculate_price.py`)
|
||
5. **更新 API 路由** (`routes.py`)
|
||
6. **更新前端组件** (`SubscriptionContentNew.tsx`)
|
||
7. **测试完整流程**
|
||
8. **灰度发布**
|
||
|
||
---
|
||
|
||
## ✅ 优势总结
|
||
|
||
### 相比旧系统的改进
|
||
|
||
1. **价格透明** - 续费用户和新用户价格完全一致
|
||
2. **逻辑简化** - 不再计算剩余价值,代码减少 50%+
|
||
3. **易于理解** - 用户体验更清晰
|
||
4. **灵活扩展** - 轻松添加新的计费周期
|
||
5. **历史追溯** - 完整的订阅历史记录
|
||
6. **数据完整** - 每次支付都有完整的记录
|
||
|
||
### 用户体验改进
|
||
|
||
1. **按钮文案清晰** - "续费 Pro"/"选择 Pro"明确表达意图
|
||
2. **价格一致性** - 所有用户看到的价格都一样
|
||
3. **无隐藏费用** - 不会因为"升级折算"产生困惑
|
||
4. **透明计费** - 支付金额 = 显示价格 - 优惠码折扣
|
||
|
||
---
|
||
|
||
## 📝 后续优化建议
|
||
|
||
1. **自动续费** - 到期前自动扣款续费
|
||
2. **订阅提醒** - 到期前 7 天、3 天、1 天发送通知
|
||
3. **订阅暂停** - 允许用户暂停订阅
|
||
4. **订阅降级** - 从 Max 降级到 Pro(当前周期结束后生效)
|
||
5. **发票管理** - 支持开具电子发票
|
||
6. **支付方式扩展** - 支持支付宝、银行卡等
|
||
|
||
---
|
||
|
||
**设计时间**: 2025-11-19
|
||
**设计者**: Claude Code
|
||
**版本**: v2.0.0
|