Making a Payment Using a Credit Card
Learn how to purchase books and make a Stripe payment with a credit card.
The previous lesson taught us how to set up Stripe integration by generating a payment intent from Stripe. Let’s pick up from where we left off. Open the imports/ui/MakePayment.jsx
file. On lines 2–6, we import useStripe
, useElements
, and PaymentElement
from @stripe/react-stripe-js
. The useStripe
hook is used to load Stripe into the component, while useElements
is used to load a Stripe Elements
tag. The MakePaments
component must be wrapped by a Stripe Elements
tag because we’ll use a Stripe PaymentElement
.
The PaymentElement
component
The PaymentElement
is a component from Stripe that displays a form on the page so that users to enter their credit card details for processing. The component in which the PaymentElement
is contained should be wrapped with a Stripe Elements
tag so that it has access to the Stripe library and client secret.
Open App.jsx
to see how Elements
is used to wrap the MakePayment
component. On lines 84–88, the Element
component from Stripe is used to wrap MakePayment
. If a user navigates to the /make_payment
route, the component is rendered. In the MakePayment.jsx
file on lines 10–11
, we extract stripe and elements from the hooks function. On line 52, we load the PaymentElement
component.
Submitting the PaymentElement
form
We have a “submit” button defined on line 54. With a click of this button, the handleSubmit
function is called. The “submit” button is disabled if stripe is null
, which means that we were unable to load the Stripe library on the component.
The handleSubmit
function is an async
function, and we’ll need to await
the value. On line 15, we check if stripe and elements are loaded. If it’s not, we return from the function.
On line 21, we call the confirmPayment
function of stripe. This function is an async
function, and we need to await
the result. We pass in the elements
and confirmParams
, which is an object with a key of return_url
.
If the payment was successfully confirmed, Stripe pushes the user to the URL
defined in the object key, return_url
. We use the Meteor.absoluteUrl
function that returns the root of the application. Upon successful payment confirmation, we want to push the user to the /complete
route.
If Stripe was unable to confirm the payment, the error
destructured from the method stripe.confirmPayment
on line 21 won’t be null
. Stripe uses the client secret to confirm if the payment the user is about to make is a valid payment intent. This information is available in the elements
variable that was passed to the Stripe payment confirmation method.
The setErrorMessage
function is called when an error is encountered by passing in the message
property of the error
object. We also remove the client_secret
from local storage and could decide to push the user to the component to restart the payment process, if we want.
Payment Confirmation
Stripe pushes the user to the /complete
route. Let’s take a look at the /complete
route. Open the App.jsx
file. On lines 90–94, we have a route defined that Stripe pushes us to. The /complete
route is wrapped with a Stripe Elements
tag that renders the CheckPaymentStatus
. The CheckPaymentStatus
checks the status returned from Stripe to see if the payment was successful.
Open the imports/ui/CheckPaymentStatus.jsx
file. On lines 11–51, we define a function called checkStatus
. This function performs a check on the payment status. It does that by calling the stripe.retrievePaymentIntent
function and passing in the client_secret
.
On line 12, we retrieve the clientSecret
from the URL using the URLSearchParams
function. The search parameter of the URL is retrieved after the ?
symbol in the URL. We get the search parameter using window.location.search
. The get
function of URLSearchParams
is used to retrieve the payment_intent_client_secret
key from the search parameter.
On line 16, we check if we were able to retrieve a clientSecret
from the URL. If the clientSecret
is null
, we push the user to the home
route. We await
the result of the payment confirmation check with Stripe on line 22. We’re only interested in the paymentIntent
, which we destructured from the return
value.
On line 28, we check the status
property of the paymentIntent
using a switch
statement. The showMessage
function is updated with the status of the payment. The showMessage
is a function used to change the message state. On line 48, we call a Meteor Method called stripe.completePayment
to update the payment status in our database. We also remove the client_secret
key from local storage.
Calling the checkStatus
function
The checkStatus
function is called as soon as stripe
is loaded on the page. On lines 56–60, we define a useEffect
function that has a dependency of stripe. This means that this function only executes when the value of stripe changes. Inside the useEffect
function, we also check if stripe isn’t null
. If the check succeeds, the checkStatus
function executes, and the result of the Stripe confirmation is displayed on the page.
Task
Run the application, and purchase some books. Use the following credit card details to make the payment:
Card number: “4242 4242 4242 4242”
Exp date: Any valid future date
CVV: Any valid three-digit number
Get hands-on with 1400+ tech skills courses.