【问题标题】:Detect if subscription is cancelled automatically检测订阅是否自动取消
【发布时间】:2017-04-06 22:11:48
【问题描述】:

我已将我的 Stripe 订阅设置为在​​ 3 次付款尝试失败后自动取消,并且我有 customer.subscription.deleted webhook 来记录取消的订阅。

有没有办法在 customer.subscription.deleted webhook 中检测订阅是否因付款尝试失败而被条带取消,或通过条带仪表板手动取消或因我们的应用程序发出 API 请求而被取消?

【问题讨论】:

    标签: stripe-payments


    【解决方案1】:

    如果您改为在计费期结束时取消订阅,则会立即触发 customer.subscription.updated 事件。该事件反映了订阅的 cancel_at_period_end 值的变化。当订阅在该期限结束时实际取消时,会发生 customer.subscription.deleted 事件。

    【讨论】:

      【解决方案2】:

      您无法区分最后两种情况,因为仪表板本身使用 API。

      但是,您可以区分自动取消和手动取消。只需查看customer.subscription.deleted 事件正文中的request 属性即可。

      如果在多次付款失败后自动取消订阅,则request 将具有空值。

      否则,如果通过 API 或仪表板取消订阅,request 将有一个非空值:subscription cancelation request 的请求 ID ("req_...")。

      编辑:正如 Yoni Rabinovitch 所指出的,如果使用at_period_end=false(或没有at_period_end 参数,因为false 是默认值)取消订阅,则上述情况为真。

      如果使用at_period_end=true 取消订阅,则将立即触发customer.subscription.updated 事件(以反映订阅的cancel_at_period_end 属性现在为真),并且该事件的request 将具有请求取消订阅请求的 ID。

      但是,在计费周期结束时实际取消订阅时将发送的 customer.subscription.deleted 事件将具有 request=null,就像在太多失败的付款后自动取消一样。

      【讨论】:

      • 太棒了!非常感谢。 “请求”属性将为我完成工作。谢谢。
      • 从我可以看到,如果订阅在订阅期结束时自动取消,则 customer.subscription.deleted 事件中的请求属性为 null,因为订阅上的 cancel_at_period_end 设置为 true。因此,检查“请求”属性似乎不足以确定订阅因付款失败而被取消。
      • @YoniRabinovitch 你完全正确。我编辑了我的答案以指定在这种情况下会发生什么。
      【解决方案3】:

      我带着同样的问题来到这里,根据在这里找到的答案,我能够创建这个代码的 sn-p,它涵盖了原始问题的所有案例:

          try {
              \Stripe::setApiKey(config('services.stripe.secret'));
              \Stripe::setApiVersion(config('services.stripe.version'));
      
              $endpoint_secret = config('services.stripe.invoice_webhook_secret');
              $request = @file_get_contents('php://input');
              $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'] ?? null;
      
              $event = \Stripe\Webhook::constructEvent(
                  $request,
                  $signature,
                  $endpoint_secret
              );
      
              //$event->type is: "customer.subscription.deleted"
              //Keep in mind that you can change the settings in stripe 
              //so failed payments cause subscriptions to be left as unpaid instead
              //of cancelled, if those are your settings this event will not trigger
      
              $subscription = $event->data->object;
      
              if ( !empty($event->request->id)) {
                  //the request was made by a human
      
      
              }elseif ( !empty($subscription->cancel_at_period_end)) {
                  //the request was empty but the subscription set to cancel
                  //at period end, which means it was set to cancel by a human
      
      
              }else{
                  //the request was empty and
                  //NOT set to cancel at period end
                  //which means it was cancelled by stripe by lack of payment
      
      
              }
      
          } catch ( \Exception $e ) {
              exit($e->getMessage());
          }
      

      希望这可以帮助其他人寻找这个,因为这是谷歌出现的第一个结果。

      【讨论】:

        猜你喜欢
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 2011-01-06
        • 2016-12-16
        • 1970-01-01
        • 2017-05-23
        • 2014-11-18
        • 1970-01-01
        相关资源
        最近更新 更多