Using customer.subscription.update instead of invoice.paid and invoice.payment_failed event webhooks to handle Stripe Subscriptions

Viewed 902

I'm trying to build a simple Subscriptions website with three or four different plans using Stripe.

In the application when a user registers, a Stripe Customer ID is assigned. Then, when subscribing to a plan, I'm listening to these webhook events:

customer.subscription.updated || customer.subscription.created

They are triggered every time there's a change in the subscription. Then I check the status property which will tell me if the user is active, incomplete, trialing, canceled, past_due, or unpaid and act accordingly in my database table for users.

This makes sense to me, but Stripe uses invoice event webhooks instead (https://stripe.com/docs/billing/subscriptions/checkout#provision-and-monitor):

  • checkout.session.completed
  • invoice.paid
  • invoice.payment_failed

Should I listen to these events instead? I'm not sure, because, for example, invoice events won't track when a customer changes the plan in the middle of a billing cycle, so I'd have to add the customer.subscription.updated webhook anyways.

1 Answers

It's really up to you and what your integration needs (there are a lot of different webhook events, and many of them can be used for the same purpose). Typically, users care more about knowing when the renewal invoice is actually paid which is why that guide recommends those events as the bare minimum. If you had a subscription where you were sending goods to a customer every month it makes more sense to listen for confirmation of successful invoice payment before shipment.

That being said, you definitely can rely on customer.subscription.updated events but you'll need to also listen for the invoice.paid/payment_failed events if you care about knowing when payment succeeds or want to notified of retries. Take the situation where your subscription renews and payment is successful:

  1. First, you'll get the customer.subscription.updated event signaling that the billing cycle has changed and a draft invoice has been created (this will also send an invoice.created event).
  2. After an hour the invoice is finalized and paid automatically
  3. Your webhook endpoint gets an invoice.paid webhook event, but not another customer.subscription.updated event because the status was active and has not changed.
Related