How to build an eCommerce Website using React Redux, GraphQL, Firebase #20 – Stripe Payments API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to the 20th video in this tutorial series on building an ecommerce website using react redux graphql and firebase in today's video we're going to be working on our checkout page we're going to be integrating with stripes payments api to securely process the payment but before we begin let's run through a quick demo of what you will have built by the end of this tutorial of course you can click through to our search pages of course we have infinite scrolls so as you can see we can view more products but let's add something else to our cart once we're satisfied we can click on check out and i'm just going to skip ahead and fill in this form but as you can see the user is able to enter a separate shipping address to their billing address they can also enter of course their card number now i am using stripes development api keys which means that i am currently running a test environment on my local machine and i can just use their test card number so that is the following number once that is filled in i can just hit pay now and once the payment is successful i'll be redirected to the home page and my cart will be cleared and as you can see the payment was successful i can see all the information about the transaction as well as the shipping information and of course you can also see the full payment intent which is a huge amount of data that in upcoming tutorials we will be using to actually create and store users order history within another firebase collection before we get started i just want to encourage you guys to check out my official youtube channel you can find that at youtube.com forward slash simpletut not only to find my other videos but also the official playlist for this series i also want to encourage you guys to check out the official github repository for this project you can find that github.com forward slash simple tut you can find my official website at simpletut.com but most importantly of all please do like comment and subscribe and don't forget to turn on those notifications in this tutorial we're going to be implementing stripes payments api into our application we're going to create a checkout form where users can enter their shipping billing and credit card information and then we're going to use the react stripe.js library to process that payment redirect the user to a confirmation page and then clear their cart now before we get started please do create your own stripe account and log in to your dashboard we're going to need to get our api keys but before we can do that we do need to install a few more dependencies into our project both for our firebase functions and for our main application the first thing that we need to do is install the dependencies we're going to be using in this tutorial now the first one is going to be react stripe js now this is the official documentation for this library i'll be posting a link to this in the description of this video but you can also just search google for react for react stripe.js and this page will come up but again it is on the official stripe website um and it should be quite easy for you to find alternatively you can just copy this command which again i'm just going to be copying directly from the documentation so what i'm going to do is come back over to vs code i'm going to go into terminal new terminal and i'm just going to run the command and this will install those dependencies into my project so i'm just going to enter that and click on return and let that install okay so now that that's installed i'm just going to clear down my terminal and i'm going to install two more dependencies the first is axios we're going to be using this to make asynchronous requests to our firebase function we're also going to need to install react country region selector and again this is something we're going to use later on in the tutorial so please bear with me let's install these dependencies and we'll talk more about them a little bit later so i'm just going to hit on return and that's going to add those dependencies to my application and that's all the dependencies we need to install for our main application but as you know we also have a separate application within our project for our firebase functions this is what we created in the lost tutorial and as you'll remember this has its own mpm dependencies and its own package json file so i need to actually install stripe for my firebase functions so what i'm going to do is i'm just going to navigate into my functions directory so i'll just say cd functions and as you can see i'm now inside of my functions directory and i'm just going to go ahead and npm install stripe at this point we're ready to start coding we need to create our new payment route this is going to be the page that houses our checkout form where the user will be able to enter their shipping billing and cod information so the first thing we need to do is head back over to our text editor we need to create our new page component so within my pages directory i'll create a new folder we're going to call this payment it's only going to be a functional component so we'll just have an index.js we're going to import react from react it's just going to be a function so we'll just say const payment equals a function we're going to at this point we're not going to return anything until we create our components we'll just say export default payment but we need to go ahead and create the component so we're going to create a payment details component so in the components folder let's create another folder called payment details this is going to have both an index file and a style sheet so we'll say styles.scss and in the index file we're going to import react from from react we're going to create a const called payment details it's a functional component so it's just going to equal a function and we're just going to return a div with a class of payment details and we're going to export this by default so we'll export payment export payment details and we also want to import the style sheet so we'll say import styles dot scss and for now that's going to be enough for us to come back over to our page component so this is paid this is our payment component and we're going to import that payment details component we'll import that from our components folder so we'll import that from components payment details and we'll just render that component for now now all i need to do is actually define my route so i'm going to come back over to app.js this is where we define our routes and i'm going to import my new page component which is import payment from pages slash payment and what we want to do is just underneath where we define our cart route we're going to create another new route the path is just going to be slash payment we're going to call the render prop and what we're going to do is define our layout so we're going to define main layout and we're just going to pass in our payment component okay so at this point we've created our basic page component and our payment details component and this component is the one that we're going to be building our forms into so this is where we're going to actually render out a checkout form where the user can enter their shipping billing and cod information so the first thing that we need to do is just build out that form right so to do that what i'm going to do is reuse some components we wrote in an earlier tutorial in this series and that's our shared forms components so in my components directory we have this folder called forms and in a tutorial earlier in this series we created our form input and button components well we're going to use that here right so at the top of our payment details component we're going to import our form input we're going to import that from forms slash form input and then of course we want to import our button component so we'll import that from again forms slash button and then what we'll do is we'll wrap this in a form so i'm just going to create a form and on submit on the on submit event we're going to call a function so we'll say const handle forum submit this is going to be async it's going to take the event and all we're going to do now is we're just going to capture that event and call prevent default and that's going to stop the page from reloading whenever this form gets submitted so we just need to pass that to our unsubmit event and then what i'm going to do is i'm going to wrap so this form is going to be divided into three sections right so we have shipping we're gonna have another section for our uh billing and another section for our card details so i'm to create a div here and i'm going to give this the class of group and i'm going to have a h2 inside of that and we're just going to call this shipping let's duplicate this for each of those sections so we're going to have another area for billing and another one for card details right so maybe shipping address and shipping address so billing and shipping address and card details now under the h2 we're going to have our form components so now we're not going to worry about our state just yet we just want to get the initial form in place so let's just create our form our basic form input let's just specify the type which is going to be of type text let's specify the placeholder which for this is going to be recipient name then what i want to do is just duplicate this a couple of times so we're going to duplicate it for line 1 right so the line 1 of the user's address we want to duplicate this for line two if there is one we need it for city state and postal code so i'm just going to create another one here for city another for state and another for postal code right and then i want to have the same fields apart from recipient name in fact i'll take i'll take that too i'm just going to copy all of these fields so all of these form inputs i just created for shipping and i'm going to put them into billing right because we basically need the same fields but apart from this placeholder for billing being recipient name we're going to change this to name on cod right and then finally we're not going to worry about card details just yet because we're going to be using a stripe component for our card our cards our card field but what we can do now is just view this page in the browser so what i'm going to do is just going to manually enter slash payment into the url hit return and we're gonna be able to see our forms and our payment details component right so it's looking pretty good um but what i will say is that we do need to add a little bit of styling in because for one you can see that there's no margin above our h2 so we're directly sitting on the the header here and really we need some gaps between the groups so what we can do is just come back over to the style sheet for payment details we created and imported into our component we added this payment details clause here so i'm going to use that i'm going to target it and i'm just going to set some basic settings here so i'm going to set this to be display block with a width of 100 percent um let's set a max width of something like 1000 pixels now again i'm using uh rems here which you will know if you followed the series which means root m's now because my base my root font size is 10 to calculate the rem size i just have to divide that number by 10. so in this case it's 100.0 rem which is 1000 pixels we're going to set the padding here we're going to reset that to zero and we're just going to set a margin here of about 20 ram which is 20 pixels top and bottom and also right and left we're then going to target the group class we created and assigned to those sections and we're just going to add a margin here top and left and right 0 but we're going to add 20 ram which is 20 pixels to the bottom right so let's come back now over to the web browser and you're going to see that again this is just slightly improved the page visually and that's great now unfortunately we are still missing one field for our addresses and that is the user's country now you'll note you will have noticed at the start of the tutorial when we installed new dependencies one of those new dependencies was react country region selector right and this is just going to be a really easy way for us to add a drop down component to our forms for the user to select a country right and you can see this is a really great little library that has some really nice options it's just very easy for us to use this and that's why i've incorporated it into our project and i'm going to show you how to use that now so let's go ahead and add that into our page so the first thing we'll do is just come back over to our text editor we need to come back to our payment details component and at the top of the file we're just going to import something from react country region selector which is our country drop down right and then what we're going to do is wherever we want to render that so we want to render that for our shipping and billing address what we're going to do is we're going to just render our component right but we need to pass some custom props so the first thing is the value type we want this to be the short option so we'll say value value type equals short and this is just going to mean that rather than saying united states it's just going to or great britain it's going to say gb which is what stripe will expect on their api now we are going to have a few more things to configure here but for now that's fine but what i will do is i'm going to just save this and come back over to the browser and show you what this looks like so as you can see uh we do have the field i can click and expand it and you can see we have all the countries so you can kind of get the idea of why i wanted to use another library for this because imagine trying to maintain this component yourself it's not going to be very easy but there is a problem the problem is that it doesn't match the styling of the rest of our form so there's going to be really easy way for us to fix that so what we'll do is come back over to the text editor let's go into our form input component here and what you'll see is we have a clause defined here for form row so i'm just going to come back now to my payment details component and i'm going to wrap this in a div with a class of form row and i'm going to i'm just going to wrap that component with that div but i am going to add an additional class which is going to be checkout input and then we can come back over to the style sheet for our form input which is here and what i'm going to do is rather than just targeting an input type what i'm going to do is i'm going to add a comma i'm going to use the and symbol and i'm going to say if this has an additional class so i'm talking about form row if it has an additional class of checkout input then go into target the select within that and apply the same styling so we can now come back over to my form and you can see that the style is inherited and this is much more in line with what we have on our other fields which is great okay so we just need to duplicate that now for our billing address because we're going to need a country select there too so let's add that in here underneath postal code for billing okay so now that we have configured our basic form components we're ready to start creating our state so to do that we're going to have to import something from react which is the use state hook because this is a functional component and then we need to define that state so rather than individually setting state for each of the fields within our address i'm going to create a basic object that we can use to handle both shipping and billing right so what i'm going to do is i'm just going to call this so we're going to say billing address and set billing address we're going to call the use state hook and for now we're just going to pass in an empty object we're going to do the same thing for our shipping address so we'll say shipping address and set shipping address and again we're going to call the use state hook now the only other two pieces of state that we need to create is for recipient name so we'll say recipient name and set recipient name and this is just going to be a simple string so we'll say use state and we'll just specify that as a string as an initial value and then finally we need to set the name on the card so we'll say name on card and set name on cod and again this is going to be a simple string so we'll just say use state and define that initial value as an empty string now of course this field is going to have more than one one value more than one key on this object so what i'm also going to do here is just define an initial address object so we'll say const initial initial address state and we need to do this because otherwise you will see console errors for your form components changing uncontrollably so we need to define a basic line one here we'll define that as an empty string we'll say line two define that as an empty string we have city state and i believe country and postal code which are all going to be empty strings and then we're just going to use the spread operator to pass that in to our state for our addresses okay so now that we've created that state we can bind that to our actual input fields for the appropriate fields right so for example for our recipient name we can set the value to be that of the recipient name for line one of our shipping address we can set the value to be shipping address dot line one we can do the same thing for each of these fields so we can do that with line two with city we can do the same thing so we'll say city we'll do the same thing for state so here we'll say state again for postal code so we'll just say postal code and then finally for even our country drop down we'll say value and that is going to equal our country we're going to need to do the same thing for billing so here again the value is going to be set on this occasion to name on card then the value for this is going to be value this is going to be our billing address dot line one so then we can copy this and just use that throughout our form so we'll replace line one with line two then we need to set this as city we need to do it for state and finally for postal code and for country okay so at this point we've successfully binded the values of our form inputs to the values that we're storing within our state but we're not updating that state whenever a user changes or inputs makes a change so just see that in the browser let's come back over and let's actually try and type in one of these fields and you'll see that you can't because we're not handling that change event so to handle that what we need to do is we need to assign first of all the name to each of these form inputs so we need a name attribute for each of these fields so we're saying name is recipient name line one we're going to assign that to line one we'll do something similar here for line two we need to assign it for city so we'll say name equals sorry city the name for our state is just going to be state postal code it's very important that the name matches the name you assigned your state so in this case postal code needs to match here for the name you'll see why shortly we don't need to worry about our country drop down um again name on cards so we'll say name it's going to be name on card we need to do it again for line one here for billing so name is line one line two city state postal code again needs to match and again we don't need to worry about our country drop down now the way that we handle the uh change events for uh our name on card and recipient name state is going to be different to how we handle our addresses the reason is that our addresses is an object right so it could actually be any one of these fields that we want to change at any one time but the functions and the methods that we're going to call here for our recipient name and name on card it's just a string so we're only ever updating this so that's going to be a little easier we can handle that first so let's tackle our recipient name on our shipping address first so what we're going to do is we're going to call handle change on our form input component right and if i just go into the form input component you'll see that handle change is just passed to our input field on the unchange event so what that means is we're going to get an event right so we'll get the event and then we're going to call the set recipient name method with the event dot target dot value and that will update the state right and we can do something similar for our name on card for our billing address so down here uh what we'll do is we'll say handle change still the same component same prop we're going to get the event then we're going to call set name on card with the event target dot value right now if i was to save those changes come back over to the browser you'll see that i'm now able to type in these fields right but i still can't type in my address fields so what i'm going to do is come back over to the code and i need to figure out how i'm going to set how i'm going to handle this because i need to be able to change any one of these fields that we have on our billing and shipping address objects so to do that i'm going to actually create a method a function so we're going to say const handle shipping first of all right this is just going to take the event and then we're going to destructure from that event from from the event dot target right so we wanna destructure the name and value uh from the target and then what we want to do is call set shipping right and then we're going to use the spread operator to pass in any of the initial or the current state but we're going to update the current name right we need to put that in brackets because uh it is a dynamic value and then we're going to just set the new value right so we need to do the same thing for for billing so what we'll do is we'll say const handle billing right again it's going to take the event we're going to d structure name and value from the event dot target and then we're going to call set billing address right again we're using the spread operator to pass in the current billing address and we're going to update the name with the value this function received and we'd be structured from the target so now that we've created these two uh functions we can use them to update our state so on line one what we're going to do for our shipping address form fields right so for line one we're just gonna call handle change we're gonna get the event and then we're just gonna call handle shipping right and the nice thing here is we can literally just paste this to each of our fields so we can paste that to line two to city to state to postal code we don't need to make any changes and then for our billing right so for line one what we're going to do is again say handle change we're going to get the event but this time we're going to call handle handle billing and we're going to pass in the event but then again we can just copy this to each of these fields so city state and postal code right so now let's come back over to the browser and try and change the content on this form so we'll say here joe blogs we'll say first lane you know you can say whatever here maybe skip that etc etc so you know example uh example so you can see that all of this is now working but unfortunately we still can't change our country so we still need to do a bit of work on our country field so let's just finish this off by coming back over to our code and let's start off with shipping so this is our shipping our shipping form and what we want to do is on our country drop down we've already assigned the value so all we need to do now is just set the on change event so we're going to call on change and what we want to do is we want to get the value so we'll just say val and then we're going to call handle shipping right but what we're going to do is we're going to set the target and the name we're going to set the name to country and the value to be val right and then we can just take this code right and we can come down and we can paste that into our country drop down for billing but instead of calling handle shipping we'll call handle handle billing we'll save that come back over to the browser let's reload the page and now let's try and select a different country and you'll see that you can now see that the countries are being selected and that's for both billing and shipping it's working for both okay so at this point we've built our checkout form and we're ready to start working with stripe and integrating the payments api so to do that to get started we need to head over to our stripe dashboard we need to log into our account and we need to find our api keys so once you're in your dashboard click on developers and api keys and what you're going to see is your publishable key and your secret key you're going to need to copy both now the first one i'm going to copy here is my publishable key and this is what we'll use on the front end of our application right so it's okay for this key to be exposed to the public now once you've copied that let's come back over to our text editor and what we want to do is actually store this key in a configuration file so within my source directory i'm going to create a new folder called stripe and i'm just going to create a file inside of this called config.js and all i'm going to do here is just going to export const publishable key equals and i'm going to paste my publishable key here as a string and what i'll now be able to do is come back over to my pages component right so this was this is my pay payment component so we want to import first of all something from at stripe react stripe.js which is going to be elements and then we want to import something else from the core stripe library so it's just stripe stripe.js and we want to import load stripe and then finally we want to import our publishable key which we have stored which we've stored in that config file so that's outside of this folder it's in stripe config and it is our publishable key and then all we need to do is we need to wrap our payment details component with elements and outside of our payment function i'm going to create another const here we're going to call this our stripe promise and that's just going to equal uh load stripe we're going to call that and pass it our publishable publishable key and then finally all we need to do is pass stripe promise a stripe to elements now all we need to do to render our stripes card component is head over to our payment details page at the top of this file we need to import the wrapper that stripe has provided for us so we'll import that from stripe and the react stripe library we need to import our card element and then at the bottom of this file where we have our card details i'm just going to render the card element now i also want to configure some options on this component so i'm going to pass a configuration object as to the options prop now i do need to configure that so above here just above where i'm returning i'm going to say create a const called config card element right and this is just going to contain a few custom options which i'm not going to go into too much because i don't think it really is too relevant here but feel free to check the documentation of how you want to configure this but what i'm going to do here is i'm going to set the icon style i'm going to set this to solid i'm going to just generally set some style attributes here right so what i want to set here is the base style which is going to be font size i'm going to set that to 16 pixels and also i want to disable the postcode so i'm going to say hide postal code i'm going to set that to true and that's all i want to configure here so i'm going to take that configuration object and pass that to my card element i can save those changes and if i scroll down you'll see that i now have my card component at this point we are now ready to start to to actually handle uh the stripe payment right so what we have is we have our form and on the submit event of that form we call handle form submit which is this function here which captures the event and is async right so the first thing that we need to do is we need to get our card element we need to store that in a constant so what i'm going to do is i'm going to first of all i'm going to need to import something else from react stripe.js which is use elements and then at the top of my function my component i'm going to say const elements equals use elements and call that as a function and then what i'll do is i'm just going to come here i'm going to say const card element equals elements dot dot get element card right so that will give us our card component which is what we just added to our form here right okay so we're now ready to actually validate our form data so what i'll do is i'll just create an if statement and what we want to check for is our shipping address line one usually line two is optional so i'll not i'm going to leave that out but i will say shipping address dot city if we don't have our shipping address state if we don't have our shipping address dot postal code or country right if we don't have it then we want to immediately return out of this function right so we don't want to go any further now of course that's just our shipping address we want to do the same thing for our billing address so we'll say billing address dot line one again we don't need line two really so i'll leave that out but we want to say billing address city billing address state billing address postal code and country and then finally we also want to validate that we have the recipient name and the on uh sorry name name on card state right so we've we're basically validating that we have all of the form data that we expect to successfully check out right now of course this is programmatically going to be a god to ensure that we never uh try to process a payment without this data but of course this doesn't prevent the form from being submitted which would be ideal so on in addition to the other props that we've passed to our form inputs i'm going to add an additional prop which is going to be required right now let's just add that to each of these here right so we'll go through we want to add that we don't really need it on line two so i'll leave that out that's optional city state postal code and even on our country drop down right we'll do the same for a billing address so name on card line one line two is optional city state postal code and our country drop down right and again if i if i now come back over to the browser if i was to try and submit this form all right which i can't do because i haven't got a button yet so again let's just head back over to the code at the bottom underneath my form element right here let's add in a button again that was the component we imported earlier of type submit and again as you can see up here we imported our our button component so let's again view this in the browser you see we have our button i forgot to add my text so i'm just going to add in some text here right so i'm just going to say pay now come back to the browser you can see there we go if i was to try and hit pay now you'll see that we just get the basic html5 form validation so it won't allow this form to be submitted without the correct data okay so now that we've added a guard into our handle form submit function we're ready to actually handle the payment creation and this actually needs to occur on the back end right for security reasons we're going to be doing this using our firebase function right so we need a api that we can post to so what i'm going to do is i'm actually going to run my firebase function so if i come into my functions directory which we created in the last tutorial into index.js you'll see that we've deployed an express app to our firebase function and at the moment all we have is our basic catch all 404 route right so we need to create a new route for our firebase function but before we do that let's just run this locally so to do that let's go into our terminal i'll say new terminal we need to navigate inside of our functions directory so i'll just say cd functions and i'm just going to run npm run server hit return and what that will do once it spins up is it will actually run our firebase function locally for us but it will also give us the url that we can post to so you can see here it says localhost port 5001 the name of the firebase project and the the api itself so if i was to for example just hold down command and hit and click that this will actually take me to that api this is my firebase function it's running locally at this url so i can then copy that url and we can use that to test and run our project locally okay so now that we have our firebase function running locally and we know the url of our api we can make an asynchronous request to it but before we can do that we need to create an instance of that api we can use in the application and i'm going to do that using axios i'm going to come into my utils here so in my source directory i have utils index.js at the top of the file i'm going to import axios right so i'm going to import import axios from axios and then i'm going to create an instance of my api by just saying export const api you can call it api instance right and then you can just say axios dot create [Music] and we need to set the base url to the path of our firebase function api now this is the url that we're running locally obviously if you are going to deploy this to production you need to make sure you update this base url with the production um url to your to your api but for now as you know we're running this locally in development mode so this is fine so now that we've created the instance and we're exporting it we can import that in our payment details component so let's go ahead and do that so i'll import that from my utils folder so i'll come out into utils inch and we're going to import that api instance and then within my handle form submit function right we've already validated we've got a god we've validated the form data so i can just i can just post that data right so i can call api instance dot post and the first thing it expects is where we're posting so it already knows the api instance so it already knows this is a path to the api but it needs to know the the route that we're posting to so we haven't created that yet but i can tell you what we're going to create which is payments slash create right now after you've done that what you need to do is pass the data which we're going to configure here so the first thing that we need to do is we need to pass the amount right so we need to know what the amount that we expect the user to pay now we don't currently know what that is in within this component right so we actually need to fetch that because that's currently in our redux store so first of all we need to import our selectors so we're going to import that from our redux folder slash car slash car selectors we need to import our select select card total we need to import something [Music] from reselect which is create structured structured selector and then from redux right so we'll just say from react redux right we need to import the use selector hook so then all we need to do is use what we just imported so we'll create our structured selector so we'll say const map state equals create structured selector we're going to set the total to be the select cart total and then all we'll do within our component here is call use selector pass it our map state structured selector and then we'll destructure the total amount and then all we'll do is come down again to our api instance where we're posting to our backend and we're gonna we're gonna set the total times 100 because it expects it in cents now the next thing that we need to do is we need to set pass it the shipping address so this is just going to be shipping it's going to be an object we're going to pass the name which is going to be recipient name and then address which is lowercase and we're just going to use a spread operator to pass in the shipping address object that we've stored in our local state what we can then do is we can just call then and for now and for now we'll just destructure from data the client secret which is what that will return right and we're going to handle that from there right but what we're currently doing is we are posting to our firebase function just specifically the payment slash create route and we're sending them the data that we have uh stored on our front end which is the amount and shipping okay so the next thing that we need to do is come into our firebase functions uh go into our uh create our express application and create our route so the first thing we need to do is just require stripe so we'll just say stripe right just say stripe equals require stripe we then need to call that and pass it our secret key so we can get our secret key very easily we just need to come back over to our dashboard we need to click this button for our secret key and then copy it come back over to our code and just paste that in as a string okay so once we've done that we can save that change we can actually use it so we can create our our new route so this route is going to be called slash payment slash create right we're going to get the request object and the response object and then we're going to have a try catch right we'll get the error here um now if there is an error here what we're going to do is we're going to call res we're going to set the status to a 500 error json and we'll just pass in the status code of 500 with the message equals the error dot message right something like that and then what we'll do for actually trying to process this payment right so we already know on the front end we're sending the amount and the shipping address so we'll just destructure that from the request dot body right so we want to get the amount and the shipping address right and then what we need to do is create a const of our payment intent so we'll say const payment intent right equals a weight so this needs to be async right async await right and then we call stripe dot create sorry no stripe stripe payment intents dot create and then what we need to do is pass in shipping we need the amount and we need the currency that we want this to be transacted in which is for me going to be usd which is us dollar then once we've done that what we want to do is send that back to the front end so we'll say res status i'll move that to another line so status of 200 which is okay uh and success and then we'll say send and what we want to send back is the payment intent dot um client under underscore secret right and we can save those changes okay so now that we've done this we're ready to come back over to the front end of our application and handle the rest and process the rest of the payment so what we can do is come back over to the source directory components and component details here and as i said before we're going to get back the client secret right so what we can then do on the front end is called stripe right so to get stripe what we need to do is here we need to call import the use stripe hook and then the same way we got elements we can say cons stripe equals use stripe call that as a function we now have access to the stripe object and then what we can do is we can call stripe here and create payment method and then we need to configure that right so we're going to say type is of card the card itself is going to be our card element here which we've already uh assigned to our card element constant here we're storing that in this variable we need to set the billing details right which again we already have because we have our name which is the name on card right we're storing that in state and for the address right we already have the address which is our we can use the spread operator and pass in the billing address and that's all we need to do so we can then call dot then right and again from this we can destructure the payment method right because that's what that's going to give back to us it's going to give us our our payment method and then we can actually just go ahead and process the payment at this point and we're going to need both our client secret and our payment method so to process the payment we just call stripe dot confirm card payment so confirm confirm card payment we need to pass in our client secret and then we need to pass in our payment method which again we have with our payment method dot id right um and then to actually uh uh get a uh and then what we can do is we can just call then and we can get the uh payment intent right and this is basically all the details about the transaction if it's successful so for now we can just console log out our payment intent right so let's just log that out to the console so the first thing i'm going to do is just make sure that you have your some items in your cart and then let's come back over to our our payment route so we'll just say payment and i'm just going to enter something like joe blogs so for the test card right but for the test card we want to use uh this again we're using the test apis so we can use stripes uh test codes so we just say four two four two four two four two four two four two um again because this is just a fake cod that stripe provides in their documentation that as long as you're using the development api keys this will work so you can test your payment gateway all right so let's run this let's uh first of all let's open up our network our network tab and click on pay now uh and as you can see we're getting an error okay so it's just saying that we're getting a 404 okay so let's check out our code uh and i can already see the problem so within my firebase function it's the http protocol i used get we're making a post request so let's just save that come back over and let's try that again pay okay and as you can see so this error was from before but this is our payment intent so the payment was successful and if i dove into the information here you'd actually see the details about the payment but we can actually do that from our stripe dashboard so let's come back over to our stripe dashboard let's go to home scroll down a little bit and you'll see that this was um that the payment that we just processed uh you can come down and see if you click on payments you can see more information about this payment transaction the amount you'll if you scroll down you'll see some more information about so here for example is your shipping address you can see example example example that we we added into the the payment form the checkout form and again this is your event data so this is all of the data about the transaction that you just processed you can see all of the lines of the code here and again we may use this in a later tutorial when it comes to creating our order history by you know saving some of this data to a firebase collection where we can store the user's order history so it can be very very useful okay so at this point we've created our checkout form we're able to even integrate with strides payments api we're processing the payment successfully but what we want to do now is take a bit of a step back and think about the basic user experience the workflow that we are currently sending the user through so the first thing that we want to change is we want to restrict access to this page users should only be able to make payments if they are logged in we also need to update the the checkout button on our cart so that it links to actually make to this payment page and once this the payment has actually been successful we want to clear the user's card and redirect them to either a confirmation page or maybe the home page so let's make a start and that will be very easy for us to achieve so we need to come back first of all to our code let's just close these files and what we're going to do is we're going to come back into our app.js and what we're going to do is we're going to wrap our payment route our page component here with uh with oauth which again is a component that we created in an earlier episode earlier tutorial from this series and that's all we need to do to restrict access to that page so if i now come back over to the browser you'll see that i'm i'm not able to get to that payment route if i was to go in payment i'm redirected to uh to log in right so i have to be logged in to see that route the second thing that we need to change is we need to make sure that we are linking to that page so let's come over to our cart we can get there through components and it is our checkout component which is here and we have um our button here to check out so what we need to do is we need to import something from router so we okay we already have our history right so we can just use that to push the user to the payments route so on the on click event right what we're going to do is we're just going to call history don't push and push them to slash payment right so if you come back over i'm logged in now if i was to go to my cart and hit checkout right i am redirected here and i can view the page because i'm logged in now if i logged out right and i come to my cart and hit checkout i'm just redirected to to log in right so that's a pretty good user experience really the next thing that we need to do is we need to make sure that whenever a user does check out successfully that we clear their cart and we redirect them to either as i said a confirmation page or let's say the home page so to do that we actually need to cr uh create a new uh action uh within our redux store so within our redux folder within cart and my cart types i'm going to create a new type which is going to be clear caught and the value is going to be the same name of the key and then we need to come over to my call actions and create the correspond the the corresponding action so we'll just say export const um expo cons clear caught it's just going to be simple action well function that returns an object with a type which is going to be the cart types.clear clear cart and then we can just come over to the reducer and again so this is my cart reducer if i come down create a new case so cart types dot clear types.clearcaught and then we'll simply return right we're just going to return the state with using the spread operator our initial state so then what we can do right is if i now so we now have the action the redux action to clear the code right so if i now come back to my payment details component and i go into this file right what i can do is where i import at the top of the file use selector from react react redux i can import use dispatch and then i can get access to dispatch right the same way that i got access to the state so what i can do is i can say use i can say const dispatch equals use use dispatch right so i have access to dispatch i need to also import the action right so i can import from my actions so within redux slash cart slash cart actions i can import clear cart and then i can come down and where before i was logging out my payment intent i can go dispatch and i can dispatch my clear card action right so that's going to clear the cart but it's not going to redirect the user but we only want to redirect the user once we know the cart has been cleared so what i'm going to do is i'm going to come back up to the top and where i'm importing my select total selector right i i know i also have a selector here for the select cart items count so i'm actually going to import that as well and then what i'm going to do where i'm creating my structured selector here i'm going to say item count right and then i'm going to be able to access item count the same way i access total right and then what i'm going to do is i'm going to import the use effect hook i'm going to call the use effect hook on the component so i'll say use effect that's going to take a function it's going to take a dependencies array and then i'm going to perform a check right i'm going to perform a check i'm going to say if the item count right is is less than 1 then i want to call history dot push and sorry not push state i want to push and i want to push them to let's say the home page right or it could be any page it could be a confirmation page and i'm just going to pass in the item count into the dependency array so that whenever this changes this code is going to rerun right so what's going to happen is once a user successfully checks out and has made the payment we're going to dispatch this action to clear the cart once the cot is cleared this item count is going to change because there's it's going to change to zero if it's less than one which will be true we're going to push the user to the home page okay so now let's come back into the browser and as you can see we're getting an error because we actually don't have access to history on payment details so that's going to be really easy to fix are we we're not importing anything from react router dom so we need to do that so let's import from react react router dom the use history hook we're going to get access to history by just calling const history equals use history call that as a function and that gives us access so let's then run that in the browser you can see it's working okay let's come back over to the cart so as you can see i have items in the cart let's change the values let's just say 20 pounds so change that to one okay let's check out so i'm going to click on check out okay it's telling me i need to log in so i'm just going to go ahead and log in so i'll say admin admin dot com enter the password let's log in okay let's come back to call it check out enter in some information so again let's just say joe blogs okay so i'm i've just skipped ahead and i've entered in the form so as you can see i have still one item in the cart i've filled in the form i'm gonna click on pay again i'm using the development api keys for stripe so i'm using the test card that they provide which is just a card number of four two four two four two etc so let's click on pay and let's see what happens so i click on pay the payment's successful my cart has been cleared as you can see and i i've been redirected to the home page if i come back into my stripe dashboard let's go home and you're going to see if i scroll down i now have 70 if i look at payments so this payment of 10 pounds or dollars was successful and you can see all of the information about that payment here and that brings us to the end of this video tutorial i want to thank you guys for watching but before we sign off i just want to encourage you guys to check out my official youtube channel that's youtube.com forward slash simple tut not only to find my other videos but to find the official youtube playlist for this series this is just a great place for you to find previous and future videos of this series and i'll be posting a direct link to this in the description of this video of course i also want to remind you that at the end of each of these tutorials i am committing and pushing i am committing my code and creating prs so if at any point you want to compare your code with mine or maybe just clone the entire project then you can absolutely feel free to do that and again i'll be posting a link to it in the description of this video why not check out my website at simpletot.com but most importantly please do like comment and subscribe and don't forget to turn on those notifications
Info
Channel: SimpleTut
Views: 5,525
Rating: undefined out of 5
Keywords: ecommerce, react, react redux, GraphQL, React Context API, Node, Node JS, redux, online store, stripe, stripe api, shopping card, paypal, firebase, react router, react router dom, routes, routing, Google Sign-In, Google Auth, Google Sign In Authentication, react hooks, useEffect, useSelector, useDispatch, redux hooks, useState, React Stripe.js, Stripe Elements, Stripe Payments API, Stripe, Stripe.js
Id: UFcUJ9BsZ98
Channel Id: undefined
Length: 72min 14sec (4334 seconds)
Published: Sun Nov 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.