Accepting Payments in Django Using Stripe Checkout

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone in today's video I'll be showing you how to integrate stripe check out into a jingle app so right now I have this simple page setup and I also have a Thank You page and we'll be using these two things for the app I have my stripe account so you have to have a stripe account I have the test account working right now and then I have a documentation up for stripe on how to integrate checkout so they actually have an example with Jango so I'll be using a lot of that code and I'll be explaining it as I go along so most of the code would be the same but I'll do something slightly different so you can see how I will integrate it into my app and then finally you need to have the stripe CLI so this will allow us to test web hooks which I'll do towards the end of the video and the stripe CLI is the only way to do that locally so to get started the first thing I need to do is set up stripe in pip so I'll go back to my app and the files are just you know views and the templates that I just showed you so a pip install stripe and once I do this what I want to do is I want to bring in the configuration values for stripe so I'll have tokens so I'll go to my settings file and at the bottom I'll add the tokens that I'm going to get for my test dashboard so I'll go to developers I believe and then API keys and then I have a publishable key and a secret key so I'll just copy this and I'll say something like stripe public key and I'll just copy the public key that I have and then I'll do the same thing for the private keys so stripe private key and I'll copy these and of course in a real situation you probably wouldn't want to hard code the the tokens right here it said you can import them from environment variables or some other source that's not you know saved in your source control so the tokens can stay private but for example purposes I'm just putting them here so once I have this let's take a look at the documentation to kind of see the process that I have to follow so I set up stripe already that's step one the next step is to create a product and prices so before you can have a checkout process you have to have the ID of a product and a price for that product that the user is going to pay so to do that you can set that up on the B dashboard here and to do it you go to products here on the left hand side and you can add a product and I'll call this product the Jago product and then you can add pricing to it so here I have standard pricing I have package pricing and graduated pricing value pricing doesn't really matter in my case I'll just keep it standard and I'll also make this a one-time payment and I'll make the price of this $99 so the Jango product will be 99 dollars in addition to the name of the description let's say the best product ever you can upload an image I don't have any images for this product so I'll just leave that blank and there are some other options but just generally you need a name for the product and a price and then you can save the product here in the upper right hand corner so I'll save that and then we just need to keep track of this price ID down here so with the product we get a product ID and a price ID we don't really care about the product ID for this example we only care about the price ID so we'll be coming back and we'll be using this somewhere but just take note that we have to use this price ID eventually so let's go back to the documentation and we've created our product in price so now we have to create a checkout session so they say this is server-side so the idea behind the checkout session is on your server what you'll do is you'll start a session that represents the things that the user is going to buy and of course it uses your credentials to start the session but beyond that you have to have the things that the user is going to buy so in our case we only have one product but imagine you had like a shopping cart or something and you had you know ten things what you'll do is you'll put the ten things in this session where you created so when they get redirected to the checkout page it will have all those things listed and they can pay the appropriate price so what I'll do is I'll copy this code for create a checkout session and I'll put it in my app and where I'm going to put this is in the views so I'll go to my views inside of my actual example app and I'll just put this up here so let me just format this a little better because it didn't copy correctly and then this is what we need okay so we have the stripe API he here so SK test that's not the one that we want and said we want the private key here so what I'm going to do is I'm going to import from Django CNF I'm going to import settings and then I can say the stripe API he equals settings dots and then stripe private key all right so now if I where in my app just to make sure that loaded correctly it should be okay then what I want to do is I want to put that price ID that I was just telling you about in the price field here so I'll go back to the dashboard and I'll just copy that price ID and I'll put it here I can select so we have the price ID for the product and then we need to have a success URL and a cancel URL so for my purposes I'll make the cancel URL the same as the buy page just to keep it simple because the cancel page doesn't do anything it's just where the user gets sin if they choose not to go through with the process and then the success URL is where they get directed if things are successful so this is what I want to create here so first I'll modify this so I'll build a URL for this and I need to import Reverse so from django to our URLs important reverse and what I'll do here for the cancel URL is I'm going to say reverse and then thanks because that's my thank-you page let me just go to my URL so make sure I have the name yes so name is thanks for the Thank You page and I want to build an absolute URL because this is going to be sent to stripe so I'll do requests dots build app salutes your I and then I can pass in that reverse here okay so I'll do something similar for this link above so requests build absolute URI and I just did this backwards so this should be index and the one above is gonna be thanks so bill absolutely URI and then I'll pass in reverse and I want thanks and because of this placeholder that stripe has in here it probably won't play well with the reverse here so what I'm going to do is I'm just going to kind of cat need it so by take off everything before the question mark and then just add it here it should maintain this check out session ID because this is a variable for stripe so when I try to pass this through Jango it might escape the curly brackets and that's not what I want I want them to stay there because I'm singing this to stripe so this should build my absolute URI or thanks and I'm appending this question mark session ID checkout session ID for the query string so now that we have this up everything with stripe and by the way this is only going to accept card payments so that's why card is here you can have other methods of payment and stripe but you know card is the one that everyone is familiar with so I'll just leave that there so now that we have this session that was created so we have the idea that something is going to be purchased by the user we need to then send this information over to the template so I can redirect the user to the checkout page when they click on the button so I'll create the context dictionary and in it I'll have the session ID so I can just take session ID this object that's created here from session decreed and then I'll also pass in the stripe public key so say stripe public key so when you have something on the front end you'll have the public key instead of the private key so this should be settings that stripe public key and we'll meet that momentarily so now let's go over to the template so templates index and what I'll do is I'll bring in the code that they have and I'll show you how it gets used so let me go over to the documentation and we see the redirect to checkout so the first thing that they tell us to do is import the scripts so I'm using plain HTML here if you're using something like react the process is a little different as you can see here but with plain HTML we can just take the script tags and place them in our code I'll just place them at the bottom after the Buy Now code and then I also need this code here that will redirect to checkout so let me copy this and I'll paste it in a script so let me create the script tags and close out the script here and just for about this a little bit better so let's see this on these feet and in sit there that looks good so now I have the code for importing stripe and then redirecting a check out and of course I need the session ID here so this comes from the templates so I can actually keep the brackets here because this is the same in the template language and what I want to use is the session ID so session underscore ID right here and I need to maintain the coats because I'm taking the session ID and I'm putting it into JavaScript so it's kind of bypassing the HTML and going into JavaScript so I still need the quotes because the quotes need to be around the session ID which will just be assuring without the quotes so now that I have this I have to worry about putting an event handler on the button so any time the user clicks on the button they'll be redirected to checkout which is what this function here does so inside the script what I'll do is I'll get the button so we'll say Buy Now button Buy Now button equals documents query selector and I want to select the button so I have an ID here Buy Now button so I need the hash and then Buy Now button and then from there I can add a click event so a button or buy now button that event listener and I'm listening for click so now event I'm listening for click and then what I want to do is create the function body here and inside the function body I can put this so actually I'll just move this down and then indent everything here so now this code will only get executed after the user clicks on the button right so now let's go through the process and see if everything is working correctly and I feel like I'm forgetting the a stripe key so let me see where that gets at it yeah so I forgot this part here so we have to take that public key that I put in the context and we have to put it in the code here so I'll put this above and this is going to be the stripe public key what did I name this yeah stripe public key just like that and for the same reason easy to go into quotes as the session ID so let's try this and see if it works hopefully there are no errors I'll refresh the page and we see stripe is not defined that's pretty easy to handle because I forgot to import stripe so import stripe now let's go back refresh okay so we have the page and then I'll hit by now and nothing happens so let's take a look at the console so it says please call stripe with your publish Opel key use an empty string so it looks like the settings aren't loading properly and let me make sure my settings are saved and they're printing so I'll go here and I'll just point out the public key let's see if it's there so let me refresh the home page and then I printed it and we see the public key is there so maybe it's not being imported in the template so what I can do is I can go to the view source and I see there's nothing there for the the public key or the session ID so somewhere I didn't add those in correctly so let's go we have striped public key oh this is a pretty easy thing to fix I forgot to pass the context to the render function so context like that and now if i refresh the page okay we don't see any ears so by now I clicked it so now I've been redirected to the checkout page and if I look at the URL I'm on stripe now instead of my app so now I'll just put in some information so a test user at gmail.com the card information for the tests account is just 42 over and over again so 42 42 42 42 put an expiration date in the future any CVC any name and any zip code so 8 4 1 3 5 pay $99 and if it turns green it redirects me to the Thank You page because that's what I put in the success URL and if I look at the URL here I have my app so localhost thanks and then I have that session ID and then just has a session ID for the thing that I just purchased so I don't need to use this for anything and in fact I really don't want to use this for anything because this isn't guaranteed to happen imagine after the user purchases something they click the button then they close their browser the payment will still go through but they'll never make it to the thank you page so you don't want to depend on the user making it to the Thank You page for you to know that the order has been confirmed so later in this video I'll show you how to handle that so if we go over to the dashboard and look at payments I see a 199 dollar payment that has succeeded from test user at gmail.com but I also see three other payments that are incomplete and the reason why these payments are incomplete is because these are created after the session is created so once I create a session it is waiting for a payment and then once the user pays then I will say that the payment is successful but every time i refresh the page so let me go home every time i refresh the page and then I'll refresh the dashboard it creates a new incomplete payment and this is not what I want so what I want to do well this could be what you want actually if you have a process where you know the user is about to check out when they land on a certain page and you know they'll only change their mind if they're backing out a checkout process then it's potentially okay to generate the session like this but if you have a case where you know the user has to decide whether they want to purchase or not then you probably don't want to generate the session in this way so for this example it's pretty bad because you only have to click one button you can purchase but if it were something like a shopping cart where you add a bunch of things to a shopping cart and then you say I checkout and on that checkout page you built a session on the back end then it's not that big of a problem but you know it's its preference but ideally you wouldn't want to have these incomplete payments in here unless the payment was truly incomplete like the user at first intended to pay but then they changed their mind so to handle this what I need to do is I can create an AJAX version of this process and what will happen is when the user clicks the Buy Now button it will go to a route that will generate the session and then from there it will redirect to the checkout page so the session only gets generated after the user clicks on a button not before like in this case so let's go over to the code and it will create an example using be epi so now let's create that's in point that would be called through an AJAX call so I'll call this checkout takes in a request and this is going to return JSON so I have to import the response for that so from Django dots HTTP import JSON response okay so we're gonna return some kind of JSON response here and I'll fill this in later and this is going to be from a post request and you know in Django by default you have to have cross-site request forgery tokens anytime you have a post request but in this particular case I don't want to have it so I'll make this exempt so I'll import CSRF exempt which is this and if you want to have CSRF tokens on this you can but for the example purposes I won't have them so I'm just making it exempt here and then what I'll do is I'll add a URL so it's called checkouts and we'll say a path check outs and then views checkout and the name will be checkout as well okay now that we have check out what I can do is I can basically take the code from index so all the stripe stuff from index and I'll move it down into the checkout so the same code is being executed is just in a different place and I want to return the session ID and the public key to the response so basically I'll take this and I'll pass it to the JSON response and I have to return this and here I can get away with just passing the template again and with this I can go over to the template and modify this a bit so now instead of the redirect to check out being executed when the user clicks a button I want a call to that check out route to be executed so what I can do is I can put a fetch and I'm going to be fetching to check out so check out or just slash check out and then after that I'll get the results and I need to convert it to JSON so return results - no it's just JSON and I'll have the data available and in here I'll have the redirect to checkout so let me move this up paste that in there and then just format it a little bit better and everything looks good so now I have to modify some of the parts of the code so remember that I'm passing the public key and the session I be through the response so I won't have the public key here anymore so I have to move this down I need to put this inside of the then after the JSON is returned and instead of stripe public key like this I can just use data that check out check out data what did I call it stripe public key and then likewise I can do the same thing for the session ID so it's just session ID and I'll need to be well I don't need their quotes because this is JavaScript so data session underscore ID okay just like that so now let's try this process let me make sure I didn't forget anything and let's see if it works so I'll open up the console make sure I have no errors refresh the page no errors and let's go to the dashboard and I still have one above the completed ones so from the example I'll just refresh this a few times and then I'll go to the dashboard refresh just to make sure I'm not getting any incomplete payments and I haven't so now let's try purchasing so I'll click on the button it redirects piece of the page and I will try it so Ajax at tests calm and then we have 42 s and then I'll just put a date in the future so 25 and Ajax tests and then the zip code 1 2 3 4 5 ok so we can pay and then if it works we should be redirected to the Thank You page again and this is taken a while to process okay so that took a while but we got redirected Thank You Paige successfully and we have the session ID in the URL if we go back to stripe and refresh we should see Ajax tests was successful and we have this exceeded payment here so it only creates a session when the user actually clicks the Bible and if the user click the Buy button and then on the checkout page they decide that they don't wanna put in their credit card information then the payment will be incomplete but that makes more sense because the the user had the intent to pay at one point unlike before where they were just loading the page now that we're able to complete a payment what we want to do is we want to verify the payments now so I want to make sure that when the user pays that they have actually paid and I don't want to depend on them to redirect it to the checkout page so what I'm going to do is I'm going to set up a web hook so web hook is basically just an in-point or your app that some external process will call automatically as a result of some event happening so in this case when the user makes a payment it will send a request to our app saying that a user has made a payment and will be able to see that in the code so I'll go back to the stripe documentation let me close this I don't need it and we see the confirmed payment as successful part and they have like webhooks they have other methods but I'll use webhooks so what I'll do is I'll bring in the code and they say I'll copy everything and move it around as necessary so I'm going to create a new endpoint and we'll call this stripe webhook so stripe web look requests and then I'll just paste all the stripe code in here and I'll remove the things that are necessary so we have the stripe API key you don't eat that again but since we're using the stripe stuff in two different functions we have to move the API heat initialization outside so I'll just put this at the top of my file next we don't need to import HTTP response we'll actually we do but it's gonna be a blank response so I'll just put this at the top of the file and this actually can go with JSON response okay so now if I go back down it looks like everything else is okay so I just need to make sure everything is indented properly so I'll just move everything over and looking at it most of it should work right away so let's see we have this if and then this handle check out session function this doesn't actually exist so I will just put our example code down here and then I'll move that over so expected in a block on line 38 and oh so I have the you defined twice I'll remove this one I'll move the CRS F token exempt above and then the in point secret I'll get momentarily because I have to create the webhook but it looks like everything else is fine I run it and it's not breaking anymore so I have the striped seal I installed so like I say you have to go to the documentation to install it I'll open up another terminal and what I'm gonna do is I'm going to start up the process so to do that we have this listen here so listen to a certain point and what I actually need to do is I need to create a URL for this so path a stripe web hook and then views stripe web hook name stripe web hook okay so here is the command that I have to run and I just need to modify this to listen to or send that the web hooks to our particular endpoint so I'm adding the trilling slash this will be localhost port 8000 and then I can copy this and run it so once it's ready it's gonna give me a web hook secret so I need to take this and put it into the view here where we have the endpoint secret so typically you would create the web hooks on the dashboard so here but the thing is I can't create a web hook here that stripe can talk to you directly because I'm on my local machine there's no way for stripe to send a web hook directly to me so that's why I have to use the stripe see a lie because the stripe CLI will basically be in the middle so stripe CLI is listening for web hook events and then the events will be forwarded to my actual web hook in the app so now that I have this I will be able to see the web hook working so let me see if there's anything I should print like when the web hook fires I want to print a web hook all right so we'll see this on the terminal here so I'll create a payment by now tests webhook at gmail.com and then this is 42 s tests webhook okay so we're going to pay and we'll go back over and we see webhook is being called several times so there are different types of events the event that we're concerned with is the check-out session complete which I'll show you momentarily but this just shows that the webhook is being called it's being called it looks like five times here so there are five different events that get called and then a user gets redirected to the Thank You page so just to go over what's happening here is when the web hook is called it's gonna get the request body so the data that the web hook is sending along with this signature and then the signature is going to be used to kind of verify that the web hook is legitimate because it is an open endpoint so anybody can send a request here web hook endpoint but if they don't have the right signature then it will fail when you go to construct the event using the stripe API so if this succeeds if the event gets constructed that means the web hook is legitimate and there's information and if there are some issues than it will just raise an error so down here this is where the event can be checked so in this particular example they have a checkout session complete it which is exactly what I want and in here they're getting the session so the session is going to be related to the session that we create here so this session is just a completed version of the same session that we first created so I can do something like print session and also in each session we can get the line items so the line items represent everything that the user paid for so we won't see them on the session directly we have to query for it so what I can do is I can say line line items equals a stripe that checkout and then session and we're going to I can spell session we're gonna list the line items and to do this we have to pass in the session ID so it's gonna be that session object above an ID it's actually a dictionary and I can say limit one because I know there's only one product and I'll just print out the line items right so now let's go ahead and make another payment and tests say test line items so let's be test line items at gmail.com and then and then six twenty five four five five tests line items and then one two three four five ok so we'll pay and what we expect to see is when it succeeds we want to see the session and the line items so here we have the session so let me just bring this up we have the session gives you information about it and here let's see we have the description so this is the line item we have the Django product we have the subtotal and we have other information about the product itself but you know in our case the most important things are the amounts and the description we want to know what was actually purchased so using this web hook we can then do something in our system so imagine you know items needs to be shipped out we can change a flag in the database saying that the order has been processed and it is waiting shipment or something like that or you know you have a process where an email can get sent to the person saying like hey here's your ebook or whatever just depends on what you're selling but you would do it here in the web hook instead of doing it at the thank-you page so you know that the user is actually purchase and they didn't just land on the thank you page and use like a fake session ID so that's pretty much it for the basics of the stripe checkout process of course you can make it more complicated if you have a more complicated checkout system but this is the essential knowledge that you need to know to at least get started on it if you want to use it in this way you want to extend on it then it just depends on whether you're particularly use cases so if you have any questions about this feel free to leave a comment down below if you like this video please give me a thumbs up and if you haven't subscribed to my channel already please subscribe so thank you for watching and I will talk to you next time you
Info
Channel: Pretty Printed
Views: 14,675
Rating: undefined out of 5
Keywords: django stripe, stripe, checkout, payments, django, python, stripe payments django, accepting payments django
Id: JwhEjEqG43M
Channel Id: undefined
Length: 32min 39sec (1959 seconds)
Published: Wed Jul 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.