WEBVTT

00:00.020 --> 00:06.590
Okay, so our next task is to create the payment intent when a user visits the checkout and every time

00:06.590 --> 00:11.630
they visit the checkout, we want to update the payment intent because they could come to the checkout,

00:11.630 --> 00:13.880
they could decide they want to continue shopping.

00:13.880 --> 00:18.350
And when we've loaded the checkout initially we've gone ahead and created that payment intent.

00:18.350 --> 00:22.940
But if they do update their basket, they'll have to come back to the checkout page if they do want

00:22.940 --> 00:25.490
to pay for what they've added or removed from their basket.

00:25.490 --> 00:31.760
And then we would need to update that payment intent again, so that the payment amount inside our intent

00:31.790 --> 00:36.560
to pay matches what their basket currently is.

00:36.830 --> 00:44.480
So every time they come to the checkout, we need them to effectively contact our API or make that request

00:44.510 --> 00:49.670
to our API, which in turn is going to update stripe and update that payment intent.

00:49.670 --> 00:54.560
So let's go back to VS code, and let's just clean things up at the top for the time being.

00:54.560 --> 01:00.170
And we'll go into our checkout folder inside features.

01:00.170 --> 01:07.900
and we will create a checkout API component or checkout API BTS.

01:08.170 --> 01:12.430
And inside here we'll create this just like we have the others.

01:12.430 --> 01:18.640
We'll specify export const checkout API equals create API.

01:18.760 --> 01:28.330
And once again your friendly reminder to get the one from React or Redux toolkit query react I should

01:28.330 --> 01:28.990
say.

01:29.080 --> 01:36.700
And then we'll specify the reducer path and call it checkout API.

01:37.030 --> 01:43.870
We'll use our base query and say base query with error handling and we'll specify the endpoints.

01:43.900 --> 01:49.600
Add a colon, add the word builder and the arrow open parentheses.

01:49.630 --> 01:50.890
Open curly brackets.

01:50.890 --> 01:53.830
And then we can specify our queries.

01:53.830 --> 01:59.570
So we're going to have a create payment intent Query.

01:59.570 --> 02:01.100
So we'll use builder.

02:01.100 --> 02:03.770
And this is going to be a mutation.

02:03.770 --> 02:07.130
And we're going to get our basket back from our API.

02:07.130 --> 02:10.250
And we don't need to provide this with any arguments.

02:10.250 --> 02:11.600
So that will be void.

02:11.630 --> 02:14.360
Then we open parentheses and curly brackets.

02:14.360 --> 02:17.060
And then we can define the query.

02:17.060 --> 02:19.460
So the query doesn't take any arguments.

02:19.460 --> 02:19.910
For this.

02:19.910 --> 02:23.390
We'll just use a function with no arguments.

02:23.870 --> 02:28.520
And inside here we will return in curly brackets.

02:28.520 --> 02:35.720
The URL is going to be payments and the method is going to be post.

02:35.900 --> 02:39.290
And we need to update our basket.

02:39.290 --> 02:43.490
And how do we do that using Redux Toolkit.

02:43.490 --> 02:47.120
Because we do have a basket API.

02:47.210 --> 02:54.530
And inside here our basket effectively is contained in the fetch basket query because it's cached.

02:54.530 --> 02:56.060
And that's what we need to update here.

02:56.060 --> 03:02.310
We need to update the cache if our API comes back with an updated basket with the payment intent ID

03:02.520 --> 03:04.350
and the client secret.

03:04.740 --> 03:07.980
So we effectively need to update this query.

03:08.010 --> 03:12.180
So let's go back to our checkout API and take a look at how we can do that.

03:12.180 --> 03:14.130
And once again we've used this a few times.

03:14.130 --> 03:18.750
We're going to use the on query started I'm in completely the wrong place there.

03:18.750 --> 03:20.460
I need to do this underneath the query.

03:20.460 --> 03:22.650
So we're going to use the on query started.

03:22.650 --> 03:27.060
And it's going to be an async method and doesn't take any arguments.

03:27.060 --> 03:29.580
So we'll just use an underscore for the first parameter.

03:29.580 --> 03:37.170
And then we need access to the dispatch and the query fulfill inside here.

03:37.170 --> 03:40.890
And then we can add the arrow and open curly brackets.

03:40.890 --> 03:44.070
And we'll do this inside a try catch block.

03:44.070 --> 03:52.530
And if we get an error we'll just console dot log the error and say payment intent creation failed.

03:52.740 --> 03:55.050
And add a colon.

03:55.050 --> 04:03.950
And we'll just append on the error to the console log there and inside the try block we'll specify const

04:04.220 --> 04:05.360
in curly brackets.

04:05.360 --> 04:10.340
Data equals await and query fulfilled.

04:10.370 --> 04:18.650
This should give us back our baskets inside this parameter because that's what our API is returning.

04:18.650 --> 04:21.140
And then we can use dispatch.

04:21.170 --> 04:22.430
Open parentheses.

04:22.430 --> 04:25.250
And I'll move this down to a second line.

04:25.250 --> 04:31.010
And we'll need to use our baskets API and the util from that.

04:31.520 --> 04:34.880
And then we can use the update query data method.

04:35.540 --> 04:38.660
Inside here we can use the fetch baskets.

04:38.870 --> 04:41.120
The second parameter is the arguments.

04:41.120 --> 04:42.890
That's going to be undefined.

04:43.670 --> 04:48.320
And the third argument is going to be our draft basket.

04:48.320 --> 04:51.260
So I'll use draft as the argument name.

04:51.260 --> 04:58.440
Add the arrow open curly brackets and we'll use draft dot client secrets.

04:58.620 --> 05:01.620
Equals data dot client secret.

05:01.620 --> 05:07.710
And do we need the payment intent on our client side?

05:08.550 --> 05:13.080
I'm going to say no because we will never use the payment intent ID on the client side.

05:13.080 --> 05:17.340
So I'm just going to ignore the payment intent ID that I added.

05:17.340 --> 05:24.570
I could clean up the basket type, but I'll just ignore it for the time being as it's not going to do

05:24.570 --> 05:25.050
any harm.

05:25.050 --> 05:30.840
But the only thing we really need inside our client side basket is the client secrets.

05:30.840 --> 05:35.400
We've got the payment intents ID on the basket that's stored in our database.

05:35.400 --> 05:41.700
We do need it there, because that's what we're going to use to update a payment intent.

05:41.700 --> 05:46.110
But as far as our client goes, then all it needs is the client secret here.

05:46.530 --> 05:48.840
So that will suffice for our query.

05:48.840 --> 05:53.700
And then we can go to our stores as we need to update this as well.

05:53.700 --> 06:03.530
And we'll add in our checkout Out API reducer path and say check out API reducer inside here, just

06:03.530 --> 06:04.610
as we've done before.

06:04.610 --> 06:07.490
And we'll also add the middleware as well.

06:08.270 --> 06:16.100
And like so and I need to go back to the checkout API because we do need to export the hook from here

06:16.100 --> 06:17.240
as well.

06:17.240 --> 06:22.910
So we'll use exports const and inside curly brackets.

06:22.910 --> 06:27.530
I'm just going to or add the curly brackets then use the checkout API.

06:27.560 --> 06:29.690
So I get the auto completion help.

06:29.690 --> 06:35.540
And we need to use the use create payment intent mutation from this.

06:35.540 --> 06:40.730
So then we can go back to our checkout page and make use of what we've done here.

06:40.760 --> 06:49.820
And when the checkout page loads then we're going to need to call our use create payment Intent mutation.

06:49.820 --> 06:53.120
So we're going to need to do this inside a use effect.

06:54.200 --> 06:55.730
And we'll use const.

06:55.740 --> 06:57.450
and will bring in the function first.

06:57.450 --> 07:00.630
And I'll just call it create payment intents.

07:02.100 --> 07:08.940
And I'll also bring in the is loading here from this hook as well.

07:08.940 --> 07:13.050
And say equals use create payment intent mutation.

07:14.460 --> 07:21.990
And we'll use a use effect inside here we'll add the callback function and we'll add its dependencies.

07:21.990 --> 07:29.640
Now for this one I'm going to take extra extra care, especially whilst we're in development mode now.

07:29.640 --> 07:36.300
We haven't been affected by it so far because of our usage of RTK query.

07:37.230 --> 07:44.010
But whilst in development mode, whilst in strict mode, then a use effect would typically be executed

07:44.040 --> 07:45.000
twice.

07:45.240 --> 07:51.420
Now I do not want this function to be executed twice just because I'm in development mode.

07:51.420 --> 07:57.110
I would like to prevent that kind of behaviour and one way that we can prevent that kind of behavior

07:57.110 --> 07:59.990
is to add an extra hook inside here.

07:59.990 --> 08:03.920
And I'm going to say const created equals use ref.

08:05.420 --> 08:09.770
And I'm going to specify false as its initial value.

08:09.890 --> 08:12.080
So this use ref.

08:12.110 --> 08:18.770
It's effectively a mutable object whose current property is initialized to the passed argument, which

08:18.800 --> 08:25.010
is going to be false, and the returned object will persist for the full lifetime of the component.

08:25.190 --> 08:28.790
So it's unaffected by our checkout page Rerendering.

08:28.790 --> 08:32.750
For whatever reason, the value of this persists.

08:32.810 --> 08:39.830
So we can use this to effectively check to see if this has been created.

08:39.830 --> 08:44.000
The payment intent has been created when this component has first loaded.

08:44.000 --> 08:52.640
So the way that this works is I'm going to check to see if not created dot current or not.

08:52.730 --> 08:54.750
And I meant to call that created.

08:54.750 --> 08:57.570
So I'll specify created currents.

08:58.200 --> 09:01.530
Then we will create the payment intents.

09:01.590 --> 09:09.720
And after that has been created we'll update created currents to be true.

09:09.990 --> 09:16.650
So the next time this use effect is called then created is going to be set to true, which means this

09:16.650 --> 09:21.780
method will not be executed and we will not create an additional payment intent.

09:22.230 --> 09:26.100
In testing I was able to onloading the checkout.

09:26.100 --> 09:32.700
I would actually consequence of this, or the consequence of this would be that an additional payment

09:32.700 --> 09:37.890
intent was created in stripe, and then we would have two payment intents for the same baskets, which

09:37.890 --> 09:38.910
is not ideal.

09:38.910 --> 09:43.110
So this avoids that kind of scenario in production.

09:43.110 --> 09:47.880
This is not relevant because it's only going to be executed once anyway.

09:47.880 --> 09:56.870
This is more of a development trick that we need if we want to avoid An external service, being updated

09:56.900 --> 10:02.360
twice when we don't want it to, and our dependency for this one we've got the warning here tells us

10:02.360 --> 10:12.440
we need to add the create payment intent as a dependency, and I'll use the Isloading here as an additional

10:12.440 --> 10:15.920
check before we load our checkout stepper.

10:15.920 --> 10:23.210
So we'll also add another or condition and just check to see if we're loading in this case.

10:23.210 --> 10:27.980
So let's go back to our browser and see what kind of progress we've made.

10:27.980 --> 10:31.370
Well I can see that the checkout has now loaded.

10:31.400 --> 10:35.480
That means that our basket now has that client secret.

10:35.480 --> 10:42.500
And if we go and inspect and we'll ignore the console, we'll just go straight to our Redux DevTools

10:42.500 --> 10:43.820
in this case.

10:43.820 --> 10:47.090
And we take a look at the latest state.

10:48.110 --> 10:55.560
And we take a look at the basket API inside the queries inside the fetch basket and take a look at the

10:55.560 --> 10:56.340
data.

10:56.370 --> 11:03.060
Then we can see that we have the client secrets available and that is what we would expect, what we

11:03.090 --> 11:10.410
would also expect depending on the items we have in here, I've got a product ID of ten which is priced

11:10.410 --> 11:14.340
at 1800, and I have a quantity of one.

11:14.340 --> 11:20.340
What we would also expect is that this transaction to be reflected inside stripe as well.

11:20.340 --> 11:27.690
So if I just refresh this page, then what we should have is another payment intent.

11:27.690 --> 11:28.740
And that's correct.

11:28.740 --> 11:31.170
It's $18 for the item.

11:31.200 --> 11:37.080
And because it's below $100 then we've got the plus five delivery charge there as well.

11:37.080 --> 11:38.370
So excellent.

11:38.370 --> 11:39.420
That's what we'd expect.

11:39.420 --> 11:44.790
And that should also of course reflect in our order summary on the right hand side.

11:44.850 --> 11:46.200
So great.

11:46.230 --> 11:50.520
And our next step is going to be the address step.

11:50.520 --> 11:53.070
And we'll take a look at what we need to do for that next.
