💳 Payment Integration with React and Node.js (Super Simple via Stripe with Dummy Data)
Ishwor karki

Ishwor karki @ishworj

Joined:
Mar 3, 2025

💳 Payment Integration with React and Node.js (Super Simple via Stripe with Dummy Data)

Publish Date: May 19
6 2

If you're building a React project and want to add a payment feature, you're in the right place. In this post, I’ll show you the easiest way to integrate Stripe Checkout using:

  • React for the frontend
  • Node.js + Express for the backend
  • No database — just dummy data

Perfect for beginners who want to learn fast or create a tutorial or demo app!


🛠 What We’re Building

You’ll create:

  • A fake cart (no real database)
  • A “Pay Now” button
  • A Stripe payment flow
  • A simple success/failure result screen

🧰 Tech Stack

  • Frontend: React (using basic components)
  • Backend: Node.js with Express
  • Payment: Stripe (Checkout session)

📦 Backend Setup (Node.js + Express + Stripe)

Step 1: Create the backend project

mkdir backend
cd backend
npm init -y
npm install express stripe cors dotenv
Enter fullscreen mode Exit fullscreen mode

Step 2: Add your .env file

Create a .env file in the backend folder and add your Stripe secret key:

STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key_here
Enter fullscreen mode Exit fullscreen mode

Step 3: Create index.js

import express from "express";
import dotenv from "dotenv";
import Stripe from "stripe";
import cors from "cors";

dotenv.config();
const app = express();
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

app.use(cors());
app.use(express.json());

app.post("/api/checkout", async (req, res) => {
  try {
    const { items, email } = req.body;

    const line_items = items.map((item) => ({
      price_data: {
        currency: "aud",
        product_data: { name: item.name },
        unit_amount: item.price * 100,
      },
      quantity: item.quantity,
    }));

    const session = await stripe.checkout.sessions.create({
      payment_method_types: ["card"],
      line_items,
      customer_email: email,
      mode: "payment",
      success_url: "http://localhost:5173/payment-result?success=true&session_id={CHECKOUT_SESSION_ID}",
      cancel_url: "http://localhost:5173/payment-result?success=false&session_id={CHECKOUT_SESSION_ID}",
    });

    res.json({ url: session.url });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Checkout session failed" });
  }
});

app.listen(5000, () => console.log("Backend is running on port 5000"));
Enter fullscreen mode Exit fullscreen mode

💻 Frontend Setup (React)

You can use Vite or Create React App. Let’s say you're inside App.jsx.

Step 1: Dummy Cart UI

import React from "react";
import axios from "axios";

const dummyCart = [
  { name: "T-shirt", price: 30, quantity: 2 },
  { name: "Hat", price: 20, quantity: 1 },
];

const App = () => {
  const total = dummyCart.reduce((acc, item) => acc + item.price * item.quantity, 0);

  const handleCheckout = async () => {
    try {
      const res = await axios.post("http://localhost:5000/api/checkout", {
        items: dummyCart,
        email: "test@example.com", // Dummy email for now
      });

      window.location.href = res.data.url;
    } catch (err) {
      alert("Checkout failed");
      console.error(err);
    }
  };

  return (
    <div style={{ maxWidth: 400, margin: "40px auto", textAlign: "center" }}>
      <h2>🛒 Dummy Cart</h2>
      {dummyCart.map((item, index) => (
        <p key={index}>
          {item.name} x {item.quantity} = ${item.price * item.quantity}
        </p>
      ))}
      <h3>Total: ${total}</h3>
      <button onClick={handleCheckout} style={{ padding: "10px 20px" }}>
        Pay Now
      </button>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

🚀 Run and Test

  1. Start the backend:
node index.js
Enter fullscreen mode Exit fullscreen mode
  1. Start the frontend (React app):
npm run dev
Enter fullscreen mode Exit fullscreen mode
  1. Go to your app and click the "Pay Now" button — you’ll be taken to Stripe’s secure checkout page! Here's what to expect:
  • ✅ Itemized summary of the products (name, price, quantity)
  • 💳 Input fields for card details (number, expiry, CVC)
  • 📧 Pre-filled customer email (if provided in session)
  • 🔒 Secure and PCI-compliant design

This is a hosted page by Stripe — meaning you don't need to worry about building the form or storing card info. It’s fast, secure, and mobile-friendly.


💳 Stripe Test Card Details for Development

Stripe provides a range of test card numbers that work in test mode and simulate different payment scenarios.


✅ Commonly Used Card

Purpose Card Number Expiry CVC Result
Success Payment 4242 4242 4242 4242 Any future date Any 3 digits ✅ Approved

❌ Other Test Cards

Scenario Card Number Result
Declined card 4000 0000 0000 0002 ❌ Declined
Insufficient funds 4000 0000 0000 9995 ❌ Declined
Card requires authentication 4000 0027 6000 3184 3D Secure required
Incorrect CVC 4000 0000 0000 0127 ❌ Declined

🧾 Usage Guide

  • Expiry Date: Use any future date like 12/34
  • CVC: Use any 3-digit number like 123
  • ZIP/Postal Code: You can enter any value, e.g., 12345

✅ What Happens After Payment?

Notice this part in our backend:

success_url: "http://localhost:5173/payment-result?success=true&session_id={CHECKOUT_SESSION_ID}",
cancel_url: "http://localhost:5173/payment-result?success=false&session_id={CHECKOUT_SESSION_ID}",
Enter fullscreen mode Exit fullscreen mode

Stripe will automatically replace {CHECKOUT_SESSION_ID} with the actual session ID. That means you can verify the payment on the next page using that session.


🧠 Challenge For You!

Here’s a fun task to practice what you’ve learned:

✅ Use the session_id in the URL to verify the payment on your /payment-result page.

Hint:

  • Use useSearchParams() in React to get the session ID.
  • Create a new backend route:
  stripe.checkout.sessions.retrieve(session_id)
Enter fullscreen mode Exit fullscreen mode
  • Check if session.payment_status === "paid"

You can then show either a "Payment Successful 🎉" or "Payment Failed ❌" message based on the result.


🎉 That’s It!

You now have a working Stripe Checkout integration using dummy data. Feel free to expand this into a real cart later. Let me know if you’d like help verifying the session or deploying it online!

Comments 2 total

  • Nevo David
    Nevo DavidMay 19, 2025

    Nice, love when stuff just works and you don’t gotta fight with docs for hours.

  • Dotallio
    DotallioMay 19, 2025

    Love how simple you made this! Any tips on turning the dummy cart into a real one with a database?

Add comment