logoPay4SaaS
核心概念

订阅生命周期

订阅不是"付钱就完了"——试用、激活、续费、升降级、取消、过期,每一步都有对应的状态和处理逻辑。Pay4SaaS 把这整套生命周期都管理好了。

状态流转

                      ┌─────────┐
                      │ pending │  ← 发起结账
                      └────┬────┘

                ┌──────────┴──────────┐
                ▼                     ▼
          ┌──────────┐          ┌──────────┐
          │ trialing │──付款──▶│  active  │◀── 续费成功 / 恢复订阅
          └──────────┘          └────┬─────┘

                 ┌───────────┬───────┼───────┬───────────┐
                 ▼           ▼       ▼       ▼           ▼
           ┌───────────┐ ┌────────┐ ┌──────┐ ┌────────┐
           │ canceling │ │ paused │ │expired│ │past_due│→ 按 expired 处理
           └─────┬─────┘ └────────┘ └──────┘ └────────┘

                 │ 到期

           ┌──────────┐
           │ canceled │
           └──────────┘

各状态说明

状态说明用户能否使用服务
pending已发起结账,等待支付
trialing试用期中是(无限订阅模式下可用)
active已付费,正常使用
canceling用户已取消,但当前周期未到期是(到期前仍可使用)
canceled已取消且已到期
expired已过期(付款失败或自然到期)
paused支付平台暂停了订阅,防止平台侧已停止扣款但用户仍能使用
past_due付款逾期,系统直接按过期处理

试用期

配置试用期后(见定价模式),用户首次订阅时可以免费试用。

关键规则:

  • 每个用户只能试用一次,系统通过 trial_start 字段追踪
  • 已试用过的用户再次订阅时,系统自动使用无试用版本的商品 ID
  • 试用期间,无限订阅模式下用户可以正常使用服务
  • 配额订阅模式下,没有试用这一回事,但你可以给用户送积分体验。
  • 试用期结束后自动扣款,扣款成功则转为 active

升级与降级

系统通过比较实际价格来判断升级还是降级:新价格 > 当前价格 = 升级,反之 = 降级。

升级(立即生效)

  • 新计划立即生效
  • 支付方式自动按比例计算差价(prorated)
  • 配额订阅模式下,配额按新计划重置

降级(下个周期生效)

  • 当前周期不变,保留原计划权益
  • 系统写入 pending_plan_typepending_plan_billing_cycle
  • 下次续费 Webhook 到达时,自动应用降级
  • 配额订阅模式下,当前周期保留原配额

前端可以通过 status.details 查看待生效的降级信息:

const { status } = useAccess()

if (status.details.pendingPlanType) {
  console.log(`下个周期将切换为: ${status.details.pendingPlanType}`)
  console.log(`生效时间: ${status.details.pendingPlanEffectiveAt}`)
}

取消与恢复

取消

取消分两种:

  • 到期取消(默认): 状态变为 canceling,当前周期结束前仍可使用,到期后变为 canceled
  • 立即取消: 状态直接变为 canceled,立即失效

恢复

用户在 canceling 状态下(还没到期)可以撤销取消:

  • 状态恢复为 active
  • 清除取消相关字段
  • 继续正常扣费

续费

续费是自动的。支付方式在每个计费周期结束前自动扣款,通过 Webhook 通知系统:

  1. 收到续费成功的 Webhook(如 invoice.paid
  2. 系统更新 current_period_startcurrent_period_end
  3. 如果有待生效的降级计划,此时自动应用
  4. 配额订阅模式下,重置月度配额

如果续费失败:

  1. 收到付款失败的 Webhook(如 invoice.payment_failed
  2. 系统将订阅状态标记为 expired,立即停止服务
  3. 支付方式后台会继续重试扣款
  4. 如果后续扣款成功,收到成功 Webhook 后自动恢复

重复订阅处理

如果用户在已有订阅的情况下又发起了一次订阅:

  • 相同计划: 延长到期时间(把新周期叠加到已有订阅上)
  • 不同计划: 取消旧订阅,激活新订阅

乱序保护

支付方式的 Webhook 可能乱序到达(比如"取消"先于"激活"到达)。系统通过以下机制防护:

  • 每个状态变更操作都检查当前状态是否允许转换
  • updateSubscriptionPeriod 只允许周期向前推进
  • expireSubscription 检查 current_period_end 是否已过
  • markSubscriptionCanceled 只允许从 active/trialing/canceling 转换

On this page