laravel / cashier-stripe

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.
https://laravel.com/docs/billing
MIT License
2.37k stars 670 forks source link

[14.x] Update Subscription.php #1623

Closed logcastelli closed 8 months ago

logcastelli commented 8 months ago

When the Stripe customer's panel is configured to cancel immediately, the Webhook does not set the "ends_at" field, only the stripe_status is changed to "canceled".

Therefore, the canceled() method returns false when in fact the subscription is canceled. With this change, the method also takes into account when the "stripe_status" field is canceled.

image

image

driesvints commented 8 months ago

Hi @logcastelli. Trying to wrap my head around this...

  1. Could you please post a full payload of the event you mention? Is it subscription updated or deleted event?
  2. Does the subscription deleted event come in at all?
logcastelli commented 8 months ago

Hi @driesvints!

This event is received when the customer unsubscribes via Stripe's customer portal.

When the option in the portal configuration is: "Cancel at end of billing period" stripe sends an event of type "customer.subscription.updated" to the webhook.

Screenshot 2023-12-20 at 08 21 02

When the option is: "Cancel immediately" stripe sends an event of type "customer.subscription.deleted"

Screenshot 2023-12-20 at 08 21 14

As you can see in the "customer.subscription.deleted" cancel event the "cancel_at" field is null

In practice, this means that a subscription canceled on the Stripe portal configured with the "Cancel immediately" option continues to return as active and the Billable Model continues with the subscribed option equal to "true".

Full payloads below

customer.subscription.deleted.txt customer.subscription.updated.txt

driesvints commented 8 months ago

@logcastelli but the cancel_at doesn't matter. The incoming customer.subscription.deleted event is handled here:

https://github.com/laravel/cashier-stripe/blob/0d38b0c24cc761f53dfcbc9d74b6ba40d61c8964/src/Http/Controllers/WebhookController.php#L217

Which in turn calls:

https://github.com/laravel/cashier-stripe/blob/0d38b0c24cc761f53dfcbc9d74b6ba40d61c8964/src/Subscription.php#L1072

Which will fill out the ends_at. The only reason I see that not happening for you is if you're not sending the event to your webhook endpoint. Could you maybe verify that you're receiving the event in your app?

Maybe I'm missing something else but the subscription should definitely be canceled.

logcastelli commented 8 months ago

I checked here and the webhook should indeed set the ends_at field.