Handling multiple "Only when" scenarios from a webhook

Hi there,

I’m using a single Stripe webhooks to action a bunch of different things in my app and wondering the best way to handle this.

Specifically I’m using the Subscription Change event in Stripe but this has multiple outcomes in my app depending on the specifics of the event. For example; upgrading plan, downgrading plan, pause plan, resume plan amongst others.

I can add an “Only when” condition in the backend workflow endpoint but that returns a failure if it’s listening for a downgrade and hears an upgrade. Alternatively I can have the webhook land and then have a really complex workflow to filter the payload and send the data to various custom events.

What is best practice

a) multiple of the same webhook event triggered to different backend API endpoints with conditionals on the endpoint, leading to lots of failed webhooks in Stripe but clean processing in Bubble

b) one webhook landing in Bubble and then a complex workflow to filter and send payload to different custom events

c)something I haven’t thought of.

I know if frontend workflows the answer would be A so I’m inclined to go with that.

Thanks in advance

Martin

1 Like

You can check the ‘Return a 200 if condition is not met’ so it won’t return a 400 error to solve that.

Alternatively I can have the webhook land and then have a really complex workflow to filter the payload and send the data to various custom events.

There shouldn’t be any need for an overly complex workflow here - just a simple one to trigger the other relevant workflows (I’m intrigued as to why you think it might be really complex? - I guess it depends on what you’re trying to do)…

Just set up a single API endpoint in Bubble to receive the webhook (you can put conditionals on here if need be, but you probably don’t need any unless you need to filter out certain things - in which case set the ‘Return a 200 if condition is not met’ option to yes to avoid failures.

Set up your other workflows as needed (the ones which do the work you need to do) - i.e. one for upgrading plans, one for downgrading, pausing plan etc.

Then, in your API endpoint just add conditional actions to trigger the relevant workflow as needed (based on the webhook payload)

I know if frontend workflows the answer would be A so I’m inclined to go with that.

multiple of the same webhook event triggered to different backend API endpoints with conditionals on the endpoint, leading to lots of failed webhooks in Stripe but clean processing in Bubble

Option A seems way more complicated and messy to me…

If you were going to use different endpoints there would be no need to use conditionals, would there?

2 Likes

Thanks so much for the detailed response

If you were going to use different endpoints there would be no need to use conditionals, would there?

I was thinking to create multiple webhooks from Stripe for the same event but all going to different endpoints. Each one with an only when conditional.

in which case set the ‘Return a 200 if condition is not met’ option to yes to avoid failures.

I tried this but didn’t seem to work. Will try again.

(I’m intrigued as to why you think it might be really complex?

I might just be a bit overwhelmed but I have a bit of a list of scenarios and permutations. Upgrade, downgrade, pause, status change to unpaid, status change to paid, free trial change to active. There are more.

I’m sure it can all be handled with relative ease, just want to minimise the chances of edge cases sneaking through and causing the wrong emails to go out etc. A great case for just using Stripe Checkouts :rofl:

Nearly there though.

Thanks :+1:

I was thinking to create multiple webhooks from Stripe for the same event but all going to different endpoints. Each one with an only when conditional.

I guess that’s an option (but to me seems a lot more complex and hard to manage - but if it works for you then go for it).

I tried this but didn’t seem to work. Will try again.

It definitely works (at least it does for me - no reason it shouldn’t for you, that’s precisely what it’s for)

I might just be a bit overwhelmed but I have a bit of a list of scenarios and permutations. Upgrade, downgrade, pause, status change to unpaid, status change to paid, free trial change to active. There are more.

How many more? 10? That’s not complex? 20? Still not really complex - only one action will ever be running.

Seems a lot simpler and cleaner than having 20 separate endpoints in Bubble, and 20 separate webhooks in Stripe to manage.

Admittedly, if you’ve got dozens or hundred of workflows you need to trigger then it might get a bit long (but still not complex - as you’ll only ever be triggering a single action).

Nearly there though.

As usual with Bubble there are probably multiple ways to get to you goal, so whatever makes the most sense to you is the best way to go.

This is great to know. Just need to map out all of the "Only when"s carefully to cover all bases.

As usual with Bubble there are probably multiple ways to get to you goal, so whatever makes the most sense to you is the best way to go.

This is very true. Trying to pick up some best practice along the way too as not from a dev background.

One other question @adamhholmes, would you change the DB based on outcomes of webhooks to ensure change has occurred Stripe side too? At the moment I’m changing things in my DB after sending API call to Stripe and then doing a check on webhook to see that contains same data as my DB. Appreciate there is probably no straight answer but if one is “better” than the other, nuance aside.

Hi, what did you end up doing?

The problem about using 1 webhook for multiple actions, e.g. pause/resume, fir the same event is that the return fields are different. So then those fields are not accessible on different actions. That is why multiple webhooks with conditions for the same even but different action make sense, if it works.

@net-tt The way to get all conditionals available is to create a fake payload containing all the data you might need. Get it into Postman or RapidAPI and fire it over to your Bubble endpoint, then you have all the data fields ready to use as/when they come in.

For this use case it essentially meant packing the the previous_attributes object full of things I might need to know to trigger the various workflows. You can find all the things you might need to know by looking in Stripe at past events.

Hope this helps.

That is a great idea. Thank you!