Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 5
In the last part of this tutorial, we will display the cart items, add the ability to increment/decrement the quantity, remove products from the cart, and finally pay the orders using Stripe.
Add the cart component
Inside the cart component, we display all the products added to the cart with options to increment/decrement the quantity, remove products from the cart, and finally pay the orders using Stripe.
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrementQ, incrementQ, removeFromCart } from '../../redux/slices/cartSlice'
import Stripe from '../payments/Stripe'
export default function Cart() {
const { cartItems } = useSelector(state => state.cart)
const dispatch = useDispatch()
const total = cartItems.reduce((acc, item) => acc += item.product_price * item.quantity, 0)
return (
<div className='row my-4'>
<div className="col-md-12">
<div className="card">
<div className="card-body">
<table className="table">
<thead>
<tr>
<th>#</th>
<th>Image</th>
<th>Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Subtotal</th>
<th></th>
</tr>
</thead>
<tbody>
{
cartItems.map((item, index) => (
<tr key={item.id}>
<td>{index += 1}</td>
<td>
<img src={item.product_image} alt="Product Image"
className='fluid rounded' width={60} height={60} />
</td>
<td>{item.product_name}</td>
<td>
<i className="bi bi-caret-up"
onClick={() => dispatch(incrementQ(item))}></i>
<span className="mx-2">
{item.quantity}
</span>
<i className="bi bi-caret-down"
onClick={() => dispatch(decrementQ(item))}
></i>
</td>
<td>${item.product_price}</td>
<td>${item.product_price * item.quantity}</td>
<td>
<i className="bi bi-cart-x"
onClick={() => dispatch(removeFromCart(item))}
></i>
</td>
</tr>
))
}
<tr>
<th colSpan={3} className='text-center'>
Total
</th>
<td colSpan={3} className='text-center'>
<span className="badge bg-danger rounded-pill">
${total}
</span>
</td>
</tr>
</tbody>
</table>
{
total > 0 && <Stripe />
}
</div>
</div>
</div>
</div>
)
}
Add the stripe component
Inside the Stripe component we have a pay button once clicked the user will be redirected to the Stripe checkout form to pay orders.
import React from 'react'
import { useSelector } from 'react-redux'
import axios from 'axios'
export default function Stripe() {
const { cartItems } = useSelector(state => state.cart)
const fetchPaymentUrl = async() => {
try {
const response = await axios.post('http://127.0.0.1:8000/api/pay/order',
{cartItems, success_url: 'http://localhost:5173/payment/success'}
)
window.location.href = response.data.url
} catch (error) {
console.log(error)
}
}
return (
<div className='row col-md-6 mx-auto mt-5'>
<button className="btn btn-dark" onClick={() => fetchPaymentUrl()}>
Pay now
</button>
</div>
)
}
Add the payment success component
Inside the payment success component, we display a message telling the user that the payment was done successfully.
import React from 'react'
export default function PaymentSuccess() {
return (
<div className="row my-4">
<div className="col-md-6 mx-auto">
<div className="card">
<div className="card-body">
<h4 className="text-center">
Payment done successfully thank you.
</h4>
</div>
</div>
</div>
</div>
)
}
Update the file index.css
Inside the file index.css add the code below:
i {
cursor: pointer;
}