Before we actually go ahead and create the reservation in our database, I want to go ahead and actually
build the user for this using the newly created charge, DTO and our payments service.
So let's go ahead and change this out to be a new const called Reservation.
And this will be equal to await this dot reservations repository dot create.
We'll go ahead and call our payment service and to use this, make sure we actually label this as a
private read only variable and then we'll go ahead and call await this dot payment service dot send
where we know we of course need to specify the pattern here.
And we know that in the payments controller we call this create charge.
So let's go ahead and send a create charge.
And then the data itself here is going to be the create reservation DTO dot charge object here.
And recall that this is actually returning an observable here.
So we won't await this actually, but we're going to go ahead and actually subscribe to this observable
here will be executed after the response gets sent back successfully.
And so after we actually send the charge off and the subscribe block, this is where we want to actually
go ahead and create the reservation.
So we'll make this an async function here where we can go ahead and create the reservation.
And I'll go ahead and return it directly in this async Block.
And additionally, let's go ahead and actually get the response back in the subscribe block here so
that we can actually go ahead and log it out.
So before we return the reservation, we can actually log out the response here just for some debugging
purposes.
So if I go ahead and send a request off to our reservations route here and make sure we are, of course,
authenticated first, I can see I get a 201.
Created back and now in the logs, we can see we get the response back from the payment service with
the payment intent, which is awesome to see.
And even further, if we go back to our Stripe dashboard, if you go to the payments website here,
the payments tab, you can actually see our successful payment here.
And this is very cool to see.
You can see the amount we sent for $5 and the test payment method that we provided.
So we can see that we're able to successfully communicate to our payments service and we'll see our
payments reflected in Stripe.
However, one thing we notice is that we don't actually get the reservation response back now, so let's
go ahead and fix that.
So by default, we can actually return the observable back to the root and Nestjs will subscribe to
it on its own.
So let's go ahead and subscribing here.
We'll actually use the pipe operator, so we'll pipe here and then we're going to pass in the Rxjs map
operator to actually transform form the response, because in this case we want to return reservations
repository document that we go ahead and create here.
We don't actually need the response here at all.
And then also we need to return the observable from the create route directly so that can subscribe
to it in our controller.
And now you can see if we send a request off, we get the expected response here, which is the actual
reservation document.
So we now have the ability to create a new reservation and actually bill the user in our microservice
architecture, which is great.
Next, let's add a little bit of validation to our payments microservice so that we can actually validate
the incoming create charge.
DTO here, just like we do in a regular controller, we want to validate this payload.
So let's see how we can do that next.
Leslie One additional issue I've just noticed is that if we send an unauthorized request to our reservation
service, we're actually throwing a 500 status code here.
So you can see in the auth service there's an unauthorized exception.
I haven't actually logged in with a JWT cookie yet.
However, the reservation service isn't handling this gracefully.
It's just failing with a global 500.
And the reason for this is in our common auth guard and we send this request off.
It's just erroring out and it's not able to actually parse the error from the auth service.
So let's go ahead and just add a global catch error block to this observable and we're just going to
return a new observable that returns false so that if an unauthorized response or any other error occurs
in this observable chain, we'll simply return false.
And now if we send off an unauthorized request, we get that expected 403 from the auth guard, which
is a lot better.
Okay.
So to add validation to.
Our microservice in our payments controller here so that we actually validate the decorators on the
create charge DTO.
It's very easy.
We can just simply apply the use pipes decorator here and call new validation pipe here.
And this will automatically validate all of our incoming metadata on this incoming payload.
So let's go ahead and test this out.
If we go into the reservation service and instead of passing the charge here, we just pass an empty
object.
We can go ahead and now try sending off another request here.
So if we send this request off, of course we get a 500 internal server error.
But now if we go ahead and look at the payment service, we can see we're actually getting a bad request
exception from the validation pipe because we're not providing a valid payload.
So let's go ahead and revert this.
We'll go ahead and pass the credit card once again.
And now if we send off the request, we get our reservation charge created successfully and everything's
okay.
But now we have some validation in place and we can follow this pattern.
For any other microservice message pattern, we have to apply our existing validation decorators.
Okay.
And the last thing I want to do right now is our invoice ID, which is what's going to correlate the
reservation back to the Stripe charge.
Right now we're just hard coding this and actually taking it from the user.
Instead, we want to actually get the ID of the invoice from Stripe and then persist it so firstly,
let's go into our DTO for the Create reservation and I'm going to get rid of the user supplied invoice
ID here.
We're not going to allow them to supply an invoice ID and we'll also go ahead and get rid of the place
ID here as we are not using it.
And I'll go ahead and get rid of the unused imports here.
We'll additionally go back to the reservation schema and get rid of the place ID here.
We won't be using this, but we'll keep the invoice ID instead of having the user supply anymore.
Now though, we actually are going to extract it from the stripe response.
And so if we go ahead and firstly log the response out once more and send off another reservation request
here, you can see in the log statement here for the payment intent, we get an ID for the payment intent,
which is what we want to use to be able to get the information about the payment intent later on.
So to extract this, all we'll have to do is go ahead and supply the invoice ID and pull it off of the
response.id field.
We'll get rid of the console log statement here.
And now if we go ahead and send off another request here, you can see our invoice ID is the actual
real ID for the stripe request.
If we send off another one here, you can see we will get a new unique invoice ID, which is excellent.
Okay, so quick update.
It appears that some people in the course are having issues from the Stripe API.
When sending our credit card details directly to the API.
This seems to be a sporadic change that only some users are experiencing because of Stripe changing
their API requirements and we can easily get around this error.
If you are experiencing it.
We can just use a default test card that stripe offers instead of using our own custom card details.
So in order to specify that custom test card, we just need to get rid of our existing payment method
and the payment method types.
We're going to go ahead and add payment method now of PM card visa, which is just the token or the
name of one of the test cards that Stripe has.
We won't then actually be needing the payment method in this case, so we can remove this and also get
rid of the card that we're destructuring from the create charge.
DTO Now I'm still going to keep the existing card, DTO because I think it's a good example of how we
can do nested validation in class validator.
However, we don't actually need to use it now when we're creating the charge.
So just to show this is still working, I'll go ahead and send off another reservation and I'll change
my charge, amount to $17, send off a request.
And now if we head back to our Stripe dashboard and refresh, we should still see a charge of $17 that
succeeded.
And if we click into it, we can see it's using this test visa payment method and we should have no
more errors about sending credentials directly over the wire.