Okay, now it's time to set up stripe on our client side of things and what we're going to use for this.
If I just search for React and Stripe in Google, then we'll go to the react stripe reference.
Stripe provides react components that we can use to help us configure our checkout, and it does come
with some really quite excellent functionality.
And the setup for this is really just to install the stripe react stripe js and stripe stripe js packages.
And what this gives us is stripe elements.
And stripe elements consist of lots of different components that we can utilize.
And I'll just scroll down in here to take a look at the available element components.
Some of them we will be using.
We'll be using the address element, which allows us to collect address details for 236 regional formats.
So depending on the country that the user selects, then it's going to format the address fields relevant
for that particular country and that takes away a massive burden as a developer.
Typically in a demonstration, I would just demonstrate US formatted addresses and not worry about any
others.
But if we use this address element, then this covers that for us.
What this also gives us, if combined with the payment element that we'll also use is Google autocomplete
for addresses as well.
And that is very useful.
So we'll be using the payment element which is here allows us to collect payment details for 25 plus
different payment methods from around the globe.
And we'll be utilizing those two components from here.
We're not going to be using the other ones themselves.
The card element that comes along with the payment element that we'll be using.
And because of the autocomplete functionality, then we get the most functionality for the least amount
of work.
If we use the address element and the payment element inside here.
Now one downside to using this and I'll just copy the npm install into my clipboard since I've got the
docs open and copy this.
But one downside, and what you might want to do is just right click, inspect your console, and just
savor the moment of having a nice, clean, no warning console because this is going to be the last
time we see it like this on this training course, thanks to stripe JavaScript.
Now the JavaScript that stripe provides is very functional and it's secure.
They've made it.
They've added security elements inside here to prevent fraud and all of that good stuff that you would
expect from a payment provider.
However, what it also comes along with is warnings out of our control.
So we'll see this as we encounter them.
But I just want you to to take a look and gaze at a nice, clean, unblemished Console and say goodbye
to it, because what's coming up now is really out of our control, and it's not going to be quite as
clean in the future.
So back to VSCode and let's open up our terminal and we'll go to the third tab, and we're going to
install the stripe JavaScript and the react stripe stuff.
We don't need that.
Save doesn't do any harm, so I'm not going to worry about removing it and press return.
I don't know if we're going to get the legacy peer dependencies here.
We may do.
And if that is the case, we'll just need to add on the normal switch.
And of course we do.
So I'm going to add on.
In fact let's just clear this window so I don't add this code at the bottom of the screen.
And I'll just repeat that command.
But I will add on the legacy dash peer dash deps switch and press return and get this added.
And now it is added.
So we need to give our client stripe our publishable Key.
That's the one that we can share with the client.
And it's probably about time that we started looking at configuration in our react application.
We haven't done so yet.
And if we go back to the File explorer inside the client folder, then we can provide a dot env file
where we can store key value pairs and environment variables and pass them to our client app.
So at the root of this folder it has to be in a very specific place.
We do not have this right now.
Just right click client say new file and just call it dot env and press return.
And notice it's automatically dimmed out.
So this is automatically excluded from the.
Gitignore file.
Probably doesn't have to be but it is because we can't really store any actual secure secrets inside
our client code because it's always going to be downloaded by the browser anyway.
And anything we put inside here is going to be visible inside that JavaScript.
So we don't put anything secret inside here.
So just because it's excluded from git doesn't mean that we can put secret information in here and we
are not going to.
So we're going to add two things inside here.
We're going to have a white underscore.
And by the way because we're using beats I call it white.
Then because we're using beats that means that if we want these to be passed to our client application
we have to start with white underscore.
That's compulsory.
And then we can use I'll use API underscore URL as the first one.
We say equals.
And then we can use https colon forward slash forward slash localhost colon 5001 forward slash API and
then forward slash.
Please don't forget that forward slash or do we need that forward slash I'm just going to check the
base API and see what we used inside here, because this is what we're going to use to replace it with.
And inside here we do not have a forward slash.
It basically needs to be the same as this without quotes.
So just to be safe because I know this is working, I'll go back to the env file and I will replace
what I have with what I've got in my clipboard.
And the next thing we'll add is the white underscore stripe underscore PK for a publishable key.
And we're going to set this equal to of course our stripe publishable key.
So I'll go back to stripe go back to the home.
And this is where we can get our publishable key from.
So I'll copy that into my clipboard and paste it inside.
Here we do not need quotes surrounding these key value pairs.
So let's first of all test that this one works by using it inside our base API and make sure we still
have the same functionality.
So I'll go to the base API and instead of the hard coded value, then we can change this.
And to use one of the environment variables inside Veet we use import dot meta dot env dot.
And then we can use Veet underscore API underscore URL.
And if I go back to the browser and I go back to the store page and I go back to the catalog, then
what we should find is we're still making our request to the API.
So it is getting that value from the environment.
So let's go back and use the other one that we've added inside there.
And we're going to go to our checkout page.
And just above the checkout page component we'll use const stripe promise equals.
And then we can use the load stripe function from stripe js.
And inside here this takes our publishable key.
So we can use import meta dot env.
And then we can use our vite underscore stripe underscore pk.
And this is going to load stripe into our application.
And if we hover over this then this returns a promise which we're storing inside this variable.
And with just that single line of code, if we go back to our application and we inspect and we go to
our console, uh, Chrome is moving towards a new experience that allows users to choose to browse without
third party cookies.
And this is coming from stripe.
We cannot fix this.
This is Stripe's job to fix these warnings.
There are a lot of them and I really don't like this.
I can't express enough how much I do not like having warnings in the console.
And I'll show you a way that we can filter these out, but there's not really much we can do about this.
One day stripe will fix this, but that day is not today, so they don't cause our application any harm.
It doesn't break any part of our application and they are just warnings, but they are noisy warnings
and there are lots of them.
So just something to live with until stripe eventually get around to fixing that.
Now what we're going to use with this, we're going to wrap our checkout stepper inside an element's
components we get from stripe.
So we're going to surround it with this.
And we'll add its closing tag.
And we'll put the checkout stepper inside the elements there.
Now the elements component this takes the stripe promise.
So we specify stripe.
And then we pass in our stripe promise.
But what it also takes is some options.
And we need to create the options, one of the options it needs.
It needs the client secret that we have inside our basket.
So we're going to use inside our checkout page here we're going to use our Usefetch basket query.
So I'll specify data and give it a name of basket equals use fetch basket query.
And then we can create some options that we can pass to our stripe elements.
So I'll say const options.
And we'll give this a type of stripe elements.
Options.
And stripe does come with excellent TypeScript support by the way as well.
Everything that we use from stripe will have a type available and pretty straightforward to use.
So we're going to use this in a very specific way.
And we're going to use a hook that we haven't used yet.
So our stripe elements options because we don't know if we've got the client secret at this point,
our basket could have declined secret.
It could not have it.
So we'll make this possibly undefined as an alternative type.
So we'll use a union type for that.
And we're going to use something called a usememo.
Now technically speaking what react have got coming up.
This probably will not be required in future versions of react, because react have introduced something
that's still in beta at the moment called a react compiler.
But what this ensures when we use Usememo is if our check out page Rerenders for whatever reason, then
if we store the results of what we're doing here inside Usememo, then this is Memoized.
So only if one of the dependencies we supply to this Usememo will list options possibly be recreated.
So it's just a way of ensuring that something doesn't change when something is rerendered And potentially
this could change.
So we use a use memo here which takes a callback function.
So I'll add the callback inside here.
Add curly brackets.
And this takes some dependencies.
And inside the callback function we're going to check to see if we do not have the basket and the client
secrets.
And we need to go back to our basket to add those properties as well.
So let's go back to our baskets.
And we're going to add to our baskets in the basket type.
We're going to have the client secret make it optional which is going to be a string.
And we'll have our payment intent ID again optional.
And that's going to be a string as well.
So back in our checkout page we're going to check for the presence of the client secrets.
If we do not have it then we're going to return undefined.
And that's the reason the options could be undefined.
If we do have it we're going to return.
And we'll put this inside an object and we'll specify the client secrets, colon baskets, client secrets.
And our dependency for this usememo function is the baskets dot client secrets.
So we need to check to see if we have the options before we can pass them to the elements.
So just inside the grid we'll do a couple of checks.
Actually we'll use not stripe promise because we need to check to see if we have the stripe promise
or not options.
And if we're missing either of those, we cannot load our checkout effectively because we have to have
the client secret to load the stripe elements.
So I'll specify a ternary here.
So I'll add a question mark, open parentheses.
And if we do not have either of those then we'll use typography.
And we'll give it a variant of eight six.
And we'll just say loading checkouts dot dot dot.
And to the right of the parentheses we'll add a colon.
Open more parentheses and we'll put our elements inside here.
And we'll pass as well as the stripe promise to the elements.
We need to pass through the options.
And we'll pass it to the options we have just created.
So what I'd expect to see at this point is we're going to be stuck loading the checkout, because we
do not have the client secret for our basket yet, because we haven't set up that functionality.
So if I go back to the browser, let's just refresh this page.
And if I click on the basket and then I click on the checkout, then we're going to be stuck in the
loading checkout because we're not able to get the client secret from our basket at this point.
And we'll deal with that next.
And we'll create a checkout API so that we can call our payments intent endpoint on the API.