订阅系统核心概念:模型设计
好,咱们今天聊聊订阅系统的几个核心概念。说实话,这些概念看起来简单,但我在项目中见过太多人把它们搞混了。
你想想看,一个订阅系统,本质上是在管理什么?是「谁」在「什么时间」用「什么价格」买了「什么服务」。就这么简单。但落实到代码里,就需要几个关键模型来承载。
订阅生命周期
订阅不是一成不变的。它有自己的生命轨迹。我个人习惯把订阅生命周期分为这几个阶段:
- 待激活:订单刚创建,还没付钱。嗯,这时候用户还在犹豫。
- 活跃中:钱到账了,服务正常跑着。这是最舒服的状态。
- 已过期:到期了,但还没续费。我建议给用户留个宽限期,比如3-7天。
- 已取消:用户主动退订了。注意,取消不等于删除数据。
- 已暂停:因为欠费或其他原因,服务被临时停了。
关键点:每个状态之间的转换,都要有明确的事件触发。比如「支付成功」触发「待激活→活跃中」。
我曾经在一个项目中,把「已过期」和「已取消」混为一谈。结果用户续费时,系统直接报错。那场面,别提多尴尬了。
计划(Plan)
计划,说白了就是「卖什么」。它是订阅产品的核心定价单元。
一个计划通常包含:
- 定价模型:按月、按年、按用量。我个人更推荐按年,因为现金流更稳定。
- 功能配额:比如存储空间、API调用次数。注意,配额要可配置。
- 计费周期:每月1号扣费,还是按开通日扣费?这里坑很多。
- 试用期:免费试用14天?我建议试用期不要太长,7天足够。
// 一个简单的Plan模型示例
{
"planId": "plan_basic_001",
"name": "基础版",
"price": 99.00,
"billingCycle": "monthly",
"features": {
"storage": "10GB",
"apiCalls": 10000,
"users": 5
},
"trialDays": 7
}
避坑指南:我曾经把价格硬编码在代码里,结果改价时改到崩溃。记住,价格一定要做成可配置的。
订单(Order)
订单是用户购买行为的记录。它和订阅的关系是什么?
简单说:订单是一次性交易,订阅是持续服务。用户下了一个订单,系统自动创建一个订阅。
订单模型要记录:
- 订单号(唯一,建议用雪花算法生成)
- 用户ID
- 购买的Plan ID
- 支付金额
- 支付状态(待支付、已支付、已退款)
- 生效时间
你想想看,如果用户同时买了两个Plan,是不是要生成两个订单?嗯,这里要注意,一个订单可以包含多个订阅项,但建议一个订单只对应一个Plan,逻辑更清晰。
合同(Contract)
合同这个概念,很多人会忽略。但它其实很重要。
合同是法律层面的约束。它记录了:
- 用户同意了什么条款
- 服务等级协议(SLA)
- 退款政策
- 数据隐私条款
我建议把合同和订阅解耦。为什么?因为合同可能长期不变,但订阅会频繁变更。比如用户升级了Plan,订阅变了,但合同条款没变。
注意:合同一定要有版本号。我曾经因为没有版本管理,被用户投诉说「你们改条款不通知我」。从那以后,每次合同更新都生成新版本,并让用户重新确认。
租户(Tenant)
租户,就是「谁在使用你的系统」。在SaaS里,租户通常是一个企业或组织。
租户模型要包含:
| 字段 | 说明 | 示例 |
|---|---|---|
| tenantId | 唯一标识 | tenant_abc123 |
| name | 企业名称 | 某某科技有限公司 |
| domain | 自定义域名 | xxx.com |
| status | 租户状态 | active / suspended |
| ownerId | 管理员用户ID | user_001 |
租户和订阅的关系是:一个租户可以有多个订阅。比如一个企业买了基础版和高级版两个Plan,分别给不同部门用。
我记得有个项目,一开始把租户和用户混在一起。结果一个企业有100个员工,每个员工都算一个租户。那数据隔离做得,简直是一团糟。后来重构时,我坚持把租户作为顶层实体,所有数据都按租户隔离。
模型之间的关系
把这些概念串起来,它们的关系是这样的:
- 租户(Tenant)是顶层实体,一个租户下有多个用户。
- 用户下单(Order),选择某个计划(Plan)。
- 订单支付成功后,生成订阅(Subscription)。
- 订阅关联合同(Contract),合同规定了服务条款。
- 订阅进入生命周期,状态不断变化。
核心原则:数据模型要支持「多租户隔离」。每个租户的数据互不可见,这是SaaS的底线。
好了,这些核心概念搞清楚了,后面设计数据库和API时就会顺畅很多。下一章,咱们聊聊如何把这些模型落地到数据库里。