Is the customer.subscription.updated event raised when a subscription is renewed?
Asked Answered
L

3

35

I'm confused about why Stripe's documentation suggests the customer.subscription.updated event is not fired when I believe it should:

  • A Stripe subscription object has the properties current_period_start and current_period_end which would be updated whenever the customer successfully pays a subscription's invoices ( https://stripe.com/docs/api#subscriptions )
  • The documentation for the customer.subscription.updated event states that it...

    Occurs whenever a subscription changes. Examples would include switching from one plan to another, or switching status from trial to active.

    ...which would imply that the event would be raised if the current_period_start and current_period_end values change, but it doesn't affirm if it does or it does not in this case.

    However this third-party webpage states that it is not raised when a successful renewal is performed ( https://www.masteringmodernpayments.com/stripe-webhook-event-cheatsheet#8 ).

  • But raising the event just makes sense...

  • And certainly if applications only needed to monitor a single event type (i.e. customer.subscription.updated) then it would greatly simplify program code without needing to also monitor invoice.payment_succeeded, invoice.created and charge.succeeded.
  • However the documentation for the Subscription Lifecycle ( https://stripe.com/docs/subscriptions/lifecycle ) makes absolutely no mention of the customer.subscription.updated event at all.

It just seems odd that such an appropriate event is not raised when it should be. The documentation also really doesn't say when the current_period_end and current_period_start values are updated either, which limits their utility.

So in my application, after receiving an invoice.payment_succeeded event, how can my program code determine when the customer's subscription period will end next?

Lobation answered 11/10, 2016 at 8:12 Comment(0)
C
40

I've verified that customer.subscription.updated is called when the billing period ends.

To do this I intercepted all webhooks that occur at the end of the period (FYI: I used an AWS Lambda function that receives the events from an AWS API Gateway, then puts the events on an SQS queue :))

I agree that the Stripe documentation for the customer.subscription.updated event could be clearer and could cover this use case by saying....

Occurs whenever a subscription changes. Examples would include when the billing period ends and a new billing period begins, when switching from one plan to another, or switching status from trial to active.

(FYI: I would ignore the cheatsheet website altogether. They make only fleeting reference to customer.subscription.updated - In step 8 they are describing (poorly) the use case of "Create a customer with a plan without a trial" which wouldn't create a customer.subscription.updated event because this event only occurs when the subscription is updated, not when it is created. Where they do reference customer.subscription.updated is in context of Step 12 "Invoice charge attempt fails")

In defense of Stripes documentation regarding the lifecycle of a subscription, it does say "the following image shows the lifecycle of the most important events that occur" and I'd say customer.subscription.updated is not an important event in context of creating invoices and making payments.

Some details about how Stripe handles the end of a period:

  • In my test, Stripe raised the customer.subscription.updated event approximately 2 minutes after the timestamp in the current_period_end property on the subscription. The event has two data objects associated with it. The first is the subscription with the new values on it. The second is a previousAttributes object with the two previous current_period_start and current_period_end values.

  • Two events were generated simultaneously: customer.subscription.updated and invoice.created (this was the invoice for the period that had just elapsed).

  • Around an hour after the invoice was created, three events were generated simultaneously: invoice.payment_succeeded, charge.succeeded and invoice.updated.

How you treat the rollover of a billing period vs. the payment status of an invoice is really up to you, and very much depends on your application type. That's the beauty of the Stripe API (and it is a thing of beauty).

In my case, I treat the rollover of a billing period separately to the payment status of an invoice. My application cares about when the billing period rolls over and makes updates to usage based on this, but any payment failures generate alerts & are handled offline.

In summary, you can use customer.subscription.updated to know when the billing period has changed.

Carnassial answered 3/3, 2017 at 11:1 Comment(0)
P
5

customer.subscription.updated is triggered when current_period_start and current_period_end change. These represent the billing period.

When invoice.payment_succeeded happens, it's there that you must update the information on your side (e.g.: subscription period): https://stripe.com/docs/subscriptions/guide#step-3-sync-with-your-site

Also more info here: https://support.stripe.com/questions/what-events-can-i-see-when-a-subscription-is-renewed

Profession answered 14/10, 2016 at 22:8 Comment(2)
I would respectfully challenge the statement "When invoice.payment_succeeded happens, it's there that you must update the information on your side (e.g.: subscription period)" - IMHO deciding how to handle these events very much depends on the application behaviour you're trying to achieve. My preference would be to update the subscription on my side when Stripe tells me the subscription has been updated (the customer.subscription.updated event contains the subscription object). The invoice.payment_succeeded event contains the invoice object.Carnassial
Agree with @SimonCurd. This had me confused to begin with as well. I've decided to only modify the subscription when customer.subscription.updated is fired - nowhere else.Hospodar
H
0

In my experience, listening to the invoice.payment_succeeded webhook is the best way to know when a subscription is renewed.

That's because the customer.subscription.updated webhook is triggered an hour before the renewal payment is attempted. It'll update the subscription billing period regardless of the payment status. So during that hour, users will see a future renewal date thinking the payment went through when it could actually fail a few minutes later.

So if you want to determine when the customer's subscription period will end, I think you should retrieve the subscription's current_period_end inside of the invoice.payment_succeeded webhook. It is triggered when swapping subscriptions, including when downgrading and the amount due is 0. It's also triggered for metered billing renewals and when switching from a trial to an active subscription.

Heartbreaking answered 8/7 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.