我设置了Stripe订阅,在3次付款尝试失败后自动取消,我有customer.subscription.deleted webhook来记录已取消的订阅。
有没有办法在customer.subscription.deleted webhook中检测是否由于付款尝试失败而被条带取消订阅,或者是否因为我们的应用程序发出的API请求而通过Stripe Dashboard手动取消或取消了?
答案 0 :(得分:4)
您无法区分最后两种情况,因为仪表板本身使用的是API。
但是,您可以区分自动和手动取消。只需查看request
事件正文中的customer.subscription.deleted
属性。
如果在付款失败太多后订阅被自动取消,那么request
将具有空值。
否则,如果通过API或信息中心取消订阅,request
将具有非空值:subscription cancelation request的请求ID("req_..."
)。
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的第一个结果。