‫So in this video let's integrate Stripe
‫into our backend by creating that API endpoint
‫which will create and send back a Stripe checkout session.
‫And so at this point, we're actually gonna start creating
‫our next resource.
‫And so that's the bookings.
‫And I will start here with the booking routes.
‫So booking
‫routes.js.
‫And we've done that so many times now.
‫So then I'm just gonna go ahead
‫copy all of this code
‫and put it here in the booking routes.
‫And then simply remove all of this.
‫And also this one.
‫We also don't need merge params
‫and we will have a booking controller instead of
‫a review controller.
‫So booking controller, let's actually create that.
‫So
‫.js
‫that looks correct
‫and let's also integrate this right into app.js.
‫And so let's put that right here
‫after the review router.
‫So here that's just again bookings
‫and then of course down here integrate that
‫into our API.
‫So bookings and here
‫bookings router.
‫And I think that should only be booking.
‫So let's fix that up here as well.
‫And indeed we call it booking router.
‫And the same here, it's not bookings
‫but booking routes.
‫So give it a save.
‫Close this one and this one
‫and this one here as well.
‫And so now let's actually go ahead and create
‫our first route here.
‫So let's router.get and the route that it will create here
‫will once again not follow the rest principle
‫because this one is not really gonna be about
‫creating or getting or updating any booking.
‫Instead this route will only be for the client
‫to get a checkout session.
‫And so let's actually call this one
‫checkout session.
‫Then we need to protect this route
‫so that only authenticated users can actually get
‫a checkout session.
‫So that makes sense, right?
‫And then add booking controller.
‫We're gonna create a route handler called get
‫checkout session.
‫All right.
‫So let's copy this one and create it here
‫at exports.getCheckoutSession
‫then request responds next.
‫And now let's start working.
‫Now actually there's one more thing we need to do here
‫in the routes which is to specify a URL parameter.
‫And so that's going to be the tour ID.
‫Okay, so basically we want the client to send along
‫the ID of the tour that is currently begin booked.
‫And that is so that we can fill up the checkout session
‫with all the data that is necessary,
‫such as the tour name and the tour price and all that stuff.
‫All right, so we now have access to the tour ID
‫in this handler function
‫and so the first thing that we're actually gonna do
‫is to find that tour in our database.
‫All right, so for that we need of course the tour model.
‫So let's come here to the tour controller
‫and get that from there.
‫Also we're gonna need this catchAsync
‫and so really all of this.
‫So I'm copying all of it
‫and even if I don't need it right away
‫I will probably need it a bit later anyway.
‫All right.
‫So let's layout our steps here again.
‫So get the currently booked tour.
‫Then as a second step, we create the checkout session
‫and then finally send it to the client.
‫All right, so the first step is really easy.
‫So we're gonna wait.
‫So tour.findbyId
‫which is req.params.tourId.
‫Right, so that was the name we gave it
‫in the URL parameter.
‫And of course, this is now an async function
‫with a catchAsync besides that or around that, actually.
‫Great, next up, let's create that session here.
‫And for that we actually need to install
‫this drive NPM package.
‫So let's do that here.
‫NPM install Stripe.
‫And in the meantime we're gonna go to our Stripe dashboard
‫and get our secret key from here.
‫So just hit this button here
‫and then go ahead and copy it.
‫And you see that here in the keys
‫it actually says test.
‫And so again, these ones here are just for testing
‫and then once you have your Stripe account active,
‫you can then get your live API keys.
‫Okay, now as with any other keys
‫we will put them here in our config file.
‫So Stripe
‫secret key equal to this.
‫And this is not correct here.
‫All right, so copy this one.
‫Back to our booking controller.
‫Let's now actually require this drive package
‫with has successfully installed here.
‫And just with all the other packages before
‫please make sure that you're actually on
‫the same version as I am.
‫And you see that I'm here at the brand new 7.0.0.
‫So this is really brand new.
‫And actually that's because a lot of stuff just changed
‫with Stripe a couple of days ago.
‫So I had to change a couple of these implementation.
‫Anyway, const stripe equal require
‫and then stripe.
‫Now this here will then expose a function basically.
‫And usually what we do then right away
‫is to pass our secret key right into that.
‫And so that will then give us a Stripe object
‫that we can work with.
‫So that now at process.env.STRIPE_SECRET_KEY.
‫Okay, and so now let's use that.
‫So we say Stripe.checkout.session.create.
‫And then the usual object of options.
‫All right, now there are a ton of options
‫that we can set here.
‫But only three of them are required.
‫So the first one is the payment method types.
‫So payment method types.
‫So that is an array where we can specify multiple types
‫and card is for credit card.
‫And right now that's actually all the payment options
‫that we can use for Stripe checkout.
‫But I read that in the future they will add a lot more.
‫So you can get informed by that.
‫Then we need to specify the success URL.
‫And so that is basically the URL that will get called
‫as soon as a credit card has been successfully charged.
‫So as soon as the purchase was successful
‫the user will be redirected to this URL.
‫And for now, let's simply specify that as our homepage.
‫All right and we're gonna do that just as before
‫with req.protocol://
‫and then request.get the host.
‫So basically just our home URL.
‫Then we also need to specify the cancel URL.
‫So just like this.
‫And this one is gonna be similar.
‫And so basically it's the page where the user goes
‫if they choose to cancel the current payment.
‫And actually let's make them go to the tour page
‫where they were previously.
‫And so that is basically tour/tour.slug.
‫Next up, we can also specify the customer email.
‫And so that is very handy because of course
‫we already have access to the customer's email.
‫And so with this we can save the user one step
‫and make the checkout experience a lot smoother.
‫All right so remember that this is a protected route.
‫And so as always the user is already at the request.
‫And so we can say request.user.email.
‫Next up, we can then also specify a custom field
‫which is called client reference ID.
‫And that sounds a bit weird but actually it's going to be
‫really important for us.
‫So this field is gonna allow us to pass in some data
‫about the session that we are currently creating.
‫And that's important because later
‫once the purchase was successful,
‫we will then get access to the session object again.
‫And by then, we want to create a new booking
‫in our database.
‫So remember the diagram that I showed you
‫in the last lecture.
‫Basically what I'm talking about here
‫is the last step in that diagram.
‫And also remember how that is only going to work
‫with deployed websites.
‫But still, let's already prepare for that here.
‫Okay, so to create a new booking in our database
‫we will need the user's ID, the tour ID, and the price.
‫Remember that?
‫And in this session we already have access
‫to the user's email
‫and from that we can then recreate the user's ID
‫because email here is unique.
‫We will also specify the tour's price here in a second
‫and so all that's missing is then the tour ID.
‫And so that's what we're gonna specify here
‫on this custom field basically.
‫So that's called client reference ID.
‫And all of what I just explained before
‫actually is gonna make a lot more sense
‫once we actually implement that last step
‫of creating a booking in the database, right?
‫Anyway, that tour ID is at request.params.tourId.
‫All right, and now finally, we're gonna specify
‫some details about the product itself.
‫So our tour in this case.
‫And so that's called line items which accepts
‫an array of objects.
‫So basically one per item
‫and so in our case that's only gonna be one.
‫So we're to specify the name of the product
‫and so that's at tour.name
‫and as always we also add the tour to that name.
‫Then we can also specify a description.
‫And all these field names here they really come from Stripe.
‫So we cannot make up our own fields.
‫So if you try to do that, you will really get some error.
‫All right, so in the description
‫I will put the tour summary,
‫so that nice short phrase that will describe each tour.
‫Then we can also specify an array of images.
‫Now these images here they need to be live images.
‫So basically images that are hosted on the internet
‫because Stripe will actually upload this image
‫to their own server.
‫And so this is another of the things
‫that we can only really do once the website is deployed.
‫But for now, as a placeholder, I will basically use the ones
‫from our hosted example website on natours.dev.
‫So let's go to that website.
‫So that's this one at natours.dev.
‫And the image that I'm gonna choose is the cover image.
‫So let's inspect that image.
‫So this one here and copy link address here.
‫All right.
‫So this is an array because we can specify multiple images
‫but we really only want one of them.
‫And indeed we have natours.dev/images/tours
‫and then the name of the image.
‫And this one I will simply replace with tour.image cover.
‫And that's gonna work because the names of the images
‫on natours.dev are exactly the same as we have here
‫in our project.
‫So tour.imageCover.
‫So this is one more thing that we actually need to change
‫once we put our website into production.
‫And I'm keeping actually a list of that stuff
‫so that we don't forget anything.
‫Anyway, next up is the amount.
‫So basically the price of the product
‫that is being purchased.
‫So that is tour.price
‫and now we need to multiply that by 100.
‫Because this amount is expected to be in cents.
‫And so one dollar or one Euro
‫or really most of the currencies have 100 cents.
‫So one dollar equals 100 cents.
‫And so to convert it to cents, just multiply it by 100.
‫Then we also need to specify the currency.
‫And so that's in this case USD.
‫But it could also be like, for Euro it's EUR
‫and for other currencies, you should probably take a look
‫at the documentation.
‫So of course I cannot cover all the currencies
‫that there are, right?
‫Anyway, finally we also specify the quantity.
‫And so that's just one tour in this case.
‫So that's actually it.
‫And so basically this part here is the information
‫about the session itself.
‫And then here is the information about the product
‫that the user is about to purchase.
‫All right, now let's actually store the session.
‫So const session
‫and now we to await this.
‫So this create here basically returns a premise
‫because setting all these options here
‫will basically do an API call to Stripe
‫and so then of course that's an asynchronous function
‫that we should await here.
‫Okay, but anyway this is now our session
‫and so the last step is of course to send it
‫back to the client.
‫So as always,
‫the status is success.
‫And then let's simply send the session like this.
‫All right, so that should actually be it.
‫Our router is already configured
‫and so I think we could actually now try this out
‫in postman.
‫All right, now later of course we will not allow anyone
‫to do this using postman
‫because that doesn't make much sense.
‫But now since we're only testing this
‫it actually makes a lot of sense.
‫All right so let's head over to postman
‫and create a brand new request.
‫So that's gonna be at bookings/
‫uh, I'm not really sure.
‫Yeah, so checkout session and then /tourId.
‫All right, so let's get our tours here.
‫To get the ID from there basically.
‫So let's do the Sea Explorer.
‫Okay, and that should actually be enough.
‫Oh wait, we are of course not logged in.
‫So log in here.
‫Now we are in admin,
‫but let's use someone else here.
‫And I think we used Leo before
‫so let's now use that user.
‫Now we have an incorrect password.
‫All right so let's see what else we have.
‫So what other users we could use.
‫And actually let's use Monica here.
‫Why not?
‫So hopefully her password is correct.
‫Well, let's actually try to replace this here
‫with test1234.
‫Well, maybe we did change the passwords
‫of all of these users in some other lectures before.
‫So let's use John here.
‫So I know that we never used John
‫so now it has to work.
‫Oh, I actually see the error that I just did before.
‫So here it's not natours, it must be example.com.
‫So let's try that again with Monica here.
‫Or really just with John.
‫This is more difficult than I expected it to be.
‫But now finally we are logged in.
‫All right, and so with that,
‫let's try to get our checkout session.
‫We are missing the authorization from here.
‫One more time, and now we get some real error here.
‫So something that is actually really coming from the code
‫that we just wrote.
‫All right.
‫So let's check that out.
‫And the problem is that here it's actually sessions.
‫So stripe.checkout.sessions.
‫One more time.
‫This time it's taking a lot longer which is a good sign.
‫And we have another error.
‫So line 15 cannot read slug of node.
‫All right, well that sure is weird
‫because there should be a slug on this tour.
‫So uh
‫yeah you see that here it actually is.
‫So maybe something went wrong with actually reading
‫this tour.
‫Which I cannot really understand why that would be.
‫But let's just try to log the tour to the console.
‫All right, and actually we get null.
‫Which probably means that there's a tour ID
‫not correctly defined.
‫Oh, here is the problem.
‫So I have it, ID all uppercase,
‫but then here in the controller I have the D in lowercase.
‫So like this.
‫And so that's the small type of bugs that happen
‫all the time obviously.
‫So let's see what's the next one.
‫Oh and actually this time we got it right.
‫So you see that is the session that we just created.
‫And it edits some more other stuff here
‫but that doesn't really matter for us right now.
‫What's really interesting to see though
‫is that we now can actually already kind of see
‫this payment, or at least this payment request,
‫let's say in our drive dashboards.
‫So if we go there and go to payments
‫and then to all, you will see that this last one here
‫actually just happened right now.
‫So if we click that, then you will see some data about it.
‫So you see for example that it is actually about
‫the Sea Explorer Tour.
‫You also have the price, you also have the image.
‫Probably also some data about the user.
‫And actually no, not really.
‫But what matters here is that it says incomplete.
‫And that's because we only created the checkout session
‫on the server.
‫And so we're missing the second step
‫where we then actually charge the credit card
‫on the client side.
‫So since we're missing that,
‫let's actually do it right in the next video.