Stripe integration with netlify

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();

Have a read of:

and

1 Like

Thank you, ive read through both of those. what should i use to deploy my site then?are there any other free altrernatives? and shouldnt it be able to work with the way i have it set up if i just change the the app to run through the express router functions.

https://docs.netlify.com/integrations/frameworks/express/

and to my knowledge is this not just making api calls meaning that what im trying to do should work with netlify functions

@nitronick23 The way that you’re working isn’t a way that I work, so I can’t advise on specifics.

Your best bet would be to read the documentation and then do some tests.

In regards to alternatives you could Google around.

I’m sure you’re aware but Netlify doesn’t actually have a “free plan”, the Starter Plan has generous inclusions but if you exceed them there is a cost.

1 Like