In this tutorial, we will learn how to build a shopping cart using React and integrate Stripe for payment processing. The shopping cart will allow users to add items to their cart, update quantities, and remove items. When the user is ready to checkout, they will be redirected to the Stripe payment page to complete the purchase.
Before we begin, make sure you have Node.js and npm installed on your machine. You will also need a Stripe account to obtain the necessary API keys.
1. Setting up the Project
Let’s start by setting up a new React project.
Open a terminal and run the following command:
npx create-react-app shopping-cart
Once the project is created, navigate to the project directory:
cd shopping-cart
2. Installing Dependencies
Next, we need to install the necessary dependencies for our project. We will use the stripe
and react-stripe-checkout
libraries for integrating Stripe payment processing.
Run the following command to install the dependencies:
npm install stripe react-stripe-checkout
3. Setting up Stripe
To integrate Stripe into our shopping cart, we need to obtain the necessary API keys.
- Log in to your Stripe account, or create a new account if you don’t have one.
- In the Dashboard, navigate to Developers > API keys.
- Copy your Publishable key and Secret key. We will use these in our code.
4. Creating the Shopping Cart Component
Now let’s start building our shopping cart component.
Create a new file called ShoppingCart.js
in the src
directory and add the following code:
import React, { useState } from 'react';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
// TODO: Implement add to cart, update quantity, remove item, and checkout functions
return (
<div>
{/* TODO: Display cart items */}
{/* TODO: Implement add to cart, update quantity, and remove item buttons */}
{/* TODO: Implement checkout button */}
</div>
);
};
export default ShoppingCart;
In the code above, we import the useState
hook from React to manage the cart items state. We also define the cartItems
state variable as an empty array. We will use this array to store the items in the cart.
5. Displaying Cart Items
Let’s start by displaying the items in the cart.
Update the ShoppingCart
component code as follows:
import React, { useState } from 'react';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
return (
<div>
<h2>Shopping Cart</h2>
{cartItems.length === 0 ? (
<p>No items in cart</p>
) : (
<ul>
{cartItems.map((item, index) => (
<li key={index}>
{item.name} - {item.quantity}
</li>
))}
</ul>
)}
</div>
);
};
export default ShoppingCart;
In the updated code, we display a heading “Shopping Cart” and check if cartItems.length
is zero. If the length is zero, we display a message “No items in cart”. Otherwise, we map through the cartItems
array and display each item name and quantity as a list item.
6. Adding Items to Cart
Let’s implement the functionality to add items to the cart.
Update the ShoppingCart
component code as follows:
import React, { useState } from 'react';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
const addToCart = (item) => {
const existingItem = cartItems.find((i) => i.id === item.id);
if (existingItem) {
setCartItems(
cartItems.map((i) =>
i.id === item.id ? { ...i, quantity: i.quantity + 1 } : i
)
);
} else {
setCartItems([...cartItems, { ...item, quantity: 1 }]);
}
};
return (
<div>
{/* Display cart items */}
{/* Implement add to cart, update quantity, and remove item buttons */}
{/* Implement checkout button */}
</div>
);
};
export default ShoppingCart;
In the updated code, we define the addToCart
function. This function takes an item as a parameter and checks if the item already exists in the cart (existingItem
). If it exists, we update the quantity of the item by finding it in the cartItems
array with find
, and if not, we add the item to the array with a quantity of 1 ([...cartItems, { ...item, quantity: 1 }]
). Finally, we update the cartItems
state with setCartItems
.
To test the functionality, update the code where you’re rendering the ShoppingCart
component:
import React from 'react';
import ShoppingCart from './ShoppingCart';
const App = () => {
const item = {
id: 1,
name: 'Example Item',
};
return (
<div>
<h1>Shopping App</h1>
<ShoppingCart />
<button onClick={() => addToCart(item)}>Add to cart</button>
</div>
);
};
export default App;
In the code above, we define an item
object and pass it as a prop to the ShoppingCart
component. We also add a button and an onClick
event that calls the addToCart
function with the item
object.
7. Updating Item Quantities
Next, let’s implement the functionality to update item quantities in the cart.
Update the ShoppingCart
component code as follows:
import React, { useState } from 'react';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
const addToCart = (item) => {
// ... (Add item to cart logic)
};
const updateQuantity = (item, quantity) => {
if (quantity === 0) {
removeItem(item);
} else {
setCartItems(
cartItems.map((i) => (i.id === item.id ? { ...i, quantity } : i))
);
}
};
const removeItem = (item) => {
setCartItems(cartItems.filter((i) => i.id !== item.id));
};
return (
<div>
{/* Display cart items */}
{cartItems.length === 0 ? (
<p>No items in cart</p>
) : (
<ul>
{cartItems.map((item, index) => (
<li key={index}>
{item.name} - {item.quantity}
<button
onClick={() => updateQuantity(item, item.quantity - 1)}
>
-
</button>
<button
onClick={() => updateQuantity(item, item.quantity + 1)}
>
+
</button>
<button onClick={() => removeItem(item)}>Remove</button>
</li>
))}
</ul>
)}
{/* Implement add to cart button */}
{/* Implement checkout button */}
</div>
);
};
export default ShoppingCart;
In the updated code, we define the updateQuantity
function that takes an item and a quantity as parameters. If the quantity is 0, we call the removeItem
function. Otherwise, we update the cartItems
state by mapping through the cartItems
array and updating the quantity of the item if the item ID matches (setCartItems(cartItems.map((i) => (i.id === item.id ? { ...i, quantity } : i)))
). Finally, we define the removeItem
function that filters out the item from the cartItems
array and updates the state.
We also update the rendering of the cartItems
in the return
statement to include buttons for updating the quantity (-
and +
), and a button to remove the item from the cart.
8. Implementing Checkout
Now let’s implement the checkout functionality using Stripe.
Update the ShoppingCart
component code as follows:
import React, { useState } from 'react';
import StripeCheckout from 'react-stripe-checkout';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
const addToCart = (item) => {
// ... (Add item to cart logic)
};
const updateQuantity = (item, quantity) => {
// ... (Update quantity logic)
};
const removeItem = (item) => {
// ... (Remove item logic)
};
const handleToken = (token) => {
console.log(token);
// Send the token to your server for processing
};
return (
<div>
{/* Display cart items */}
{/* Implement add to cart, update quantity, and remove item buttons */}
<StripeCheckout
stripeKey="YOUR_STRIPE_PUBLISHABLE_KEY"
token={handleToken}
>
<button>Checkout</button>
</StripeCheckout>
</div>
);
};
export default ShoppingCart;
In the updated code, we import the StripeCheckout
component from react-stripe-checkout
and define the handleToken
function. This function logs the token to the console and can be used to send the token to your server for processing.
We also add a StripeCheckout
component that takes your Stripe Publishable key as the stripeKey
prop, and the handleToken
function as the token
prop. Inside the StripeCheckout
component, we add a button for the user to initiate the checkout process.
At this point, you should replace 'YOUR_STRIPE_PUBLISHABLE_KEY'
with your actual Stripe Publishable key.
9. Testing the Shopping Cart
Now let’s test the shopping cart functionality.
Update the App
component code as follows:
import React from 'react';
import ShoppingCart from './ShoppingCart';
const App = () => {
const item = {
id: 1,
name: 'Example Item',
};
return (
<div>
<h1>Shopping App</h1>
<ShoppingCart />
<button onClick={() => addToCart(item)}>Add to cart</button>
</div>
);
};
export default App;
In the code above, we import the ShoppingCart
component and define an item
object. We also add a button with an onClick
event that calls the addToCart
function with the item
object.
Save your changes and start the development server by running the following command:
npm start
Open your browser and navigate to `http://localhost:3000`. You should see the shopping cart component and a button to add the item to the cart. Click the button, and the item should be displayed in the cart. You can also update the quantity or remove the item from the cart.
10. Completing the Checkout Process
To complete the checkout process, we need to implement the server-side functionality to process the Stripe token and create the charge. This tutorial focuses on the front-end implementation using React, so we will not cover the server-side implementation in detail.
However, we can provide an example of how you can make an API request to your server using fetch
and pass the token to your server for processing.
Update the handleToken
function in the ShoppingCart
component code as follows:
const handleToken = (token) => {
fetch('/charge', {
method: 'POST',
body: JSON.stringify(token),
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((data) => {
console.log(data);
// Handle the response from your server
})
.catch((error) => {
console.error('Error:', error);
});
};
In the updated code, we use the fetch
function to make a POST
request to the /charge
endpoint of your server. We pass the Stripe token as the request body, and set the content type to application/json
. We also handle the response from your server for further processing.
Update the ShoppingCart
component code:
import React, { useState } from 'react';
import StripeCheckout from 'react-stripe-checkout';
const ShoppingCart = () => {
const [cartItems, setCartItems] = useState([]);
// ... (Additem to cart, update quantity, remove item functions)
const handleToken = (token) => {
fetch('/charge', {
method: 'POST',
body: JSON.stringify(token),
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((data) => {
console.log(data);
alert('Payment Successful!');
setCartItems([]);
})
.catch((error) => {
console.error('Error:', error);
});
};
return (
<div>
{/* Display cart items */}
{/* Implement add to cart, update quantity, and remove item buttons */}
<StripeCheckout
stripeKey="YOUR_STRIPE_PUBLISHABLE_KEY"
token={handleToken}
>
<button>Checkout</button>
</StripeCheckout>
</div>
);
};
export default ShoppingCart;
In the updated code, we handle the response from your server by logging the data to the console, displaying an alert message with “Payment Successful!”, and clearing the cart items by calling setCartItems([])
.
Remember to update 'YOUR_STRIPE_PUBLISHABLE_KEY'
with your actual Stripe Publishable key.
This completes the implementation of the shopping cart with Stripe integration using React.
Conclusion
In this tutorial, we learned how to build a shopping cart using React and integrate Stripe for payment processing. We created a shopping cart component with functionalities to add items, update quantities, remove items, and initiate the checkout process. We also introduced the react-stripe-checkout
library to integrate Stripe into our application and handle the token for server-side processing.
Remember to handle the server-side implementation separately to complete the checkout process and create a charge in Stripe.