Accepting Payments in Flask Using Stripe Checkout [2020]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone in today's video I'm going to show you how to integrate stripe check out with flask so I made this video a few years ago but since then stripe has changed their entire checkout process so I thought I'd make a new video showing you how to do it with the new version of stripe checkout so before you can even follow this tutorial you need to make sure you have a stripe account and you're gonna be using your test credentials and you know you go to API he's over here you'll be able to see your test keys and make sure they have tests in it for the tokens you'll also need the command line interface installed so I'll give you a link to the documentation for installing the command line interface and once you install the command line interface make sure you log in so basically you just call stripe login and what's going to happen is it's gonna open up a browser window where you can log-in to your stripe account and then basically connect your command line interface with your stripe account so you can run commands from your command line interface so once you have those two things you can follow the tutorial so we're gonna be following this process roughly for checkout and I'll show you how to adopt it offer flask and I'll link this in the description below as well so you can follow along with this so to start I already have my app running it has a basic product page where you can click buy now and it also has a thank-you page so if I go to slash thanks you see thank you so this isn't gonna do anything special it's just a page this first one is where pretty much everything is happening so for my code I have these two routes already and obviously I have flasks installed and you also want to install stripes so pip install stripe and I already have it installed and once you do that we can start working on getting the payments integrated so first you want to add in your tokens for your public key and your secret key for stripe so I'll just add them to my configuration so I'll say a stripe public key and then I'll have one for secret so stripe underscore secret key and then I'll ask them as strings here and then we'll be using them so if I go over to my dashboard look at my keys so I have the bulky and I'll put this in public and then I have a secret key which I can reveal by just clicking that and I'll put them in secret so like I said make sure they both have tests because we're just doing these on the tests account once you have these two things then we can kind of start following the process of adding check out so first set up stripes already did that so pip install stripe next what we want to do is we want to create a product so obviously if the user is going to be giving you money they're gonna they're going to give you money for something and that is a product and stripe so if you go here on your stripe dashboard to the left hand side where it says products you can create a new product and I'll do that now give it a name so the product and description let's say the best product ever also give it a price and a frequency so one-time or recurring for this video I'll just use one time and I'll set it to be $99 and then once you do that you can just hit save product at the top right hand corner and it's gonna take you to the actual product page so we'll come back here let's go back to the documentation so we created the product next thing we have to do is we create a checkout session so the checkout session is what's going to allow us to start the process to take someone's money so if I copy the code here so I'll just take everything here and I'll copy it into my index route so we'll put it here in index and I'll show you two versions of this the first one we're gonna put it directly in index on the second version I'm gonna do like an API call to the server so we can get this through Ajax but first I will put it in index so let me just indent everything I'm gonna move this call to stripe that API key outside of the route because I'll be using it for the command line interface stuff with the web hooks later so let me just put that up here so stripe API he equals app config secret key so we see it's the same as the one should be the same but it isn't but stripe secret key here is the one that we want and now let me explain what's going on with so me indent everything first so when we create a session we have to specify the payment type so we're gonna be using a credit card here stripe has some other payment methods and you can easily change it to those payment methods as well but for our purposes we're gonna keep it on cart the most important part are the line items so the line items represent all the things that the buyer will be paying for so I've already created one product and this price ID is what I want to update so if I go over to the dashboard again we see that under pricing we have an API ID this is what we want so the product has an ID we don't want the product ID we want the actual pricing ID because each product and have multiple prices so we'll just put that here and also the quantity so I can change this to be like five if I wanted to but I'll leave it as one and if you had more items you can add them to this list here so imagine you were building this for like a checkout cart then the user can put multiple things in the cart with multiple quantities and then you can add those all here but for simplicity purposes I'm just gonna leave it as one for the single product and price that I created the mode is going to be payment and then for the success URL this is going to be our server and I'm going to change this to be URL for instead of example so let me import URL for and I'll start with a cancel URL so for cancer URL I'll just read the rectum back to the index so to do that I'll say URL for index and because this is supposed to be an external URL I have to do underscore external equals true so that's gonna generate the full URL and just instead of just the endpoint then I need to do something similar for the success URL but it needs to be slightly different so I'll show you first the thanks part and then the external equals true so that's the same but I need to add this second part to it the part where it has session ID equals checkout session ID I need to add this directly because when I have those brackets inside of URL for it's gonna convert those for me and I don't want that to happen so this is for strike these brackets so I'll make this a string and now it's going to concatenate the URL for thanks along with this query string for session ID because what happens is after user submits their payment they get redirected to this Thank You page along with a session ID in the URL and from there you can do something with a session ID I won't be doing anything with it in this video but you could if you wanted to because it's gonna be there and I'll show you that when we get to that point so I have a session ID in there and I have the cancer URL so now that I have this session created what I need to do is I need to send it to the template because there's going to be a little bit of JavaScript involved so I'm going to create a variable called let's say session say check out check out session ID and this is going to be equal to the session ID so this session is the one created from a striped checkout session doc Reid I also need to pass my public key so I'll call this checkouts public key and this is going to come from my configuration so this is going to be AB doc config stripe public key so let me add that here let me move these down so it's a little easier to read so we have to check out public key and then that's it that all gets returned in the template and like I said there are a couple of ways of doing this the first is to pass everything to the template here a second approach which I'll do later is using Ajax to get these because there's going to be a downside to do in this way and I'll show you that in a moment but I pass those to the template and this is the template here so if we go back to the documentation for the checkout process I've already created a session next thing I want to do is I want to redirect to checkout so first I need to install or just import the stripe library in my JavaScript to be used in JavaScript I should say so down here what I can do is I can just say scripts source equals and then you know the stripe stuff then what I'll do is I'll create a separate file so scripts and I'll call this script Jas how about this script No Ajax no Ajax Jas because I'll have a second version for Ajax and I'll go ahead and create this over here so script - no a jxj yes and in here I'm going to write the code for stripe and let's go back here we need to initialize stripe with the public key so I'll just copy this and this needs to go into the index so before I load this scripts I'm going to have this script and in here I'll have the stripe object and the reason why I'm doing it here is because I'll have access to the variables that I passed so check out session ID and check out public key so check out public key is going to go here and actually what I'll do is I'll I'll instantiate stripe inside of the script but I'll set the variable here so the variable is called this I copied that twice check out public key so check out public key is the public key that I'm passing from the backend and this needs to be inside the curly brackets because it's ginger and this is going to be a string and I'll name it check out public key as well and I can make this a constant if I want so cons I check out public key now I also do the same thing for the session ID so check out session ID is going to be equal to the check out session ID that comes from the routes so I can put the colons there and then these two things will be available inside of my script so now I can take that check out public key which is now a variable and I can pass it to stripe here just like that because these two are really the script here and the script here are gonna be run at the same time so anything that I have before the script no Ajax will be available inside of script no Ajax so that's what I'm using it there there check out public key now what I want to do is I want to get that button that I have on the screen because I'm gonna do something when I click it so I have the ID by now button so what I can do is like cons button equals documents query selector and I want to select the Buy Now button and then I can add an event listener to that button so any time the user clicks that button I want to activate the stripe stuff so button add event listener I want to add the click events and then doesn't have to take anything other than the event and inside of here is where I want to do the stripe stuff so let's go back to the documentation and it's pretty simple we basically just called the stripe object and call the method redirect to checkout on it and we just have to pass the session ID so I'll copy this and I'll put it into my code so copy that there and what I want to do is I want to update the session ID so this should be the checkout session ID so remember I have the variable here in the index so check out session ID and I can put it here so because this is JavaScript I can just drop that in there like that and everything should work so let's try running this and see if I made any mistakes so I'll go to my store refresh the page and we see stripe is not defined that's a pretty easy mistake to fix I just need to import stripe so import stripe here at the top and now let's try running this again and we see the product page and if I click buy now does it redirect me and it doesn't so let me open up the developer tools and go to the console and I can kind of see what happens so it says loading failed for the script with source script no Ajax and that's a pretty easy thing to fix so because I'm using flask the script won't just simply be in script no Ajax this files location so I have to use URL form so it's gonna be URL four and then this is a static file the file name is going to be that script no Ajax Jes so I could just put quotes around it like that and then I can close out the URL for so I have my script no Ajax file inside of my static directory so this URL for is just going to get it so let's try that again refresh it looks like I loaded this time so click by now so let's see we have this template syntax error somewhere we have render templates is not working and that's simply because I forgot the closing Jinja brackets so another easy mistake to fix let's try that again and refresh the page okay so now it's loaded again let's try clicking by now and now it redirects us to the stripe checkout page so I can close this because it appears to be working and I'll create a payment so for stripe the test card is just 42 42 over and over again and say you have 16 digits the expiration date just needs to be in the future the CVC can be anything the name can be anything as if it can be anything and then I click pay $99.00 and if it processes successfully it should redirect me to my Thank You page which it does and we can look here in the address bar and we see session ID equals CS tests and then the rest here so this is where the session ID is and inside of your thank you grout you can do something with it you can like query the API to see what that session has but we won't do that here we're gonna do something similar somewhere else so now that we have that let's go over to the dashboard and we go to payments in here we can see a successful payment from test a test com of 99 dollars so that's exactly what we want and we also see three other payments that are incomplete so why would it be incomplete payments when I only tried one payment it's because every time I create that session it starts by creating a session that doesn't have a payment captured on it and then they when they actually pay that's when it goes successful so every time I load the page it's going to create a session for me so if I go home and then if i refresh the page here we see there's another incomplete one here so this isn't always the best way it kind of depends on your checkout flow if you want you can do this using Ajax well which will generate the session right when they click the button so let me show you how to do that now so what I'll do is I'll create a second file called script - age XJS and what I'm gonna do is I'm going to create another route I will call this stripe pay write it can be anything so stripe pay it's gonna be a get request and it's gonna return some kind of JSON data and what I want to do is I want to move this session stuff down into this new route so I'll just copy this and I'll move it down here alright so that's the same and I'll just comment this out of here in case you want to continue to use it so everything is the same and instead of returning the template I just want to return these two things so I can copy these and it's going to be a dictionary so let me just create that dictionary so we're gonna have checkout session ID it's gonna be a session ID and then the public key is going to come from they config so now if I make it look like this I believe that should work and now I need to call this from JavaScript so inside of my Ajax and first what I need to do is I need to modify this so I have script Ajax so I'll change this to just Ajax with without the word know now also comment out this section here so with Jinja it's open bracket hash and hash in a closing bracket so this is commented out because I'm no longer gonna be putting them here it's gonna be coming from Ajax and inside of the Ajax one I'm going to be doing something similar so I need to get the button so let me just copy this here and then I'm gonna add that event listener to the button just like I did before and let me just close it out and the codes gonna go in here and the difference between this approach and the no Ajax approach is in the no Ajax approach I'm initializing stripe here because I already have the check out publicly available and then I'm just redirecting a check out whenever they click but in the Ajax example I can't initialize stripe until I have that that check out public ID so what I need to do here is I'm gonna call fetch and I'm gonna call the route that I just create it so stripe pay then I'll call it then here and it's gonna take in results and I need to convert that to JSON so return results JSON so I won't really explain this too much you have to be familiar with how fetch works but basically I'm just performing an API request to my own app and it's going to return the JSON data so here it returns the data in a form that's like a string and I'm converting it to JSON here and then once I have the JSON here so I'll say data I'm gonna have available inside of this function body here this is where I can initialize stripe so this data is gonna have the data from the dictionary here it's gonna be a JSON object and what I'll do is I'll just copy this so the stripe needs to be initialized but instead of using check out public heat it's gonna be data dot check out public key because that's the name of the key here so data dot check out public key next I'll have the redirect to check out stuff again so I'll just copy all this and I'll add it down here and the difference is instead of having a check out session here because it's a variable without I'll have data and then checkouts sessionid just like that okay so that should be it for the Ajax one so let's try reloading the page and we have invalid syntax so let's see yeah these this should be dictionary so instead of equal sign it needs to be a colon okay so let's try this again session is not defined so here in the render template I need to comment out these because I'm no longer using them and now let's try that one more time okay so now I can load the page so I just loaded it and let's check our dashboard to see if we generated a new one and we still just have one above here so let me refresh the page a couple times 1 refresh to refresh and then I'll refresh the dashboard and I still only see one so we know it's not generating a session every time i refresh the page anymore so now I'll try making a payment and I'll say Ajax at test comm and then 42s all around and then something in the future Ajax and then see pay so it's calling the stripe API and it redirects back to the Thank You page ok and let's go back to the dashboard to verify that it's been completed and we have a new payment Ajax test comm for $99 ok so that part is pretty simple where you basically allow the user to give you money but you've probably noticed that we don't have a way of confirming that the user has actually paid us and what you don't want to do is you don't want to use the Thank You page and the session ID directly from here because the user might not always end up here like imagine their browser crashes after they pay or there's some kind of militia user like you can't always count on this Thank You page being reached for a legitimate user so what we're gonna do is we're going to set up a web hook so tripe can send us a request telling us that there has been a successful payment and then from there we can do whatever process we want so a web hook is just an endpoint in your app that some kind of automated process will send requests to whenever something happens so in this case for any type event it's gonna send a request to our web hook and then from there we can handle the different events in that web hook and determine if a user has paid so what I'm gonna do is I'm gonna I'm going to create a new endpoints so let's say underneath the Thanks I'm gonna have a web or an endpoint cost tripe web hook and this is gonna be stripe web hook again for web hooks they are a post requests so methods is posts and any web hook when it's successful it just returns nothing with a 200 status response which is the default once you return nothing in flask so here what I want to do is I want to actually process the web hook and what I'll do is I'll show you it working on the command line so I'll say web hook called so I'm never going to call this web hook myself it's going to be stripe so we'll see it on the command line when web hook is called and now I want to process the web hook and I'll show you the documentation for that so if I go here you know I've already confirmed or I've already tested the integration now I want to go to the web hook section here and they have an example this is Django but I'm using flask so I'll show you how to modify this for flask so I'll just take all this here so this is the body of the web hook and I'll put it here underneath my my print statement so we need the payload we need the signature header we're gonna start with event ie none and then we're going to do the rest of the things down here but I'll start with what they want here for the payload this is the raw request information to get that in a flask you use request stop body instead use request stats get data and it's a method and first I need to import request up here okay so down here in the web hook so this is the payload and one thing you can do is you can check the payload length just in case someone tries to send you like you know 100 megabytes it should only be like you know maybe a kilobyte or so for the the web hook so you can say requests content length if it's greater than let's say one megabyte so 1024 x 1024 what I'm gonna do is I'm going to abort so I'll say requests too big and then I'll aborts 400 and I need to import abort so we won't see this working but anytime you use that that I get data method it's a good idea to check the content length first so you don't try to get like megabytes of data and it just runs through your memory on your server then we need the signature header so to get that it's not request dot meta it's going to be requests that environ that gets then HTTP HTTP stripe signature and the combination of these two things along with some where as a some endpoint secret is going to tell stripe whether this is legit so I'll show you how to get the endpoint secret in just a moment but let me indent these so in points secret let's just put that here it's gonna be a string and let's see so we're gonna try this stripe web hook construct event so when it tries this with the three things that were passing it here if it works we know that web hook actually exists so we can verify the web hook if it doesn't then it's gonna throw one of these errors so I'll just move these over and I'll convert these to flask so this should be something empty and it returns the 400 status code so I'll just print invalid pelo and then down here likewise instead of HTTP response you can just pass an empty dictionary with 400 for the 400 status code and now prints invalid signature and then down here let me make sure the indentation is right here this is where I'm gonna handle the checkout session pleated which is the one I want and then this fulfill the purchase we won't have and then I already have the return 200 so now the code is completely compliant with flask and now to get this endpoint secret this is where I use the command line interface so what I'm gonna do is I'm gonna open up a new terminal and I don't think I need to start a virtual environment I'm gonna use the stripe the command line tool so it's cost right then I'm gonna say listen and then - - forward - so - - for it - - and then I need to pass in the URL for my endpoint so it's gonna be one two seven zero zero one five thousand slash stripe underscore web hook I can't run that and it's gonna give me these secrets so I can just copy this and put it in here so the reason why we're using this is because in a development environment stripe you can't send a request to my local machine but what it can do is it can send a request to my app through this command line interface while I'm running it so that's why I have to do this stripe listen and it's gonna forward all the requests to this URL that I specified so stripe web hook is the same as stripe web here in a production environment what you would do instead is you would go to the dashboard and you would see the developers part and you go to web hooks and then you can add an endpoint for a web hook and then it's gonna give you that same endpoint secret but like I said we're on the development server so that doesn't make any sense I have to use the command line tool so now that I have all of this what I should be able to do is I should be able to see a session when it gets created so I'm going to print the session and we're gonna see it running after we submit our payment so here's my app and we're gonna see these print statements fire off when I make a payment and we'll see it happen multiple times actually so let me go back home and because I copied it like the indentation is all messed up so let's see so line 65 is a little weird let's try this and let me restart my server okay so now I'll go and buy the product let's call this webhook at gmail.com and then 42s and then webhook one two three four five okay so we're gonna pay and now we're gonna look here and if you look we see webhook is being called multiple times and then when we get to the web hook for the event that we're looking for checkout session completed we can then see the session information for that particular payment so we see like the customer ID we see the ID for the overall payment intent so this payment intent is the unique payment for the user so this is what you want to use if you're storing it in the database so if you have like an order table you're going to store this in the order table and for your order table you can make this column unique so you know you don't accept the same payment twice and then it's just the other information relevant to this and what I'll do is I'll show you some of it so what you can do is you can get the line items and that's everything that the user bought sauce a line items equals any stripe checkout dot session and then I think it's lists line items and you can pass in a limit the limit is going to be 1 and y'all sees a passed in the session ID so session ID just like that is the first argument and then what I can do is I can simply print out the value of the first one because re I know only I know only have one so line-items data it's gonna be zero and in description if I recall correctly and now let me try another payment I'll go back home by now I'll say line item at test comm 42s again line item and then one two three four five pay the webhooks are going to fire and then we see down here for the description we have the product so that's the product that was purchased by the user so all this information in here this is where you would handle the fulfilment part so this is where you can like add it to your database send email is telling the user that they have access to the products or you can add it to some kind of dashboard where you know an employee will actually pack the order and send it to someone whatever the process is this is where you would handle it so you don't handle it and the thank-you page is better to handle it here in the webhook because you know it's more reliable that way so this is the basic process of using stripe check out obviously can be a lot more complicated you know you can sell more you can do more after the users paid but this is the basic overall process and I thought I'd make this because they don't really have a good tutorial for flask so if you have any questions about this process just leave a comment down below and I'll try to answer it and that's it for this video so if you like this video please give me a thumbs up if you haven't subscribed to my channel or you please subscribe thank you for watching and I will talk to you next time
Info
Channel: Pretty Printed
Views: 16,772
Rating: undefined out of 5
Keywords: flask stripe, stripe, checkout, payments, flask, python, stripe payments in flask, accepting payments in flask
Id: cC9jK3WntR8
Channel Id: undefined
Length: 32min 50sec (1970 seconds)
Published: Fri Jun 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.