首页 / 内容指南 / 当前文章

Stripe Subscription 的 incomplete、incomplete_expired、trialing、active、past_due、unpaid、paused 和 canceled 有什么区别?

发布于 2026-08-26 · deliwaimao.cn 编辑部

Stripe 订阅对象的 status 不是一条简单的“成功/失败”布尔值。incomplete 表示首张账单仍需完成付款;incomplete_expired 表示首期付款窗口过期且订阅不能再继续;trialing 表示正在试用;active 表示订阅处于正常服务状态;past_due 表示到期款项未成功但仍处于催收/重试阶段;unpaid 表示已进入不再自动推进账单付款的欠费状态;paused 表示试用结束时按特定配置暂停订阅;canceled 表示订阅已经终止。

本文目录(19 节)

八种状态快速对比

↔ 表格可左右滑动查看完整内容
状态常见进入原因是否可能继续开通服务主要下一步
incomplete创建订阅后的首期付款未完成通常等待支付,不宜直接当已付费完成 PaymentIntent 或处理认证
incomplete_expired首期付款长期未完成通常不应开通新建订阅/Checkout 流程
trialing免费试用尚未结束按试用政策可开通提醒结束时间并准备付款方式
active试用或有效计费周期正常通常开通持续监听账单与状态变化
past_due续费账单付款失败由宽限期策略决定催收、重试、更新付款方式
unpaid重试策略最终进入欠费通常限制或暂停服务收款后恢复或创建新流程
paused试用结束无付款方式且配置为暂停通常暂停付费权益添加付款方式并恢复订阅
canceled立即取消或到期取消完成通常停止服务记录终止并处理重订阅

状态机不是只看 Subscription 一个对象

创建和续费会同时涉及 Subscription、Invoice、PaymentIntent、PaymentMethod 与 Customer。Subscription 状态回答“订阅生命周期在哪一阶段”,Invoice 状态回答“账单是否 draft/open/paid/void/uncollectible”,PaymentIntent 状态回答“具体付款是否需要支付方式、客户操作、确认或已成功”。

因此 incomplete 不等于 PaymentIntent 的某个固定状态,past_due 也不等于账单已经永久坏账。诊断时应沿以下关联链查看:

Subscription.latest_invoice
  -> Invoice.payment_intent(适用时)
  -> PaymentIntent.status / last_payment_error

不同付款方式和 Stripe 版本可能改变细节。应用应展开或再次查询关联对象,不要根据订阅状态猜测具体拒付码。

incomplete:首张账单还没有完成

创建需要立即付款的订阅时,如果使用允许未完成首期付款的 payment_behavior,Subscription 可以先进入 incomplete。这给客户完成 3DS、补充付款方式或处理异步付款留出机会。

此时订阅记录已经存在,但不能把它等同于“已付费会员”。最安全的权益策略通常是等待 invoice.paid 或订阅达到符合业务规则的 active,同时核对账单金额是否为预期。

前端可能拿到与首张 Invoice 相关的 PaymentIntent client secret,完成必要的客户动作。服务端仍需通过 Webhook 确认结果;浏览器跳转成功、客户端 confirm 返回或用户到达 success URL 都不能单独作为最终入账依据。

重复创建订阅会产生多个 incomplete 对象。应为业务订购操作使用幂等键,并在数据库保存 Stripe Subscription ID,恢复原流程而不是每次重试都新建。

incomplete_expired:首期付款窗口已失效

incomplete 不会无限等待。如果首张账单未在 Stripe规定的窗口内成功,订阅会转为 incomplete_expired。Stripe 文档通常描述这一窗口约为 23 小时,具体行为应以当前官方文档和对象时间戳为准。

该状态是终止状态,相关未完成账单会按 Stripe 规则处理,不能再通过简单确认旧 PaymentIntent 把同一订阅恢复成 active。通常应让客户重新开始订阅创建流程。

不要通过手工修改本地数据库把它改成 active。应创建新的合法计费对象并重新完成付款。历史 incomplete_expired 对象仍应保留用于审计、漏斗和重复请求分析。

trialing:试用正在进行

trialing 表示订阅处于试用期。是否开放功能取决于你的试用政策,但 Stripe不会自动替应用限制功能。应以 Subscription ID 和 Customer 绑定权益,避免仅凭可伪造的前端试用结束时间判断。

试用创建时可以要求付款方式,也可以允许无付款方式。试用结束时的行为取决于缺失付款方式设置:可以取消、暂停,或根据配置创建账单并进入后续状态。必须在创建订阅前决定,不能等试用结束后才假设默认行为。

试用提醒、税务要求、支付方式收集和法规通知也要按业务地区处理。测试可使用 Test Clocks 推进时间,而不是等待真实天数;测试时仍需监听与生产相同的事件类型。

active:处于正常订阅状态

active 通常表示订阅已开始正常服务,或无需立即付款的订阅满足当前条件。它是开通权益的重要信号,但不保证“每一分钱都已最终不可撤销”。退款、争议、异步支付逆转和后续账单失败仍可能发生。

有些零金额账单、优惠、试用结束或无需付款的场景可以让订阅进入 active,而没有一次常规卡扣款。因此不要把 active 解释为“最新 Charge 一定存在”。若业务必须确认现金到账,应同时检查 Invoice 的 paid 状态和金额。

计划在周期末取消的订阅,设置 cancel_at_period_end=true 后,在当前周期结束前通常仍保持 active 或其他当前状态。cancel_at_period_end 是取消计划,不是新的 status

past_due:已逾期但仍在恢复流程中

续费 Invoice 付款失败后,Subscription 常进入 past_due。Stripe 可以根据重试和催收设置再次尝试,向客户发送通知,并等待更新付款方式。

这一状态是否继续提供服务属于业务决策。有的产品立即降级,有的提供数天宽限期。无论如何,都应把策略写成显式权益状态,而不是散落在多个 Webhook Handler 里。

客户更新默认付款方式后,应用可能需要按当前账单与 Stripe配置触发或等待重新付款。只更新 Customer 默认付款方式不代表旧 Invoice 已经自动 paid。应查询 Invoice 和 Subscription 的最新状态。

past_due 的持续时间与最终去向受自动催收设置影响,可能继续 past_due、转为 canceled、unpaid,或在付款成功后恢复 active。不能写死“失败三次就取消”之类假设。

unpaid:欠费且自动推进受限

unpaid 通常表示重试策略结束后,订阅仍欠费并被配置进入该状态。后续 Invoice 可能继续生成但会立即关闭或不再正常自动收款,具体以 Stripe Billing 配置为准。

业务通常应暂停付费权益,并向客户提供更新付款方式与结清账单的路径。支付成功后是否自动恢复、需要手工 reopen Invoice,还是创建新订阅,应依据当前账单状态和恢复设计,不要只把 Subscription status 在本地改成 active。

unpaidpaused 不同:unpaid 来源于欠费催收结果;paused 是订阅状态机中由试用结束缺少付款方式等特定设置触发的暂停状态。

paused:订阅状态真正暂停

当试用结束且没有付款方式,并且 trial_settings.end_behavior.missing_payment_method 配置为 pause 时,Subscription 可以进入 paused。在此状态下不会为订阅生成 Invoice,直到恢复。

恢复通常需要先为 Customer 添加可用付款方式,再调用恢复订阅的相应 API,并明确恢复计费周期、按比例计费和账单处理方式。恢复是计费操作,必须使用幂等与 Webhook 确认。

状态 paused 经常与 pause_collection 混淆。pause_collection 是暂停收款的配置,Subscription 的 status 仍可能保持 active;期间 Invoice 的处理由 behavior(如 keep_as_draft、mark_uncollectible、void)决定。它不等于 status=paused

canceled:订阅已经结束

立即取消会使 Subscription 进入 canceled。周期末取消则先设置 cancel_at_period_end,订阅在当前周期结束前通常仍可用,到期后才变成 canceled。

取消时应明确是否按比例计费、是否开最终 Invoice、如何处理未开票使用量、余额与未支付 Invoice。直接删除订阅并不会自动替业务完成所有退款或数据删除。

canceled 通常不能恢复为原来的活动订阅。客户回流时一般创建新订阅;如果只是计划周期末取消而尚未真正 canceled,可以在到期前撤销取消计划。

权益撤销不要只依赖一个事件。Webhook 可能延迟、重复或乱序,应用应获取对象最新版本并执行幂等状态投影,必要时以 current_period_end、取消字段和最新 Invoice共同判断。

paused 与 pause_collection 的详细区别

↔ 表格可左右滑动查看完整内容
项目status=pausedpause_collection
本质Subscription 生命周期状态收款行为配置
常见入口试用结束无付款方式且配置 pause主动暂停收取已存在订阅的账单
Subscription statuspaused通常不变为 paused
Invoice 生成暂停期间不生成仍可能生成,按 behavior 处理
恢复方式调用恢复订阅流程取消/修改 pause_collection 配置
权益策略通常暂停由业务与暂停原因决定

客服后台必须分开显示这两种情况。只显示“已暂停”会让运营误以为没有 Invoice,实际可能持续创建 draft 或 void 账单。

Webhook 应监听哪些事件

不要只监听 customer.subscription.updated。完整订阅系统通常至少关注:

  • customer.subscription.created:记录订阅建立及初始状态;
  • customer.subscription.updated:状态、周期、取消和暂停字段变化;
  • customer.subscription.deleted:订阅进入取消结果;
  • invoice.created/finalized:账单生成与定稿;
  • invoice.paid:账单成功支付,可用于开通或续期;
  • invoice.payment_failed:付款失败,进入催收与通知;
  • invoice.payment_action_required:需要客户认证的相关流程;
  • customer.subscription.trial_will_end:试用即将结束提醒。

事件类型和可用字段应以当前 Stripe API 版本为准。Webhook 到达顺序不能作为唯一事实顺序;处理器应验证签名、按 Event ID 幂等,并在关键转换时重新读取 Stripe 对象。

权益状态不要直接等于 Stripe status

建议在应用中建立独立权益状态,例如 PENDING_PAYMENTTRIAL_ACCESSPAID_ACCESSGRACE_PERIODSUSPENDEDENDED。映射由业务规则驱动:

incomplete           -> PENDING_PAYMENT
trialing             -> TRIAL_ACCESS
active + invoice paid -> PAID_ACCESS
past_due             -> GRACE_PERIOD 或 SUSPENDED
unpaid/paused        -> SUSPENDED
canceled             -> ENDED(或到期后结束)

这只是示例,不是 Stripe 强制规则。应用还要考虑周期结束时间、退款、争议、免费方案、手工赠送权益和企业合同。映射版本应可审计,避免运营修改催收设置后权益逻辑悄悄变化。

常见状态转换路径

首期立即付款

创建 -> incomplete -> active
                   -> incomplete_expired

有试用期

trialing -> active
         -> paused(缺付款方式且配置 pause)
         -> canceled(缺付款方式且配置 cancel)

续费失败

active -> past_due -> active(补款成功)
                   -> unpaid / canceled(按催收配置)

真实路径还受免费账单、异步支付、手工发票、收款方式和 API 设置影响。状态图用于理解,不能替代对象与事件验证。

一套可执行的测试矩阵

  1. 首期付款成功、卡被拒、需要 3DS、用户放弃认证。
  2. incomplete 在有效期内恢复,以及超时进入 incomplete_expired。
  3. 带付款方式和不带付款方式的试用结束。
  4. missing payment method 分别配置 cancel、pause 等行为。
  5. 续费首次失败、重试成功、重试最终进入 unpaid 或 canceled。
  6. 设置和解除 pause_collection,检查 Invoice 行为与 Subscription status。
  7. 立即取消、周期末取消、到期前撤销取消。
  8. Webhook 重复、乱序、延迟和处理失败后的重放。

使用 Test Clocks 和测试支付方式推进场景,断言 Stripe 对象、内部权益、通知和会计记录四者一致。不要用 Dashboard 手工点击作为唯一回归测试。

常见误区

  • 创建出 Subscription ID 就立即开通付费权益。
  • incomplete 当作续费失败;它主要描述首期付款未完成。
  • 认为 incomplete_expired 可以继续确认原付款并自动恢复。
  • past_due 写死为固定重试次数和天数。
  • 混淆 status=pausedpause_collection
  • 设置 cancel_at_period_end 后立刻把状态显示为 canceled。
  • 只处理 Subscription Webhook,不处理 Invoice 付款事件。
  • 依据 success URL 开通服务,而不等待服务端确认。

FAQ

1. incomplete 时可以给用户开通服务吗?

通常不应把它当已付款。可以给受限的付款完成页面,但付费权益应等待 Invoice paid 或符合业务规则的 active 状态。

2. incomplete_expired 能恢复吗?

它是终止状态,通常需要重新创建订阅流程。不要尝试只修改本地状态或继续使用过期的首期付款上下文。

3. active 是否保证款项不可撤销?

不保证。退款、争议、异步支付逆转和未来续费失败仍可能发生。需要现金确认时同时检查账单与交易对象。

4. past_due 期间应该立即停服吗?

Stripe 不替你决定。可以设置宽限期或立即限制,但应形成明确、可审计的权益策略,并与催收通知一致。

5. unpaid 和 canceled 有什么区别?

unpaid 表示订阅欠费且收款推进受限,记录仍表达欠费关系;canceled 表示订阅已经终止。恢复流程和账单处理不同。

6. pause_collection 会让 status 变成 paused 吗?

通常不会。它是收款行为配置;真正的 paused status 多与试用结束缺少付款方式并选择 pause 有关。

7. cancel_at_period_end=true 后 status 是什么?

到期前通常仍是 active、trialing 或其他当前状态,只是计划在周期末取消。真正到期后才进入 canceled。

8. 只监听 customer.subscription.updated 够吗?

不够。付款成功/失败、需要客户操作和账单生命周期来自 Invoice 等事件。应建立幂等、多事件的状态投影。

结论

incompleteincomplete_expired 管理首期付款,trialingactive 表示正常试用或服务,past_dueunpaid 表示不同阶段的欠费恢复,paused 是特定暂停状态,canceled 是终止结果。把 Stripe 状态机与内部权益、Invoice 和 PaymentIntent 分开建模,才能安全处理首付、续费、暂停与取消。

参考来源

  1. Stripe Docs, The subscription lifecycle and statuses: https://docs.stripe.com/billing/subscriptions/overview
  2. Stripe API Reference, The Subscription object: https://docs.stripe.com/api/subscriptions/object
  3. Stripe Docs, Using webhooks with subscriptions: https://docs.stripe.com/billing/subscriptions/webhooks
  4. Stripe Docs, Use trial periods on subscriptions: https://docs.stripe.com/billing/subscriptions/trials
  5. Stripe Docs, Pause payment collection: https://docs.stripe.com/billing/subscriptions/pause-payment
  6. Stripe Docs, Manage failed payments: https://docs.stripe.com/billing/revenue-recovery
  7. Stripe Docs, Test subscriptions with simulation clocks: https://docs.stripe.com/billing/testing/test-clocks