How to Build an Amazon Clone with Payment Integration: React Firebase Guide
You can build a production-ready Amazon clone with payment integration by extending the React and Firebase starter from the GorvGoyl/Clone-Wars repository with Stripe checkout sessions handled via Firebase Cloud Functions.
The Clone-Wars repository curates open-source clones of popular web platforms, including an Amazon clone entry built with React and Firebase listed at line 68 of the README. This guide demonstrates how to transform that foundation into a complete e-commerce marketplace with secure payment processing, user authentication, and order management.
Architecture Overview
The Amazon clone implementation relies on a serverless architecture that separates client-side rendering from secure backend operations.
Frontend Stack
The user interface utilizes React with React Router for navigation between product listings, detail pages, and the shopping cart. State management for the cart persists across routes using the Context API or Redux, while responsive styling comes from CSS Modules, Tailwind CSS, or Material-UI.
Backend Infrastructure
Firebase provides the serverless backend. Firebase Authentication handles user accounts via email/password or social providers, while Cloud Firestore stores product catalogs, user profiles, and order snapshots. Business logic runs in Firebase Cloud Functions, which securely execute code without managing servers.
Payment Processing
Stripe integrates as the payment processor. The implementation uses callable Cloud Functions to create secure checkout sessions server-side, keeping your Stripe secret key isolated from client-side code as implemented in functions/src/stripe.ts.
Initializing Firebase Services
Before adding payments, initialize Firebase in your React application. In your firebase.ts configuration file, import the modular SDK and instantiate the Auth and Firestore services:
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket:import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
This setup exposes the auth and db instances for use throughout your components, including the cart management logic in src/components/Cart.tsx.
Creating Secure Checkout Sessions
Payment security requires server-side session creation. In functions/src/stripe.ts, implement a callable Cloud Function that validates the user's authentication and generates a Stripe checkout URL:
import * as functions from 'firebase-functions';
import Stripe from 'stripe';
const stripe = new Stripe(functions.config().stripe.secret, { apiVersion: '2023-08-16' });
export const createCheckout = functions.https.onCall(async (data, context) => {
const { cartItems, userId } = data;
if (!context.auth?.uid || context.auth.uid !== userId) {
throw new functions.https.HttpsError('unauthenticated', 'User must be signed in');
}
const lineItems = cartItems.map(item => ({
price_data: {
currency: 'usd',
product_data: { name: item.title },
unit_amount: Math.round(item.price * 100), // cents
},
quantity: item.quantity,
}));
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: lineItems,
mode: 'payment',
success_url: `${process.env.HOST_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.HOST_URL}/checkout/cancel`,
metadata: { userId },
});
return { url: session.url };
});
The function checks context.auth.uid to ensure only verified users proceed, then constructs line items from the cart data. The unit_amount converts dollars to cents by multiplying by 100 and rounding.
Handling Checkout from React
In your cart component, invoke the Cloud Function using the Firebase SDK's httpsCallable method and redirect the user to Stripe:
import { httpsCallable } from 'firebase/functions';
import { functions } from './firebase'; // initialized Firebase app
async function goToCheckout(cart) {
const createCheckout = httpsCallable(functions, 'createCheckout');
const result = await createCheckout({ cartItems: cart, userId: auth.currentUser.uid });
window.location.href = result.data.url; // send user to Stripe
}
This pattern keeps sensitive operations off the client while providing a seamless redirect to the hosted payment page.
Processing Payment Confirmations with Webhooks
After the user completes payment, Stripe sends webhook events to your backend. Deploy a raw HTTP function to listen for checkout.session.completed events and update your Firestore database:
export const stripeWebhook = functions.https.onRequest(async (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.rawBody, sig, functions.config().stripe.webhook_secret);
} catch (err) {
return res.status(400).send(`Webhook Error: ${err.message}`);
}
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
const userId = session.metadata.userId;
// Mark order as paid in Firestore
await admin.firestore().collection('orders')
.doc(session.id).set({ userId, status: 'paid', ...session });
}
res.json({ received: true });
});
The webhook handler verifies the Stripe signature using the webhook secret stored in Firebase Functions configuration, then writes the order status to the orders collection.
Securing Your Marketplace
Protect user data with Firestore security rules. Configure firestore.rules to restrict read and write access so users can only interact with their own carts and order history:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /carts/{userId} {
allow read, write: if request.auth.uid == userId;
}
match /orders/{orderId} {
allow read: if request.auth.uid == resource.data.userId;
allow create: if request.auth.uid != null;
}
}
}
Deployment Strategy
Deploy your application using platform-specific workflows:
- Frontend: Deploy the React build to Vercel, Netlify, or Firebase Hosting for static asset serving.
- Backend: Deploy Cloud Functions and Firestore rules using the Firebase CLI (
firebase deploy).
Summary
- The GorvGoyl/Clone-Wars repository provides a React and Firebase foundation for building Amazon-style marketplaces, referenced at line 68 of the README.
- Stripe checkout sessions created in Firebase Cloud Functions keep payment credentials secure while handling complex cart calculations server-side.
- Firebase Authentication integration ensures only verified users can initiate checkout flows, preventing unauthorized payment attempts.
- Stripe webhooks provide the definitive source of truth for payment status, updating Firestore records only after confirmed successful transactions.
- Firestore security rules enforce data isolation, ensuring users access only their own cart and order data.
Frequently Asked Questions
How do I secure my Stripe secret keys in Firebase Functions?
Store sensitive credentials in Firebase Functions configuration using firebase functions:config:set stripe.secret="sk_live_..." and access them via functions.config().stripe.secret as shown in functions/src/stripe.ts. Never expose these keys in client-side code or version control according to the GorvGoyl/Clone-Wars implementation pattern.
Can I use PayPal instead of Stripe for payment integration?
Yes, though the Clone-Wars repository references Stripe. You would replace the createCheckout function with PayPal's SDK or REST API calls, storing the PayPal client credentials in Firebase Functions config and creating orders server-side before returning approval URLs to the React client.
How do I handle inventory management after a successful payment?
Extend the stripeWebhook function to decrement stock quantities in Firestore after receiving checkout.session.completed. Use Firestore transactions to ensure atomic updates between checking stock availability and confirming the order to prevent overselling in your Amazon clone.
Is Firebase sufficient for a high-traffic production marketplace?
Firebase scales automatically for most e-commerce applications, but consider the Firestore pricing model for high-volume read/write operations. For the Amazon clone architecture described in the GorvGoyl/Clone-Wars repository, Firebase handles authentication, database, and serverless functions efficiently up to millions of requests per month.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →