WEBVTT

00:00.050 --> 00:05.990
Before we actually go ahead and create the reservation in our database, I want to go ahead and actually

00:05.990 --> 00:11.970
build the user for this using the newly created charge, DTO and our payments service.

00:11.990 --> 00:17.180
So let's go ahead and change this out to be a new const called Reservation.

00:17.330 --> 00:23.150
And this will be equal to await this dot reservations repository dot create.

00:23.180 --> 00:28.370
We'll go ahead and call our payment service and to use this, make sure we actually label this as a

00:28.370 --> 00:35.000
private read only variable and then we'll go ahead and call await this dot payment service dot send

00:35.030 --> 00:38.780
where we know we of course need to specify the pattern here.

00:38.780 --> 00:43.900
And we know that in the payments controller we call this create charge.

00:43.910 --> 00:46.940
So let's go ahead and send a create charge.

00:46.940 --> 00:54.500
And then the data itself here is going to be the create reservation DTO dot charge object here.

00:54.500 --> 00:57.680
And recall that this is actually returning an observable here.

00:57.680 --> 01:05.310
So we won't await this actually, but we're going to go ahead and actually subscribe to this observable

01:05.310 --> 01:10.350
here will be executed after the response gets sent back successfully.

01:10.350 --> 01:16.200
And so after we actually send the charge off and the subscribe block, this is where we want to actually

01:16.200 --> 01:19.230
go ahead and create the reservation.

01:19.230 --> 01:24.450
So we'll make this an async function here where we can go ahead and create the reservation.

01:24.450 --> 01:28.590
And I'll go ahead and return it directly in this async Block.

01:28.590 --> 01:34.260
And additionally, let's go ahead and actually get the response back in the subscribe block here so

01:34.260 --> 01:38.280
that we can actually go ahead and log it out.

01:38.550 --> 01:45.330
So before we return the reservation, we can actually log out the response here just for some debugging

01:45.330 --> 01:46.020
purposes.

01:46.020 --> 01:51.990
So if I go ahead and send a request off to our reservations route here and make sure we are, of course,

01:51.990 --> 01:55.110
authenticated first, I can see I get a 201.

01:55.110 --> 02:01.560
Created back and now in the logs, we can see we get the response back from the payment service with

02:01.560 --> 02:04.470
the payment intent, which is awesome to see.

02:04.470 --> 02:12.270
And even further, if we go back to our Stripe dashboard, if you go to the payments website here,

02:12.270 --> 02:17.070
the payments tab, you can actually see our successful payment here.

02:17.070 --> 02:19.110
And this is very cool to see.

02:19.110 --> 02:25.290
You can see the amount we sent for $5 and the test payment method that we provided.

02:25.290 --> 02:30.240
So we can see that we're able to successfully communicate to our payments service and we'll see our

02:30.240 --> 02:31.770
payments reflected in Stripe.

02:31.770 --> 02:38.160
However, one thing we notice is that we don't actually get the reservation response back now, so let's

02:38.160 --> 02:39.180
go ahead and fix that.

02:39.180 --> 02:47.220
So by default, we can actually return the observable back to the root and Nestjs will subscribe to

02:47.220 --> 02:48.300
it on its own.

02:48.300 --> 02:50.940
So let's go ahead and subscribing here.

02:50.940 --> 02:59.340
We'll actually use the pipe operator, so we'll pipe here and then we're going to pass in the Rxjs map

02:59.370 --> 03:08.150
operator to actually transform form the response, because in this case we want to return reservations

03:08.150 --> 03:11.840
repository document that we go ahead and create here.

03:11.840 --> 03:14.570
We don't actually need the response here at all.

03:14.570 --> 03:21.860
And then also we need to return the observable from the create route directly so that can subscribe

03:21.860 --> 03:23.300
to it in our controller.

03:23.300 --> 03:31.130
And now you can see if we send a request off, we get the expected response here, which is the actual

03:31.130 --> 03:32.480
reservation document.

03:32.480 --> 03:38.630
So we now have the ability to create a new reservation and actually bill the user in our microservice

03:38.630 --> 03:40.420
architecture, which is great.

03:40.430 --> 03:46.130
Next, let's add a little bit of validation to our payments microservice so that we can actually validate

03:46.130 --> 03:47.790
the incoming create charge.

03:47.810 --> 03:53.150
DTO here, just like we do in a regular controller, we want to validate this payload.

03:53.150 --> 03:54.920
So let's see how we can do that next.

03:54.920 --> 04:01.520
Leslie One additional issue I've just noticed is that if we send an unauthorized request to our reservation

04:01.520 --> 04:05.640
service, we're actually throwing a 500 status code here.

04:05.640 --> 04:09.960
So you can see in the auth service there's an unauthorized exception.

04:09.960 --> 04:13.410
I haven't actually logged in with a JWT cookie yet.

04:13.650 --> 04:17.280
However, the reservation service isn't handling this gracefully.

04:17.280 --> 04:20.490
It's just failing with a global 500.

04:20.490 --> 04:26.040
And the reason for this is in our common auth guard and we send this request off.

04:26.070 --> 04:32.070
It's just erroring out and it's not able to actually parse the error from the auth service.

04:32.070 --> 04:39.180
So let's go ahead and just add a global catch error block to this observable and we're just going to

04:39.180 --> 04:46.320
return a new observable that returns false so that if an unauthorized response or any other error occurs

04:46.320 --> 04:49.920
in this observable chain, we'll simply return false.

04:49.920 --> 04:56.160
And now if we send off an unauthorized request, we get that expected 403 from the auth guard, which

04:56.160 --> 04:57.000
is a lot better.

04:57.030 --> 04:57.360
Okay.

04:57.360 --> 04:59.730
So to add validation to.

04:59.800 --> 05:06.250
Our microservice in our payments controller here so that we actually validate the decorators on the

05:06.250 --> 05:07.600
create charge DTO.

05:07.630 --> 05:08.730
It's very easy.

05:08.740 --> 05:15.730
We can just simply apply the use pipes decorator here and call new validation pipe here.

05:15.730 --> 05:21.630
And this will automatically validate all of our incoming metadata on this incoming payload.

05:21.640 --> 05:23.260
So let's go ahead and test this out.

05:23.260 --> 05:29.890
If we go into the reservation service and instead of passing the charge here, we just pass an empty

05:29.920 --> 05:30.880
object.

05:31.690 --> 05:35.920
We can go ahead and now try sending off another request here.

05:35.920 --> 05:40.060
So if we send this request off, of course we get a 500 internal server error.

05:40.060 --> 05:44.950
But now if we go ahead and look at the payment service, we can see we're actually getting a bad request

05:44.950 --> 05:49.860
exception from the validation pipe because we're not providing a valid payload.

05:49.870 --> 05:51.640
So let's go ahead and revert this.

05:51.640 --> 05:55.120
We'll go ahead and pass the credit card once again.

05:55.120 --> 06:01.210
And now if we send off the request, we get our reservation charge created successfully and everything's

06:01.210 --> 06:01.840
okay.

06:01.840 --> 06:05.950
But now we have some validation in place and we can follow this pattern.

06:05.950 --> 06:12.880
For any other microservice message pattern, we have to apply our existing validation decorators.

06:12.880 --> 06:13.180
Okay.

06:13.180 --> 06:18.490
And the last thing I want to do right now is our invoice ID, which is what's going to correlate the

06:18.490 --> 06:21.130
reservation back to the Stripe charge.

06:21.130 --> 06:25.090
Right now we're just hard coding this and actually taking it from the user.

06:25.090 --> 06:32.090
Instead, we want to actually get the ID of the invoice from Stripe and then persist it so firstly,

06:32.090 --> 06:38.390
let's go into our DTO for the Create reservation and I'm going to get rid of the user supplied invoice

06:38.390 --> 06:39.260
ID here.

06:39.260 --> 06:43.790
We're not going to allow them to supply an invoice ID and we'll also go ahead and get rid of the place

06:43.790 --> 06:46.340
ID here as we are not using it.

06:46.340 --> 06:50.270
And I'll go ahead and get rid of the unused imports here.

06:50.270 --> 06:55.730
We'll additionally go back to the reservation schema and get rid of the place ID here.

06:55.730 --> 07:01.400
We won't be using this, but we'll keep the invoice ID instead of having the user supply anymore.

07:01.400 --> 07:06.350
Now though, we actually are going to extract it from the stripe response.

07:06.350 --> 07:13.700
And so if we go ahead and firstly log the response out once more and send off another reservation request

07:13.700 --> 07:21.740
here, you can see in the log statement here for the payment intent, we get an ID for the payment intent,

07:21.770 --> 07:27.110
which is what we want to use to be able to get the information about the payment intent later on.

07:27.110 --> 07:34.730
So to extract this, all we'll have to do is go ahead and supply the invoice ID and pull it off of the

07:34.730 --> 07:37.850
response.id field.

07:37.880 --> 07:40.190
We'll get rid of the console log statement here.

07:40.190 --> 07:47.420
And now if we go ahead and send off another request here, you can see our invoice ID is the actual

07:47.420 --> 07:49.580
real ID for the stripe request.

07:49.580 --> 07:56.150
If we send off another one here, you can see we will get a new unique invoice ID, which is excellent.

07:56.180 --> 07:57.590
Okay, so quick update.

07:57.590 --> 08:03.020
It appears that some people in the course are having issues from the Stripe API.

08:03.020 --> 08:07.250
When sending our credit card details directly to the API.

08:07.280 --> 08:13.790
This seems to be a sporadic change that only some users are experiencing because of Stripe changing

08:13.790 --> 08:17.810
their API requirements and we can easily get around this error.

08:17.810 --> 08:19.670
If you are experiencing it.

08:19.700 --> 08:26.840
We can just use a default test card that stripe offers instead of using our own custom card details.

08:26.840 --> 08:33.920
So in order to specify that custom test card, we just need to get rid of our existing payment method

08:33.920 --> 08:36.050
and the payment method types.

08:36.080 --> 08:43.910
We're going to go ahead and add payment method now of PM card visa, which is just the token or the

08:43.910 --> 08:47.120
name of one of the test cards that Stripe has.

08:47.120 --> 08:54.020
We won't then actually be needing the payment method in this case, so we can remove this and also get

08:54.020 --> 08:57.080
rid of the card that we're destructuring from the create charge.

08:57.080 --> 09:04.220
DTO Now I'm still going to keep the existing card, DTO because I think it's a good example of how we

09:04.220 --> 09:08.000
can do nested validation in class validator.

09:08.000 --> 09:11.780
However, we don't actually need to use it now when we're creating the charge.

09:11.930 --> 09:17.750
So just to show this is still working, I'll go ahead and send off another reservation and I'll change

09:17.750 --> 09:21.920
my charge, amount to $17, send off a request.

09:21.920 --> 09:30.440
And now if we head back to our Stripe dashboard and refresh, we should still see a charge of $17 that

09:30.440 --> 09:31.370
succeeded.

09:31.370 --> 09:37.580
And if we click into it, we can see it's using this test visa payment method and we should have no

09:37.580 --> 09:41.210
more errors about sending credentials directly over the wire.
