site-name = [Shop Yomilo] https://shopyomilo.netlify.app/
I am trying to process payments to complete this ecommerce website and it seems all the resources ive tried are outdated or not exactly what im looking for. I am aware of and have seen stripe integrated through the use of netlify functions and I know that i may need mongoDB (which ive setup but havent utilized besides a simple success console log). Right now checkout works locally obviously, as an express app and as you can see below im trying to have it a create checkout page on the fly with whatever items are in the cart.
Long story short, how do i deploy my ecommerce site with the backend functionality?
I hope i gave enough context and thank you for your time.
//server.js
import express from "express";
import dotenv from "dotenv";
import stripe from "stripe";
import mongoose from "mongoose";
import mongodb from "mongodb";
// Load Variables
dotenv.config();
// Start Server
const app = express();
app.use(express.static("dist"));
app.use(express.json());
// Home Route
app.get("/", (req, res) => {
res.sendFile("index.html", { root: "dist" });
});
// Cart
app.get("/cart.html", (req, res) => {
res.sendFile("cart.html", { root: "dist" });
});
// Success
app.get("/success.html", (req, res) => {
res.sendFile("success.html", { root: "dist" });
});
// Success
app.get("/cancel.html", (req, res) => {
res.sendFile("cancel.html", { root: "dist" });
});
// Stripe
let stripeGateway = stripe(process.env.stripe_key);
app.post("/stripe-checkout", async (req, res) => {
const lineItems = req.body.items.map((item) => {
const unitAmount = parseInt(parseFloat(item.price) * 100);
console.log("item-price:", item.price);
console.log("unitAmount:", unitAmount);
return {
price_data: {
currency: "usd",
product_data: {
name: item.title,
images: [item.image],
},
unit_amount: unitAmount,
},
quantity: item.quantity,
};
});
const session = await stripeGateway.checkout.sessions.create({
payment_method_types: ["card"],
mode: "payment",
success_url: `http://localhost:3000/success.html`,
cancel_url: `http://localhost:3000/cancel.html`,
line_items: lineItems,
billing_address_collection: "required",
});
res.json({ url: session.url });
});
mongoose.connect
(
process.env.MONGO_URL
)
.then(() => console.log("DBConnection Success!"))
.catch((err) => {
console.log(err);
});
app.listen(process.env.PORT || 3000, () => {
console.log("listing on port 3000");
});
//main.js
//extra context if needed to show overall setup
//Products Array
const products = [
{
id:1,
title: "Umbrella Sunshade",
price: 29.95,
image: "https://i.ibb.co/MZqQcDY/slider-img-1.png",
url: "umbrella-sunshade.html",
},
{
id:2,
title: "Wireless Detector",
price: 24.95,
image: "https://i.ibb.co/vPdQqky/slider-img-2.png",
url: "wireless-detector.html",
},
{
id:3,
title: "Magnetic Wireless Charger",
price: 59.95,
image: "https://i.ibb.co/CtFtMWS/slider-img-3.png",
url: "magnetic-wireless-charger.html",
},
{
id:4,
title: "Suspended Wine Rack",
price: 19.95,
image: "https://i.ibb.co/jb64ZXq/slider-img-4.png",
url: "suspended-wine-rack.html",
},
];
// Get the products list and elements
const productList = document.getElementById("productList");
const cartItemsElement = document.getElementById("cartItems");
const cartTotalElement = document.getElementById("cartTotal");
// Store Cart Items In Local Storage
let cart = JSON.parse(localStorage.getItem("cart")) || [];
//Render Products On Page
function renderProducts()
{
if (productList != null)
{
productList.innerHTML = products
.map(
(product) => `
<div class="product">
<a class="product-link-a" href="${product.url}">
<img src="${product.image}" alt="${product.title}" class="product-img">
<div class="product-info">
<h2 class="product-title">${product.title}</h2>
<p class="product-price">${product.price.toFixed(2)}</p>
</div>
</a>
<a class="add-to-cart" data-id="${product.id}">Add To Cart</a>
</div>
`
)
.join("");
}
//Add to Cart
const addToCartButtons = document.getElementsByClassName('add-to-cart');
for(let i = 0; i < addToCartButtons.length; i++)
{
const addToCartButton = addToCartButtons[i];
addToCartButton.addEventListener("click", addToCart);
}
}
//Add To Cart
function addToCart(event)
{
const productID = parseInt(event.target.dataset.id);
const product = products.find((product) => product.id === productID)
if(product)
{
//If product already in cart
const existingItem = cart.find((item) => item.id === productID);
if(existingItem)
{
existingItem.quantity++;
}
else
{
const cartItem =
{
id: product.id,
title: product.title,
price: product.price,
image: product.image,
quantity: 1,
}
cart.push(cartItem);
}
//Change add to cart text to added
event.target.textContent = "Added!";
updateCartIcon();
saveToLocalStorage();
renderCartItems();
calculateCartTotal();
}
}
//Remove from cart
function removeFromCart(event)
{
const productID = parseInt(event.target.dataset.id);
cart = cart.filter((item) => item.id !== productID);
saveToLocalStorage();
renderCartItems();
calculateCartTotal();
updateCartIcon();
}
//Quantity Change
function changeQuantity(event)
{
const productID = parseInt(event.target.dataset.id);
const quantity = parseInt(event.target.value);
if (quantity > 0)
{
const cartItem = cart.find((item) => item.id === productID);
if(cartItem)
{
cartItem.quantity = quantity;
saveToLocalStorage();
calculateCartTotal();
updateCartIcon();
}
}
}
//SaveToLocalStorage
function saveToLocalStorage()
{
localStorage.setItem("cart", JSON.stringify(cart));
}
//Render Products On Cart Page
function renderCartItems()
{
if (cartItemsElement != null)
{
cartItemsElement.innerHTML = cart
.map(
(item) => `
<div class="cart-item">
<img src="${item.image}" alt="${item.title}">
<div class="cart-item-info">
<h2 class="cart-item-title">${item.title}</h2>
<input
class="cart-item-quantity"
type="number"
name=""
min="1"
value="${item.quantity}"
data-id="${item.id}"
/>
</div>
<h2 class="cart-item-price">$${item.price}</h2>
<button class="remove-from-cart" data-id="${item.id}">Remove</button>
</div>
`
)
.join("");
}
//Remove From Cart
const removeButtons = document.getElementsByClassName('remove-from-cart');
for(let i = 0; i < removeButtons.length; i++)
{
const removeButton = removeButtons[i];
removeButton.addEventListener("click", removeFromCart);
}
// Quantity Change
const quantityInputs = document.querySelectorAll('.cart-item-quantity');
quantityInputs.forEach((input) =>{
input.addEventListener('change', changeQuantity);
});
}
//Calculate Total
function calculateCartTotal()
{
const total = cart.reduce((sum, item) =>sum + item.price * item.quantity, 0);
cartTotalElement.textContent = `Total : $${total.toFixed(2)}`;
}
//Check If On Cart Page
if(window.location.pathname.includes('cart.html'))
{
renderCartItems();
calculateCartTotal();
}else{
renderProducts();
}
//Cart Icon Quantity
const cartIcon = document.getElementById('cart-icon');
function updateCartIcon()
{
const totalQuantity = cart.reduce((sum, item) => sum + item.quantity, 0);
cartIcon.setAttribute('data-quantity', totalQuantity);
}
updateCartIcon();
function updateCartIconOnCartChange()
{
updateCartIcon();
}
window.addEventListener('storage', updateCartIconOnCartChange);
function updateCartIcon()
{
const totalQuantity= cart.reduce((sum, item) => sum+ item.quantity, 0);
const cartIcon = document.getElementById("cart-icon");
cartIcon.setAttribute('data-quantity', totalQuantity);
}
renderProducts();
renderCartItems();
calculateCartTotal();