使用 Stripe 恢复订阅(并对之前未付费的服务收费)

Posted

技术标签:

【中文标题】使用 Stripe 恢复订阅(并对之前未付费的服务收费)【英文标题】:Resuming a subscription with Stripe (and charging for previously unpaid service) 【发布时间】:2015-04-08 03:33:00 【问题描述】:

我有一个网络服务,它为我的用户发布和托管某些信息。每个用户的编辑界面与他们发布的信息是分开的。我正在使用 Stripe 订阅为其付费,但我无法想出一种可行的方式来处理未付费订阅。这是我要实现的逻辑:

    在第一次失败的计费尝试时,我的应用程序应该锁定用户的编辑界面;相反,它应该为他们提供一个页面,其中包含解决其付款问题的选项。但是,他们发布的信息仍会发布,因此延迟付款不会影响访问者的活动。 在 15 天后的最后一次计费尝试失败后,我的应用程序也应该删除他们发布的信息。此时,用户的编辑界面被替换为允许他们使用新信用卡重新激活帐户或完全删除帐户的界面。 如果用户选择重新激活帐户,他们不应获得试用期 如果用户重新激活,他们还应该支付他们之前跳过的 15 天的费用,方法是将他们的第一个计费周期缩短 15 天,或者将等于 15 天服务的费用添加到他们的第一张账单。

如果我注意正确的 webhook,#1 和 #2 很容易实现 — 只需将拖欠客户或已删除或未付费订阅的客户的请求重定向到“修复此问题”页面。 #3 也很简单——只需创建订阅并将trial_end 设置为now

#4 很棘手。我如何确定用户的最后一张发票在取消订阅之前未支付的确切时间?如何缩短新订阅的第一个计费周期?或者,我如何按比例分配客户的最后一张发票总额以代表我实际提供给他们的部分,以便我可以将该金额添加到新发票中? (我知道我可以在开始新订阅之前创建一个发票项目来收取金额,所以至少这是可能的。)

最后,Stripe 的“标记未付费订阅”选项是否有助于解决这些问题?看起来它一直在创建发票,但没有尝试为它们收费;我不认为这就是我想要的。

【问题讨论】:

【参考方案1】:

您绝对可以通过 Stripe 的订阅来完成所有这些工作。正如您所提到的,前两个问题应该通过 webhook 解决。您会在您的终端上收听invoice.payment_failed,以检测何时付款失败并立即阻止您的 UI 要求您的客户更新他们的卡详细信息。

要更新他们的卡详细信息,您可以使用Stripe Checkout,但不要设置data-amount 参数,这样它就不会向您的客户显示价格。这是一个例子:

<form action="/charge" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="pk_test_XXXX"
    data-image="/square-image.png"
    data-name="Demo Site"
    data-description="Update Card Details"
    data-panel-label="Update Card Details"
    data-label="Update Card Details">
  </script>
</form>

每次您的客户尝试更新他的卡时,您都将使用Update Customer API 并在card 参数中传递新卡令牌。这将删除客户的默认卡并将其替换为新卡。它还将尝试支付处于“过期”状态的每个订阅的最新发票。在您的情况下,这意味着将尝试支付仍处于重试模式的最新发票。这不算重试,可以看作是独立的。如果成功,您只需重新启用 UI,否则您将继续要求客户更新他的卡详细信息。

如果您在dashboard 的重试设置中进行了设置,那么当您第四次付款失败时,您将收到customer.subscription.canceled。您可以通过检查事件上的request 键并确保它是null 来检测它是自动取消。在这种情况下,您会为您的客户完全阻止用户界面/帐户。

在过去的 15 天里,如果我正确理解了您的流程,客户并没有真正能够使用您的应用程序,因为您部分锁定了 UI。但是,如果您仍然希望他支付这笔费用,您应该在您的数据库中存储客户在他无法使用订阅的 15 天内欠您 X 美元。

稍后,您的客户终于回来并希望重新启用他的帐户。那时您通知他付款流程将从今天开始您将向他收取他之前错过的额外 15 天的费用。为此,我将使用Invoice Items,这将允许您自动向第一张发票添加额外金额。您将按照以下步骤操作:

    Create 为您的客户提供 $X 的发票项目。 Create 新订阅您的计划设置 trial_end"now",以防您的计划默认设置了试用期。 这将自动为计划金额创建第一张发票并添加之前创建的发票项目。

这里的另一个解决方案是重新打开他们最近关闭的未付款发票并使用Pay Invoice API。发生这种情况时,您知道您的客户现在向您支付了整整一个月的费用,而不仅仅是他欠您的 15 天。在这种情况下,您将创建一个新订阅并设置 15 天的试用期,以便他在试用后再次开始付款。

我不会在这里使用“标记为未付款”选项,因为您将客户完全锁定在您的应用程序之外。当您让您的客户使用您的应用程序并计划在几个月内向他收取每张发票的费用时,我会使用此功能。这将用于电力供应商,例如,他们会在多个计费周期内保持您的电力供应,并继续尝试为每张发票向您收费。

在这种情况下,您的客户实际欠您的金额取决于您允许的重试次数以及每次重试之间的天数。您可以在这里做的是使用发票上的created 值并将其与您获得customer.subscription.canceled 时的当前时间进行比较,以确定经过了多少时间并计算您的客户当时欠您多少的比例。

【讨论】:

以上是关于使用 Stripe 恢复订阅(并对之前未付费的服务收费)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Stripe Firebase 扩展 Webhook 运行订阅付款未触发

立即收取订阅更改费用

如何使用条带测试卡测试订阅中的“未付费”和“未完成”状态?

订阅取消后 Stripe API 退款

跨帐户恢复购买

使用 Stripe 订阅 Node.js 进行身份验证