I am trying to understand the subsciptionStatus logic in stripe.ts

I am just wondering what could be the reason we don't want to update subscriptionStatus as soon as chekcout.session.completed along with hasPaid and subscriptionTier (line 46 and 48). I am writing a logic where after a user sign up for subscription with subscription_data.trial_periods_days , I then check whether a subscription is active or not, and re-direct them to the hidden page like so: on DemoAppPage.tsx:
No description
No description
No description
32 Replies
uglybeanhead
uglybeanhead•5mo ago
i followed openSaas documentation but it seems to be saying 2 different things: 1. for checking subscriptionStatus https://docs.opensaas.sh/guides/authorization/ (first pic) and the other check for hasPaid (second pic ) https://docs.opensaas.sh/general/user-overview/#subscription-statuses
OpenSaaS.sh
Authorization
Open SaaS is a free, open-source, full-stack SaaS starter kit for React + NodeJS.
OpenSaaS.sh
User Overview
Open SaaS is a free, open-source, full-stack SaaS starter kit for React + NodeJS.
No description
No description
uglybeanhead
uglybeanhead•5mo ago
I will just check the hasPAid and subscriptionTier to grant access for now. I am still trying to understand all these series of events that are triggered after signing up.
martinsos
martinsos•5mo ago
@Vinny (@Wasp) will be the best person to answer this one!
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
good question. ok so for a subscription, what happens when someone pays, and their paymenst go through successfully for 3 months? The hasPaid property will be true, and their subscription status will active But what happens, let's say, when their credit card has expired and their payment hasn't gone through on the fourth month? the hasPaid property is still true but their subscipriton status will be pastDue i realize that hasSubscribed maybe be a better name in this case. perhaps we should change it. hmm or perhaps we don't need hasPaid at all, and can only rely on subscriptionStatus.... let me check @martinsos what do you think would be the best approach here? 1. use the hasPaid flag on a user as an overall indicator if the person has started a subscription or not, and have it live next to
user.subscriptionStatus = 'active' | 'past_due' | 'canceled' | 'deleted'
user.subscriptionStatus = 'active' | 'past_due' | 'canceled' | 'deleted'
or... 2. drop the hasPaid flag and use user.subscipritonStatus === undefined to check if a user has or hasn't started a subscription
user.subscriptionStatus = undefined | 'active' | 'past_due' | 'canceled' | 'deleted'
user.subscriptionStatus = undefined | 'active' | 'past_due' | 'canceled' | 'deleted'
I think going with number 2, dropping the hasPaid flag, is the better option in the end
uglybeanhead
uglybeanhead•5mo ago
Hi Vinny, thanks for your input! Initially I checked if the subscriptionStatus is active to re-direct the user to access a hidden page, line 87 is not simultaneously triggered right after chekcout.session.completed, so it still stays null and the hidden page stays hidden
No description
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
you can't do that within the webhook. the webhook is only on the server you need to be doing client-side authorization https://docs.opensaas.sh/guides/authorization/#client-side-authorization but it sounds like invoice.paid is not being triggered because your webhook is not listening for that event follow the instructions here https://docs.opensaas.sh/guides/stripe-testing/#testing-webhooks-via-the-stripe-cli and test if your webhook is listening for the invoice.paid event by running this command in another terminal window:
stripe trigger invoice.paid
stripe trigger invoice.paid
more details here >>https://docs.opensaas.sh/guides/stripe-testing/#testing-webhooks-via-the-stripe-cli let me know if you have any other questions 🙂
uglybeanhead
uglybeanhead•5mo ago
Hi Vinny, I actually wrote that logic in the clientside - where the DemoAppPage.tsx is. And also did all steps in the document , webhook is listening to the invoice.paid event but the status is not updated. Here are the screen shots:
No description
No description
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
can you put a console.log(event.type) statement on line 88 and share what it says when you chrckout? also, where is your userStripeId being defined? are you still listening for 'checkout.session.completed' events?
uglybeanhead
uglybeanhead•5mo ago
No description
uglybeanhead
uglybeanhead•5mo ago
userStripeId defined on the top of the webhook, i have not changed a thing from the template instripe.ts, and yes, I am listening to checkout.session.completed
No description
uglybeanhead
uglybeanhead•5mo ago
looks like the template provided only update status when ebent customer.subscription.updated:
No description
MEE6
MEE6•5mo ago
Wohooo @uglybeanhead, you just became a Waspeteer level 2!
uglybeanhead
uglybeanhead•5mo ago
I guess i will add a line that update status when invoice.paid ? nope, does not work
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
Wait. Let’s back up. Can you show me what the result of the console.log is? In the terminal where you ran wasp start. Ah sorry. I see it now Ok can you define a the user update function to a variable and log that to the console as well? const updatedUser = await context.entities.User.updateMany() While you’re at it log the userStripeId to the console as well. I have a feeling you’re not able to find the user in your db Btw which auth method are you using?
uglybeanhead
uglybeanhead•5mo ago
you are right the userStripeId is not defined, but why is that? (also from the third pic, customer.subscription.updated was not triggered) I use google Auth
No description
No description
No description
uglybeanhead
uglybeanhead•5mo ago
No description
uglybeanhead
uglybeanhead•5mo ago
No description
uglybeanhead
uglybeanhead•5mo ago
but the database is updated tho
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
Try this. Copy this line userStripeId = session.customer as string; and paste it right under line 87. Then see what happens
uglybeanhead
uglybeanhead•5mo ago
No description
No description
uglybeanhead
uglybeanhead•5mo ago
No description
uglybeanhead
uglybeanhead•5mo ago
i suspect customer.subscription.updated was not triggered in the event, maybe that's why it was never updated I am looking into each event log which version of api are you using?
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
Whichever is in the template
uglybeanhead
uglybeanhead•5mo ago
welp. i use the new one 2023-10-16. My apologies, Vinny.
Vinny (@Wasp)
Vinny (@Wasp)•5mo ago
No worries! That must be the issue. It seems the checkout.session.completed doesn’t fire first in that version, which was causing the issue. Glad we got it fixed though 🙂
SirLan
SirLan•4mo ago
Just playing around at this point to see the functionality in the DemoApp. Love it, really nice work! I notice that you don't handle deleted/cancelled subscriptions in your generateGptResponse. So if a user has deleted or cancelled subscriptionStatus they can continue to use the API.
if (!context.user.subscriptionStatus && !context.user.credits) {
throw new HttpError(402, 'User has not paid or is out of credits');
}
if (!context.user.subscriptionStatus && !context.user.credits) {
throw new HttpError(402, 'User has not paid or is out of credits');
}
Something like this fixes that
if (!context.user.credits && (!context.user.subscriptionStatus || context.user.subscriptionStatus === 'deleted' || context.user.subscriptionStatus === 'past_due')) {
throw new HttpError(402, 'User has not paid or is out of credits');
}
if (!context.user.credits && (!context.user.subscriptionStatus || context.user.subscriptionStatus === 'deleted' || context.user.subscriptionStatus === 'past_due')) {
throw new HttpError(402, 'User has not paid or is out of credits');
}
Vinny (@Wasp)
Vinny (@Wasp)•4mo ago
Yeah you’re right. Nice catch! Do you mind submitting a PR for that?
SirLan
SirLan•4mo ago
Yeah for sure! I am AFK for a few hours but I will get one submitted as soon as I'm back 😀
Vinny (@Wasp)
Vinny (@Wasp)•4mo ago
Awesome. Much appreciated! I’m on vacation at the moment so don’t have access to a computer So that’s very helpful
SirLan
SirLan•3mo ago
GitHub
Fix: Updating subscription status check on generateGptResponse by T...
Change to ensure that deleted and past_due subscriptions are not allowed to access the GPT API without credits.
MEE6
MEE6•3mo ago
Wohooo @SirLan, you just became a Waspeteer level 1!
Vinny (@Wasp)
Vinny (@Wasp)•3mo ago
Very cool. Thanks so much. I’ll give it a look in a week when I’m back