检测订阅是否自动取消

时间:2016-11-23 03:08:24

标签: stripe-payments

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

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

3 个答案:

答案 0 :(得分:4)

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

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

如果在付款失败太多后订阅被自动取消,那么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,就像在付款失败太多后自动取消一样。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我在这里遇到了同样的问题,根据这里找到的答案,我能够创建此代码段,它涵盖了原始问题的所有情况:

    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());
    }

希望这可以帮助其他人寻找它,因为这是google的第一个结果。