#naveed-web3auth_best-practices

1 messages ยท Page 1 of 1 (latest)

rugged pilotBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1386618562608890026

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

earnest lava
#

This is the code Im using on my webhook endpoint to decide on sending an email

if !isOnLatestPhase(stripeSubSchedule.Phases) {
        lastPhase := stripeSubSchedule.Phases[len(stripeSubSchedule.Phases)-1]
        fmt.Printf("lastPhase %+v\n", lastPhase)
        downgradePlan := lastPhase.Metadata["downgrade_plan"]
        isDowngradeScheduled := downgradePlan != ""
        if isDowngradeScheduled {
            fmt.Println("send email for downgrade:", downgradePlan)
            // go s.sendDowngradeEmail(stripeSubSchedule, downgradePlan)
        }
    }
#

I go through the phases and make sure im not already on the latest phase (cuz that would mean im already downgraded)

#

One thing I dont like is that the metadata even after subscription schedule is released remains on the subscription

#

and also idk if this is the best approach for subscription schedule downgrade

mystic depot
earnest lava
#

this part remains basically

#

how to do that

#

i have to look out for subscription_schedule.released event to do that?

mystic depot
#

Yep, should work. You can get the sub_xxx ID from the subscription property in that event payload and then call this API passing metadata: ''

earnest lava
#

Is there a way to detect plan downgrade without resorting to metadata?

There are other things that we do on our dashboard like upgrade to higher plan and whatnot without using metadata. We just detect the price items on the subscription to see what the items are before sending an email e.g. "thanks for upgrading to Scale"

This approach may have some flaws like what if subscription.updated event is fired for reasons other than upgrades

#

And comparing between previous attributes and latest seems complicated

mystic depot
#

And comparing between previous attributes and latest seems complicated
That's the only way to understand the action that caused the event to fire really

earnest lava
#

So for subscription schedule that I just mentioned to detect a plan downgrade the non-metadata approach is to compare the actual phase items? evt_1Rd5CcImFOsfVEtUtwuLleNi

#

You can see in the event payload that the second phase item has metadata attached to it

mystic depot
earnest lava
#

It seems that I'd have to keep record of what price ids correspond to what plan, but that seems not the best approach given that we use lookup keys

mystic depot
#

Yes the lookup keys aren't a part of those payloads unfortunately

earnest lava
#

Is there a better way to achieve what im looking for?

mystic depot
#

Not really, no. You need some kind of mapping to you know if a phase item(s) changes it corresponds to a downgrade/upgrade

#

(or leverage metadata like you are)

earnest lava
#

In terms of leveraging webhook i think that the metadata remaining on the subscription may not necessarily pose any issue (unless I utilise it elsewhere)

#

removing it on release seems like a bonus but a good cleanup step

#

but i have to ensure that the subscription.updated event does not trigger subscription provisioning and email flows

#

so this might indicate a flaw in the design of my webhook subscription.updated handler

mystic depot
#

You'll likely need logic to discard those events yes (i.e. check for the metadata key)

earnest lava
#

this is what im currently doing

func (s *billingService) handleEventSubscriptionUpdated(tx *gorm.DB, event stripe.Event) error {
    // ...

    // validate subscription, if invalid, notify devs via Sentry
    s.validateSubscription(event)

    customerStripeID := event.Data.Object["customer"].(string)
    return s.provisionPlan(tx, customerStripeID, event)
}
#

Oh hey maybe i wont need to do anything

#
if dbCustomer.Plan == *plan {
        // skip if plan is not changed
        return nil
    }
#

it seems if plan remains unchanged i dont do anything

#

so i guess i wont have to worry about it

mystic depot
#

Worth testing for sure! Can leverage a test clock to simulate a downgrade

earnest lava
#

Alright

#

One more thing

#

Are there any design patterns or abstractions utilised in the industry that cover stripe webhooks esp. the detection of business events based on webhooks payload esp. abstracting those aspects about comparing current vs prev attributes

#

the mapping of webhook events to specific business events basically

#

Or any famous clients that utilise stripe and have documented their approach to this stuff

mystic depot
#

Most do leverage the previous_attributes hash and do a comparison to determine the nature of the change. Granted that can be complex as noted

earnest lava
#

Yes, and now that I think about it I realised this code here may cause some issues

if dbCustomer.Plan == *plan {
        // skip if plan is not changed
        return nil
    }

It may cause the plan provisioning steps related to upgrades to be triggered even for downgrades!

#

because the only condition is that the plan is different

mystic depot
#

Yeah so that's where the price comparison comes in

#

(or metadata)

earnest lava
#

If i use the metadata approach it seems that I would absolutely have to clean it up, because otherwise a user after downgrading may wish to upgrade again and the subscription.updated endpoint if it makes an exception based on if metadata.downgrade_plan exists things would not go as planned if the metadata is not cleared from the subscription by this point in time

mystic depot
#

Yep, definitely

earnest lava
#

okay so ill have to handle subscription event released and then within it i have to basically unset the downgrade_plan key. I guess it should not be an issue whether that metadata key exists or not.

As for determining whether the release event should indeed clear that key i guess it doesnt matter atm what action triggered the release.

#

Tbh I think the cleanup code is still not where it needs to be. Because

#

subscription schedules linger until all the phases are complete. So e.g. Scale downgrade to Growth, At end of month I am downgraded to Growth but sub schedule is not yet released. It needs to progress for the end of another month before it is finally relaesed

#

But if before that happens I trigger an upgrade again. to say Scale the sub schedule would be added a new phase automatically

#

lol

#

So that delays the release

#

oh wait im supposed to listen for subschedule.updated event right

#

i though there was a .released event

#

oh hold on yeah there is a .released event

#

but i guess thats not the event i should be looking out for

#

clearing metadata is all about the downgrade having completed

#

im starting to think metadata is really not a good approach at all

mystic depot
#

Then you'll want customer.subscription.updated which will fire then the sub transitions to the new period of the downgraded plan

earnest lava
#

true, only one concern is that within this webhook i am updating the sub to remove its metadata which again triggers the customer.subscription.updated event

#

but yeah i think thats alright

#

seems like the only way to make the metadata approach work

mystic depot
#

Try it out with a test clock and let us know!

earnest lava
#

Thanks for the help. It really helped clear out everything!

#

Stripe Developer Debugging (SDD) > Rubber Duck Debugging (RDD) ๐Ÿ˜‚

mystic depot
#

Happy to help! ๐Ÿฆ†