问题
I have setup my Stripe subscriptions to be automatically cancelled after 3 failed payment attempts and I have customer.subscription.deleted webhook to record the cancelled subscription.
Is there a way to detect in customer.subscription.deleted webhook if subscription is cancelled by stripe because of failed payment attempts OR manually cancelled through Stripe Dashboard OR cancelled because of an API request made from our application?
回答1:
You can't differentiate between the last two cases, as the dashboard itself uses the API.
However, you can differentiate between automatic and manual cancelations. Simply look at the request attribute in the customer.subscription.deleted event's body.
If the subscription was canceled automatically after too many failed payments, then request
will have a null value.
Otherwise, if the subscription was canceled through the API or the dashboard, request
will have a non-null value: the request ID ("req_..."
) of the subscription cancelation request.
EDIT: as Yoni Rabinovitch pointed out, the above is true if the subscription was canceled with at_period_end=false
(or no at_period_end parameter, as false
is the default value).
If the subscription was canceled with at_period_end=true
, then a customer.subscription.updated
event would be fired immediately (to reflect the fact that the subscription's cancel_at_period_end attribute is now true), and that event's request
would have the request ID of the subscription cancelation request.
However, the customer.subscription.deleted
event that would be sent when the subscription is actually canceled at the end of the billing period would have request=null
, just like an automatic cancelation after too many failed payements.
回答2:
If you instead cancel a subscription at the end of the billing period, a customer.subscription.updated event is immediately triggered. That event reflects the change in the subscription’s cancel_at_period_end value. When the subscription is actually canceled at the end of the period, a customer.subscription.deleted event then occurs.
回答3:
I came here with the same questions, Based on the answers found here I was able to create this snippet of code, it covers all the cases on the original question:
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());
}
Hope this helps someone else looking for this since this is the first result that comes up in google.
来源:https://stackoverflow.com/questions/40755353/detect-if-subscription-is-cancelled-automatically