Stripe:在“期末”降级用户

时间:2013-05-29 17:21:37

标签: stripe-payments downgrade temboo

是否可以在期末而不是立即降级用户?我已经梳理了API Docs,但未能弄清楚如何实现这一目标。

作为一种解决方法,我目前正在取消用户的订阅,然后订阅较少的订阅,试用到月底。这不会起作用 - 我需要能够将降级延迟到期末(但在请求降级时“记录”它与Stripe)。

显然,有很多方法可以通过webhook回调和本地跟踪用户订阅来实现这一目标,但我希望尽可能避免这种情况。


修改

在有人要求之前 - 我正在使用Temboo的PHP SDK。但是,我不是在寻找一种特定于语言的方法,只是一种高级的方法(如果可能的话)。

9 个答案:

答案 0 :(得分:11)

正如@Safinn和@Martin所提到的,您可以使用at_period_end: true取消订阅,以便在特定日期执行取消操作。

为了降级到不同的计划,我解决它的方法是执行上述操作,然后创建一个以相同日期/时间结束的新计划的免费试用版。这样,旧计划将在新计划试验结束的同一天取消(使其生效)。

这让Stripe完全处理降级(这应该是更直接的恕我直言),而不是在数据库中设置webhooks或跟踪日期。

答案 1 :(得分:4)

您应该跟踪用户何时加入计划 - 在customer_id旁边的数据库中保留一个日期字段。您可以使用此日期来确定他们加入的月份的日期,从而确定结算周期。如果结算日是该月的第31天,则在较短的月份,Stripe将在这些月份的最后一天(https://support.stripe.com/questions/subscription-date-at-end-of-month)收费。

现在,当用户希望降级时,他们会在登录时完成您网站上的操作。您注意到此降级请求并将其存储在a中,我们称之为" stripe_actionable_table"在您的数据库中。此表中的重要字段为:

  • actionable_date (Stripe请求的操作日期 - 您需要一些逻辑来确定上述较短的月份)
  • stripe_customer_id
  • what_to_do (升级/降级/取消)
  • change_plan_to (计划ID - 如果取消请求,则可以为null)

然后您将拥有一个在特定时间每天运行的cron,并检查此stripe_actionable_table,如果该月中的某一天与表中的行匹配,则执行Stripe请求。完成后,您可以将该行删除或标记为已删除。

答案 2 :(得分:3)

是,使用最新版本的API。

  • 创建具有多个定价计划的产品
  • 为客户订阅这些计划ID之一
  • 将客户更新为新计划时,只需执行以下操作:

    $subscription = \Stripe\Subscription::retrieve($sub);
    \Stripe\Subscription::update($sub, [    
        'cancel_at_period_end' => false,
        'items' => [
            [
                'id' => $subscription->items->data[0]->id,
                'plan' => $plan,
            ],
        ],
        'prorate' => false,
        'trial_end' => $subscription->current_period_end
    ]);
    $subscription->save();
    

通过将prorate设置为false,将trial_end设置为$subscription->current_period_end,将cancel_at_period_end设置为false,可以有效地告诉Stripe:

  

请在该用户当前的帐单到期(在期末取消)之前向该用户收费,不要在计划开关(按比例分配)上退还任何款项,并在其当前帐单周期结束时重新开始计费(试用)结束。)

当旧计划结束时,这具有将帐单更改为新计划的效果。

答案 3 :(得分:2)

现在可以使用Stripe的prorate标志。

E.g。

$subscription = \Stripe\Subscription::retrieve("sub_44ty4267H50z6c");
$itemID = $subscription->items->data[0]->id;

\Stripe\Subscription::update("sub_44ty4267H50z6c", array(
  "items" => array(
    array(
      "id" => $itemID,
      "plan" => "basic-plan",
    ),
  ),
  "prorate" => false,
));

通过将prorate设置为false,您实际上是在告诉Stripe在当前期间结束之前不要应用计划更改。

官方文件:

https://stripe.com/docs/subscriptions/upgrading-downgrading#disable-prorations

澄清(根据下面的用户评论):请注意,Stripe 立即更新自己的活动计划的表示(仅限收费)用户被延期),因此您仍需要手动管理从您自己的应用程序中延迟活动计划更改。

答案 4 :(得分:1)

Stripe最近引入了可解决此问题的订阅计划:https://stripe.com/docs/api/subscription_schedules

答案 5 :(得分:0)

使用Stripe似乎没有办法轻松完成。

我正在更新数量而不是更改计划,但也可以应用这个想法。

可能的解决方案是:

  1. 使用Stripe更新订阅数量而无需按比例分配。

  2. 将之前的数量保留到invoice.created事件。

  3. 处理invoice.created事件时,请将之前的数量与用户订阅的数量进行比较,并在必要时将其减少。

答案 6 :(得分:0)

这就是我的方法。

我只是取消了现有的订阅,该订阅将在当前结算周期结束。取消之时,我将请求的客户降级计划ID保存在我的本地用户表中。

然后,我为stripe中的customer.subscription.delete设置了一个Webhook,并创建了一个处理程序,该处理程序将只从本地用户表中选择已保存的降级计划,并立即使用该计划创建新的订阅。

答案 7 :(得分:0)

这里介绍的大多数解决方案看起来像条纹发布订阅时间表后的骇客,这可能是最优雅的解决方案。实际上,条带文档中有一个示例说明了完全相同的场景here

第1步:从您要降级的现有订阅中获得current_period_end值。

第2步:从现有订阅中创建新的订阅时间表。

$subscriptionSchedule = $stripe->subscriptionSchedules->create([
  'from_subscription' => 'sub_G678SASEGF',
]);

步骤3:分两个阶段更新新创建的计划。 phase 0是当前阶段,以current_period_end结束,而phase 1是下一个阶段,该阶段以降级的价格计划从current_period_end开始。

$stripe->subscriptionSchedules->update(
  $subscriptionSchedule->id,
  [ 
    'end_behavior' => 'release',
    'phases' => [
      [
        'start_date' => $current_period_start,
        'end_date' => $current_period_end,
        'plans' => [
          [
            'price' => $current_price_id
          ],
        ],
      ],
      [
        'start_date' => $current_period_end,
        'plans' => [
          [
            'price' => $downgraded_price_id,
          ],
        ]
    ],
  ],
]

您始终可以检查订阅对象以查看是否有活动的日程表,然后检索日程表以利用将来的任何降级。这种方法的优点是可以应用于任何降级和/或计费周期更改。使用答案中前面所述的多计划方法,一个订阅只能包含具有相同计费周期的项目。

答案 8 :(得分:-1)

  

如果您想要在当前结算周期结束时取消订阅(即,在客户已付款的时间内),请提供at_period_end值true

https://stripe.com/docs/subscriptions/canceling-pausing

我认为您可以更新订阅并添加at_period_end: true,并且应该在期末取消订阅。