Nice presentation, I do believe there is needed also a transaction log (as a User for sure I wish to check/validate/inspect all my transactions.) It is good also for auditing purpose.
Don't know how I missed this video! This is exactly what I need 😀 Even wanted to ask you on Discord how you implemented token system for your icon generator saas. Thanks Cody!
Thanks for this mate! Would love to see how you create your saas apps in next, do you have any video going through an app? Have some AI saas ideas in mind but not sure how to start. Cheers
Great video. Obviously still in development, but you should try moving the payment process as a popup on the pricing page, instead of going to another page then coming back. Paypal do that and it's so annoying for the end user! Keep up the good work. Stripe rocks.
is there any way for the webhook to interact with the client? ie. if the stripe result detects some kind of fraud or other issue, is it possible to subscribe to events coming from that api to react to?
Was using Prisma and SST in this project difficult to configure. I know on SST discord they kind of discourage using Prisma. Maybe you can do a video on how you set up this project.
Around 6:09...don't you want to log that error on the Stripe endpoint? Then return your response. Otherwise you don't know why the error might be an "Unknown Error"
I have a AI service and I was lost on how to price it, this helped me a lot thank you! If you dont want to share this particular code, can you make a separate project/indepth tutorial?
Love this! With stripe redirect to dashboard - does it wait for the hook to complete applying the credit? What if the redirect completes before the hook is finished processing?
No, it doesn’t wait. The better solution, which I didn’t implement, would be to redirect to a page which continuously polls until your user has the credits applied and then redirect them to the dashboard.
how do you handle stripe webhooks run in wrong order issue? I mean sometimes the webhooks may not run in order for example the updated event may complete first and then create event complete second. you might check this on you stripe webhook dashboard.
How do you design your apps? Do you just have a set of templates you already have and just dive right in? I guess what I really want to know is what’s your process?
Design as it how it looks? Or functionality design? Code design? For code I often just reuse code I have in other projects, for design I use a component library and just do stuff until it seems nice, put loaders where necessary, etc
Hi Cody, i was wondering if you can do a video on how to think of a project (that not many have been building) using AI. I am trying to think of a side project like yours that you are building an potentially making a small buck but its hard. I was thinking of something with Spotify but no clue...
So far I’ve made things I personally needed, such as a way to generate icons for my own side projects, and now a way to generate chapters for my RUclips videos. I’d say find something you’re interested in and see if AI can help fast track the process
I've built a similar system using Laravel but I'm storing the credits as encrypted strings in the database. Is it the right approach or should we store it somewhere else or use a 3rd party service for this on production level?
i also tried implementing this style of credit system with stripe but i ran into an issue i was trying to update ui (credits) and could not i'm nextauth they provide update method to update session client side but i didnt know to trigger update method after the stripe webhook has been called , only solution i came up with is long polling & some state in localstorage which isn't optimal
yes i thought about those too but the other issue is ran into what if the user isn't logged in when webhook get triggered so i figured might aswell do long polling@@WebDevCody
On the front end I just make a request to the backend to get the latest amount of credits for the user. I think when stripe redirects you back to your app, you could just tell the ui to refresh credits
i ran into the same issue only solution i came up with is long polling , if the payment happens immediately you can add state to redirect url payment=true & on mount check if you've queryParams payment=true & update client session then but if the payment could take couple of days just only solution is long polling with some state in localStorage 'payment=pending" or smth
@@abdousfayhi7649 my solution for something similar was to use stripe elements to host the payment on-site, then if payment fails you can handle things appropriately. web hooks take care of syncing db and if successful simply update the client session with result. Saves any request between the server and client to pull latest credits!
Something that may be unrelated but whenever somebody is using the credits, shouldn’t the operation be made transactional mainly due to issues like double charging (race condition where a user might try to invoke this action a few times in parallel)
I think it depends on the db default transactions. I believe Postgres by default uses transactions for all writes, so two conditional writes shouldn’t have race conditions
I am not sure about that bur my main idea is that even it uses transactions, creating one explicitly would not hurt. Also, even if it did, the default isolation level is read committed which would not be enough for this use case
I’m using 3.5 turbo, but I may need to switch to 4 or provide an option Gpt4 is 10x more expensive and these videos have huge transcripts, so the cost adds up with 4, but gpt3.5 is very hit and miss on regards to results. I haven’t figured out my approach for longer videos. I may have to chunk the transcripts up and process them separate and combine somehow
7:11 just a general question but should the default value for credits reside in your backend code rather than the database level? Ideally, the database shouldn’t have a default value for it so that you’re forced to enter a value, which can be handled in your backend during user creation. You can even have it as an environment variable so if that value needed to be changed in the future, you can easily do so.
I think certain design patterns are more useful for larger projects with many developers needing to work on the same code base (or projects that expect to be around for many years). For most of the content you see online and youtube, no one is going to apply clean architecture to a project that is maintained by one person; it's basically over engineering in most cases.
@@WebDevCody you can use credits: { gte: 1 } with update as you did with updateMany. The only difference is update returns a User object while updateMany returns the count of updated records.
@@WebDevCody My bad 😂 I tested the update method with gte and it threw an error when the gte condition is not met. Your usage of updateMany is the correct way since it returns back count. Thank you 😊
Hi Cody. Is the actions.ts file on the frontend? That means we are sending the number of credits from the frontend? Can a malicious client change the code to change the credit to lower the price of each item? Also what have you stored as process.env.PRICE_ID_50?
Have been avoiding Stripe for years now but you make it very easy to consume. Kudos
You are the man!! Thanks a lot for sharing your knowledge. I have learned a lot from you.
Another incredible video! Thanks Cody
This is very neat! Thank you for the tutorial!
Prisma Transactions would work perfect for that update and decrement scenario.
Nice presentation, I do believe there is needed also a transaction log (as a User for sure I wish to check/validate/inspect all my transactions.) It is good also for auditing purpose.
exactly , it will be fantastic if you make a simple tutorial about the stripe credit system , it will be great
Don't know how I missed this video! This is exactly what I need 😀 Even wanted to ask you on Discord how you implemented token system for your icon generator saas. Thanks Cody!
All the code is also in my repo as icon generator tutorial I think
@@WebDevCody just checked, it's there! Thanks!
Thanks for this mate! Would love to see how you create your saas apps in next, do you have any video going through an app? Have some AI saas ideas in mind but not sure how to start. Cheers
Great video. Obviously still in development, but you should try moving the payment process as a popup on the pricing page, instead of going to another page then coming back. Paypal do that and it's so annoying for the end user! Keep up the good work. Stripe rocks.
Good job bubby!!!
😘
awww
Very simple to understand now. Thank you.
Thanks for sharing, what's theme icon pack your using btw?
please please do make tutorial on this topic, it would be really helpful
is there any way for the webhook to interact with the client? ie. if the stripe result detects some kind of fraud or other issue, is it possible to subscribe to events coming from that api to react to?
Great video. Another question, Are you creating a product in the Stripe dashboard with 3 different pricing?
yes
hey there cody , nice video , may i know how you implemented the nextjs progress bar ?
It’s an npm library called nextjs progress bar
you should create a browser extention for you new side project
Was using Prisma and SST in this project difficult to configure. I know on SST discord they kind of discourage using Prisma. Maybe you can do a video on how you set up this project.
No, it worked easily for me. You just need to put binaryTargets to include Linux arm64 for it to work when deployed to lambda
Around 6:09...don't you want to log that error on the Stripe endpoint? Then return your response. Otherwise you don't know why the error might be an "Unknown Error"
I have a AI service and I was lost on how to price it, this helped me a lot thank you! If you dont want to share this particular code, can you make a separate project/indepth tutorial?
I may share the project in a bit
@@WebDevCodyYey looking forward to it
Love this!
With stripe redirect to dashboard - does it wait for the hook to complete applying the credit?
What if the redirect completes before the hook is finished processing?
No, it doesn’t wait. The better solution, which I didn’t implement, would be to redirect to a page which continuously polls until your user has the credits applied and then redirect them to the dashboard.
@@WebDevCody Not Next.js stuff but I've added a pending verification page in Laravel which is shown when webhook is not received yet.
how do you handle stripe webhooks run in wrong order issue? I mean sometimes the webhooks may not run in order for example the updated event may complete first and then create event complete second. you might check this on you stripe webhook dashboard.
I’m not sure if order makes a differences? I only check for the compete event, and when that comes in I apply credits to the user.
How do you design your apps? Do you just have a set of templates you already have and just dive right in? I guess what I really want to know is what’s your process?
Design as it how it looks? Or functionality design? Code design? For code I often just reuse code I have in other projects, for design I use a component library and just do stuff until it seems nice, put loaders where necessary, etc
@@WebDevCody Thanks for your response. I was referring to your UI design but you covered it.
Hi Cody, i was wondering if you can do a video on how to think of a project (that not many have been building) using AI. I am trying to think of a side project like yours that you are building an potentially making a small buck but its hard. I was thinking of something with Spotify but no clue...
So far I’ve made things I personally needed, such as a way to generate icons for my own side projects, and now a way to generate chapters for my RUclips videos. I’d say find something you’re interested in and see if AI can help fast track the process
I've built a similar system using Laravel but I'm storing the credits as encrypted strings in the database. Is it the right approach or should we store it somewhere else or use a 3rd party service for this on production level?
Why are you storing encrypted strings for credits? I’d just use an int
@@WebDevCody For additional security, still I'm worried about it.
i also tried implementing this style of credit system with stripe but i ran into an issue i was trying to update ui (credits) and could not i'm nextauth they provide update method to update session client side but i didnt know to trigger update method after the stripe webhook has been called , only solution i came up with is long polling & some state in localstorage which isn't optimal
you either need polling, websockets, or server side events to notify users when the stripe webhook finishes
yes i thought about those too but the other issue is ran into what if the user isn't logged in when webhook get triggered so i figured might aswell do long polling@@WebDevCody
How are you handling updating the client side total of credits after purchasing and updating prisma? using next auth session update()?
On the front end I just make a request to the backend to get the latest amount of credits for the user. I think when stripe redirects you back to your app, you could just tell the ui to refresh credits
i ran into the same issue only solution i came up with is long polling , if the payment happens immediately you can add state to redirect url payment=true & on mount check if you've queryParams payment=true & update client session then but if the payment could take couple of days just only solution is long polling with some state in localStorage 'payment=pending" or smth
@@abdousfayhi7649 my solution for something similar was to use stripe elements to host the payment on-site, then if payment fails you can handle things appropriately. web hooks take care of syncing db and if successful simply update the client session with result. Saves any request between the server and client to pull latest credits!
Something that may be unrelated but whenever somebody is using the credits, shouldn’t the operation be made transactional mainly due to issues like double charging (race condition where a user might try to invoke this action a few times in parallel)
I think it depends on the db default transactions. I believe Postgres by default uses transactions for all writes, so two conditional writes shouldn’t have race conditions
I am not sure about that bur my main idea is that even it uses transactions, creating one explicitly would not hurt. Also, even if it did, the default isolation level is read committed which would not be enough for this use case
Which service you are using to generate transcripts?
I use a library called yt transcripts
How did you work with videos over 8000 tokens? Assuming you're using GPT-4.
I’m using 3.5 turbo, but I may need to switch to 4 or provide an option Gpt4 is 10x more expensive and these videos have huge transcripts, so the cost adds up with 4, but gpt3.5 is very hit and miss on regards to results.
I haven’t figured out my approach for longer videos. I may have to chunk the transcripts up and process them separate and combine somehow
7:11 just a general question but should the default value for credits reside in your backend code rather than the database level?
Ideally, the database shouldn’t have a default value for it so that you’re forced to enter a value, which can be handled in your backend during user creation.
You can even have it as an environment variable so if that value needed to be changed in the future, you can easily do so.
That’s actually how I did it on another project, but was lazy for this one
Ahh okay gotcha
Great video, but why people don't usually use good practices in Next? Like Clean Architecture, DIP...
I think certain design patterns are more useful for larger projects with many developers needing to work on the same code base (or projects that expect to be around for many years). For most of the content you see online and youtube, no one is going to apply clean architecture to a project that is maintained by one person; it's basically over engineering in most cases.
@@WebDevCody fair enough
Do you do the design yourself, or you outsource?
This was all using an existing component library. Everything here is by me
why are you using updateMany instead of update for decrementing user credits
I'm pretty sure the update command doesn't allow you to check that the user has credits >= 1, but updateMany does
@@WebDevCody you can use credits: { gte: 1 } with update as you did with updateMany.
The only difference is update returns a User object while updateMany returns the count of updated records.
@@WebDevCody My bad 😂 I tested the update method with gte and it threw an error when the gte condition is not met.
Your usage of updateMany is the correct way since it returns back count.
Thank you 😊
What´s the vsc theme sir?
Bearded theme stained blue
To use stripe, does it need you to have a business open?
I think so, or a sole proprietorship with your home address
>=1, not >1 (i guess.)
You bought 50 credits but they only got 49
I bought 50 credits?
@@WebDevCody I thought so in the video but could be wrong
Hi Cody. Is the actions.ts file on the frontend? That means we are sending the number of credits from the frontend? Can a malicious client change the code to change the credit to lower the price of each item?
Also what have you stored as process.env.PRICE_ID_50?