Okay, now that we've got our confirmation token, we can now look at confirming the payment.
So back to VSCode and we'll create a method inside our checkout stepper to confirm the payment.
So we're going to add another helper method inside here.
And we'll actually confirm the payment or use that method inside this handle next.
So let's add another method inside here and we'll call it const confirm payments.
And we'll make it an async method that takes no parameters.
And inside here we'll add a try catch block.
And we'll also add some local states to track whether or not we're submitting this payment to stripe
as well.
So let's just add a bit more local state inside here.
And I'll just say const submitting and set submitting equals use states.
And I'll just set it to false initially.
And then we'll use this inside our new method.
So before the try block we'll just use the set submitting method and set this to be true inside the
try block.
Then we first of all need to be a bit defensive here because we need to make sure we have both the confirmation
token and the client secret.
Before we do this, we should have both because where we're going to call this is going to be on the
button inside the review component.
So we should have this.
But for Typescript's benefit we'll do our defensive work here.
So I'll say if not confirmation token or not basket.
And we need access to our basket inside here.
And we do not have that yet.
So we'll also bring this in as well.
And we've got our convenient hook to use now anyway.
So I'm going to use the use basket hook inside here and specify baskets.
And then inside our confirm payment we'll check for not basket dot clientsecret.
And if that is the case, we do not have either of those.
Then we're just going to throw a new error and say unable to process payments because we cannot do anything
without those elements.
But we should have them at this point anyway.
And I'll just move this below the if statement so that I don't go off the edge of the screen.
So below the if statement, then let's add a const for a payment result.
And we'll set this equal to Await and stripe.
And we can use the confirm payment method.
And this takes some options.
So I'll open parentheses and then curly brackets.
And we'll need the client secrets.
And we'll set that to the baskets dot client secret.
For this method we'll use redirect and we'll say if required because we'll handle redirection ourselves.
And then the confirmed programs will open curly brackets.
And we need to give this the confirmation token, which will set to the confirmation token.id.
And below this payment result, we'll need to check it for any errors.
So we'll add a check.
We'll add an if statement and say if payment result dot payment intent which we get back from stripe.
We can check its status and check to see if it is succeeded.
And if it is succeeded.
Then we'll redirect them to a checkout success component and we'll need to bring in navigate from React
Router here as well.
So something else to add.
Inside this already busy component we'll use const navigate and set this equal.
To use navigate we get from React Router and back down to our method.
So if we are successful, then payment has been received and we'll use navigate and redirect them to
forward slash checkout.
Forward slash success which we don't have yet, but we will create and we'll add an else if and we'll
check our payment result for an error.
And if we do have a payment result error then we're going to throw a new error.
And we'll pass in the payment result dot error dot message.
And we'll also just add a final else condition just in case we're not successful.
And for whatever reason we don't have a payment result error.
We'll just throw a new error inside here because we don't really know what's gone wrong.
But we shouldn't see this.
And we'll just say something went wrong and then we'll deal with the error which we're throwing inside
here.
So of course, if we throw an error inside our if statements here, then it's going to be caught in
this block of code.
And inside the catch block, we'll just use a toast and say toast dot error, and we'll pass in the
error dot message.
And we can't use it like that.
Of course we need to check because the error at this stage is going to be of type unknown.
We'll need to check just to make sure it's an instance of an error.
So we'll check to see if the error is an instance of error.
And this will give us access to the error message property.
I'll just cut the toast and put it inside here.
And then below the if statement.
We'll just put them back on to the previous step.
Because if they do get an error we've confirming the payment.
That means there's been a problem with the card.
So we'll set the active step and we'll set it to step and add the arrow and say step minus one just
to move them back.
And I've got a bunch of errors in here.
Let's see what these are about.
Oh, it's because I haven't used the confirm payment yet, but we'll create a checkout success page,
just the basic boilerplate we need and add a route for it.
So inside the checkout folder let's create a new file and call it Checkout Success dot TSX.
And we'll add the boilerplate inside here.
So RFC and all we'll do for the time being is we'll use typography.
We'll give it a variant of H5.
And we'll just say checkout or payment successful for the time being.
And we'll also need to create a route for this so that we do actually get redirected.
So we'll go to our routes.
And where I've got the checkout I'll just copy this one down because if we're redirecting them to the
success page then we expect them to be authenticated of course.
So we'll put it inside where are require auth routes are and we'll use the checkout success as the component
will load.
And then we can go back to our checkout stepper.
And we can make use of our new confirmed payment method.
So inside the handle next we'll check to see if the active step is equal to two.
Then if it is we'll just use await and confirm payments.
And I've still got a warning inside here.
Let's see what that is about.
So it's up here and submitting.
Of course I haven't turned off the submitting flag.
So let's go back down to the confirm payment.
And we've got our try block.
We've got our catch block.
And we'll add a finally block.
So regardless if the request is successful or not we turn off the loading spinner.
And I'll say set submitting is false.
And we'll go down to our button inside here, and we'll just add another condition on the handle.
Next button and we'll add another or and we'll check for submitting.
So we're only disabling the.
Buttons.
And in fact because this is not going to be going through or it's not using RTK query for this because
it's just our client communicating directly with stripe, then this would be a good argument to use
a loading button instead, but we'll need to do a bit of work to enable a loading button on this.
So I'm not going to include that functionality in this.
We'll just use disabled for the time being to see if that is submitting or not.
So that's part one.
We've still got a bit of work to do to add this functionality, as once we've made the payment, what
we'd also like to do is clear the basket.
So we'll take a look at finishing up this process in the next lesson, and I will take a look in the
next lesson at adding a loading button for this as well.