Hi and welcome back.
Today we're going to be working on Stripe
payment integration with our mobile application and we're going to make sure
that we can use the API endpoints that we created in the previous lessons.
So the only change I made after our lesson is that I put Stripe publishable key
and Stripe secret key inside the constants JS file so that I don't share
my information regarding Stripe with everyone who's taking this course.
You can do so as well and place your keys inside the constant JS file.
You can find your keys inside your dashboard for Stripe.
Just navigate to your dashboard, click on API keys and you're going to see
your publishable key and secret key right there.
Just make sure that you are seeing the keys for the development mode.
Great.
So in order to connect to our server, we need to be running the server
and to run the server we need to be inside the root of our server project and we just
need to make sure that we write nodemon index.JS.
This should run our server on port 3000.
To check that everything is going well, we can just open up our postman,
we can send this create payment Intent API endpoint request,
click on Send and we're going to receive a client secret key and we're going to see
this console log right here because we had placed console log here.
Great.
So the question is how do we connect our API endpoint to our mobile application?
So we can do that right now.
Let's go to our donation application.
I have my metro bundler running
here so if I make any changes they are going to be visible here.
So we're going to have to set up a couple
of functions to make sure that we can connect to our API endpoint.
That's going to be very quick and easy.
Let's just navigate to our payment page and first things first,
we need to disable this donate button when the form is not filled in.
Because if the form is not filled in then they can't donation.
Lucky for us, Card form offers a props\
called on form complete and on form complete we can set a flag
to true that will enable this donate button to be clicked.
So let's call this flag is ready and let's create a setter for this as well.
We're going to need to use useState
for this and our initial state is going to be false.
Let me import useState from react it's right here.
Let's save this and here on form complete
we're going to say that we want to set is ready to true.
Now let's use this variable for our button and say that this is going to be disabled
if is ready is false.
Let's save this and right now our donate
button is not going to be clickable and is going to be appearing as disabled.
Great.
Stripe offers several cards that you can use for testing.
And I'm going to show you what these cards are here.
I'm going to navigate to my dashboard and I'm going to turn on the test mode.
I'm going to click on developers.
And here we're going to see that there are
several cards given and we can copy these card numbers for testing
Successful Payments, failed Payments or Requires Authentication payments.
Now we're not going to be requiring any kind of authentication so we're just going
to be using Successful Payment and Failed payment cards to test our implementation.
So I'm just going to copy this number, go back to my simulator,
paste it here and then I'm just going to enter some other random information here.
And here you're going to see that Donate
button was enabled because our form has been completed.
Now, once we click on Donate button, we are actually not connected to any API
endpoints and we need to make sure that we do that.
So let's set that up.
First of all, once we're going to click
on Donate button, we should make sure that this button is
not clickable again, so that we don't process users payments twice.
For this, we're going to have to make sure that we have a loading state where we take
care of the button if the payment is still processing.
Lucky for us, again,
Stripe offers a hook that returns to us two different variables confirm Payment,
which is going to have information about how the payment was processed
and the second property is going to be loading property that is going to be
boolean, either false or true, whether the payment is still being processed or not.
So let's set those up with destructuring.
So one is going to be called Confirm Payment.
Second one is going to be called Loading and we're going to use Confirm Payment
that is going to be imported from Stripe react native right here.
So let's save this and let's make sure
that if a payment is processing, we're going to be disabling this button.
So the form is going to be disabled if
the form is not filled in or if the form is loading.
Great.
Now let's go back to this confirmation of the payment.
We're going to use this later in our
functions to make sure that our confirmation of the payment has been
processed and we show an appropriate response to the user.
So let's set up a function that handles
the payments that we're going to be making. For this
we're going to call
a function on Press and it's going to be called Handle Payment.
So we're going to have to make sure
that we create this function and it's going to be an Asynchronous function
because we're going to be making an API call.
So we're going to have to await on the response of the API call.
Now let's create Handle Payment function here that is also going to be asynchronous
and is going to take in no arguments at all.
And then we're going to have to get the client secret key because that's what
we need to make sure that we can process the payment.
This is the first step to make an intent of payment.
And for that we have already made a function on our server side.
So we just need to make sure that we can connect to our API.
So let's say that we want to get the client secret.
And for this we're going to be calling
a function that is going to be called Fetch Payment Intent
client secret. Great.
So we need to be making this function
first of all, so let's make sure that we make it here.
And it's also going to be an asynchronous function that is going to await on the API
call that we make to our server that's currently running.
So let's expect some kind of a response from our server.
Let's make sure that we await on it and let's fetch the results of this API.
The API URL is going to be http localhost
3000 because that's the port that I'm running my server on.
And our endpoint was called create Payment intent.
Now we got to pass some parameters to it.
First of all, we got to let it know
that the method of the API is post because we're sending in some information.
So we got to make sure that we match up
with the request type that we set up on our server.
And then we need to make sure that we send in some parameters using the body.
And these parameters actually need to be in JSON format.
So let's make sure that we use JSON stringify
method here and let's see what we're going to be needing for this function.
So we need an email, we need a currency, and we need an amount.
So let's get started with email
first. To get the email of the user that we are
logged in with, we're going to have to make sure that we
use the user object created in our redux store.
So let's use selector to get information
from our redux store and say that we need to get the user state.
And then here we're going to send
in an email that is going to be the user's email.
The I think I'm just going to process the payments as USD dollars.
And then we need to send in an amount
that's dependent on which item we're donating with.
So we're just going to use the donation item information here to get the price.
And we're going to make sure that we multiply it by 100 because the last two
digits again in USD is going to be converted to the cent.
So $1.34 should become 134. Great.
So now that we have this,
let's make sure that we can get some kind of response from the server.
So first of all, let's get this response and say that our
client secret is going to be awaiting on the response from the server and we're
going to convert the response into JSON and then we can console log this client
secret right here and we can even return it.
Let's just test it out and see if this is working correctly.
So let's open our Metro bundler.
Let's write in the test number that was all 42s.
Let's click on donate and now we're getting an undefined value
so we get to investigate and see what's happening here.
First of all, let's make sure that we are getting our request on our server.
So let's go to our server and we see that we're getting some invalid
request errors and this might be because we're sending in an invalid integer.
So our request actually didn't receive any kind of parameters through the body and we
can see it right here because we had it console logged here.
So we're doing something incorrectly.
Let's go back to our donation app.
Let's see what we're doing here.
We have the method,
we have the body and what we might be missing here might be headers to let
the server know that we are sending this as JSON format.
So let's set the content
type here and make sure that application is set to JSON.
Let's save this and then let's call the donation again.
I'm just going to click on this and here we see that we receive all the parameters
on our server and now let's see if on Metro bundler we received the client
secret and we did which means that everything was successful here.
This is great.
So now that we have the client secret key,
we got to make sure that we handle the payment from the user correctly.
So all we need to do for that is make sure
that we call the confirm payment method given by the hook that we created here.
So let's create a call that is going
to get back any errors returned by the stripe or the payment
intent information and then let's await on confirm payment
and let's send in the client secret that we received and let's make sure
that we say that our payment method type is a card. Great,
let's save this.
And here we can say that if we receive
an error then we need to alert the user
that error has occurred
with your payment and then let's provide
the error localized message that we're
going to receive from stripe directly indicating what kind of error occurred.
And if there are no errors, then we need to make sure that we send
in an alert to the user letting them know that their payment was successful
and let's say that the payment
was confirmed successfully.
Let's save this,
make sure that you import alert from react native and here instead of else we should
actually use payment intent to make sure that this went in successfully.
So let's use payment intent right here. Great.
Now let's click on donate it's eight three right now.
This payment was successful.
I'm going to go to my Stripe dashboard. Great.
So once I click on payments here,
we're going to see that $1.34 was successfully completed on April 18.
Eight three, which was three minutes ago.
This is great.
And if we were to go to our simulator and go back and select school supplies
kit let's say, try to donate, enter 42 card number.
That is a test card number provided by Stripe and click on donate again.
This is going to be processing.
The payment was completed successfully.
We can go back here, refresh the page,
and here we're going to see that $13.08 was successfully completed.
Now let's test our integration with failed payment.
So I'm going to copy this number,
go to my simulator and make sure to select all of this and paste my new number in.
I'm going to click on donate and I got payment was confirmed successfully.
So let's go to our payments.
And here we see that this was successfully completed again, which is very weird
because this was supposed to be a test number that is supposed to fail.
So let's make sure that our Stripe can read that we entered a new information
by deleting the last digit and entering it again.
Let's click on donate one more time
and now we receive that error has occurred with our payment.
This must have been because once we pasted
the number in, the react native card number didn't get updated.
So if we go back to our payments, we're going to see that this payment has
failed and we have responded with the correct response.
So if the payment is successful,
we can just say that we want to navigate back to the page where user was.
So let's use navigation, go back here.
And if we were to use 42 card number again and clicked on donation,
then success message was shown and our payment was processed successfully.
So that's all.
This is how easy it is to integrate with Stripe. In the next lesson
what we're actually going to do is make sure that we can upload our Stripe
integration of our server side code to Firebase to make sure that instead
of localhost, we're connecting with Firebase functions.
And if you don't know what Firebase functions are, please use a link given
in this resource that will link you back to the video where we went over how
to transfer your local setup to Firebase functions.
Thanks so much for watching.
I'll see you in the next lesson.