#windlepoons-webhooks

1 messages · Page 1 of 1 (latest)

sand shadow
wanton fern
#

To be more specific, I perform multiple API calls (create customer, create subscription, add payment method, etc), and I cache the return object to avoid hitting Stripe too much. But the webhooks come in later, and I don't want to update my cache with the webhook object if the current Stripe object I cached is newer.

#

Ideally there'd be some sort of incrementing version on the stripe object.

#

I'd prefer not to cache these and keep hitting Stripe, but.... API rate limits.

sand shadow
#

Sorry it got busy for a minute there! Thanks for being patient

#

We don't have anything like an incrementing version, but thinking out loud, you may want to consider only updating your cached objects for *.updated events, or other events that you know result in changes on the subscription object.

wanton fern
#

Ah, its quite challenging getting under 100/sec rate limits during bursts caused by large chunks of the subscriber base hitting renewal periods when they've signed up around the same time. I don't think we have that many subscribers compared others, so I'm quite perplexed how other Stripe users handle renewal bursts on webhooks which need more Stripe data to handle.

#

This can end up causing bad loops, because we 500 error when we rate limit by Stripe, which means the Stripe webhook fails, then Stripe retries....

#

Caching the Stripe objects helps of course, but then its critical to ensure an older webhook doesn't overwrite data that we stored. We could always fetch from Stripe on a webhook to ensure we get the newer one even if the object in the webhook payload is older, but then we're back to more Stripe API calls.

sand shadow
#
  • bursts caused by large chunks of the subscriber base hitting renewal periods when they've signed up around the same time*

Ah, I see what you're saying now. Maybe a good solution is for you to respond with 200 for the webhook events and add them to a queue that you pull off of at a more reasonable rate?

wanton fern
#

That would help for some of them, but we do a decent amount of manual invoice processing, so upon the webhook event that the invoice was opened, we need to finalize it with an API call within an hour and mark auto-advance to false.

sand shadow
#

Do you happen to be setting all your subscriptions to a specific billing cycle anchor time and that's why you're getting a huge burst at a specific time?

wanton fern
#

Marketing campaigns reached large groups of users at the same time.

sand shadow
#

Gotcha

wanton fern
#

A feature recommendation to address this case would be:

  • Have stripe invoice.open webhook read a return payload, so the website could finalize and change auto-advance as the response instead of more API calls.
#

Especially as this period of time for an open invoice is critical since multiple bits cannot be changed after the 1 hour window.

#

Or exclude these types of things from Stripe API rate limiting. 🤷‍♂️

sand shadow
#

Something I just want to note (I haven't fully thought through whether this is the best idea) - the 1 hour window is 1 hour from when you successfully respond w/ a 2XX to the invoice.created event. If you were to NOT respond, then that window would be extended and we would wait up to 72 hours before finalizing the invoice

wanton fern
#

Ah, ok, I didn't realize that.

sand shadow
wanton fern
#

Thanks, I'll look at moving the events to a queue to slow them down. For caching Stripe objects though, it'd still be very useful to be able to know based on the object whether or not my cached copy is newer than the webhook copy.

sand shadow
#

That's fair - I'll add that is feedback to the team 👍

wanton fern
#

My immediate attempt at a solution is to stash request id's in Redis for a few hour TTL if I cached the resulting Stripe object, and if I see a webhook event with a request id that matches my cache, I ignore the object as I know I accounted for it already and have probably stashed a newer one as well. It's a bit heavy-weight of an implementation approach, but I believe that would work.