Skip to main content
The cart and checkout flow takes a customer from browsing the menu all the way to a completed Stripe payment. Cart state is held in memory via React Context and mirrored in MongoDB so that logged-in users never lose their basket between sessions. When the customer is ready to pay, a Stripe Checkout session is created on the backend and the user is redirected to Stripe’s hosted payment page.

How the Cart Works

Cart state lives in StoreContext as a plain object called cartItems. Each key is a food item’s _id and each value is the quantity currently in the basket:
When a user logs in, loadCartData syncs the server-side cart to this local map:

addToCart and removeFromCart

Both functions optimistically update local state first, then persist the change to the backend when a token is present.
Cart changes made by a guest (no token) are kept in memory only for the current browser session and are not persisted to the database.

Cart Page

The /cart route renders the Cart component, which lists every item where cartItems[item._id] > 0. For each row the component shows the item image, name, unit price, quantity, and line total. The × button calls removeFromCart. The Cart Totals panel at the bottom summarises:
Clicking PROCEED TO CHECKOUT navigates to /order. Unauthenticated users are redirected back to /cart, as are users who reach /order with an empty cart.

PlaceOrder Page

The /order route renders the PlaceOrder component. It presents a delivery address form alongside a final cost summary.
All fields are required.
Clicking PROCEED TO PAYMENT submits the form and calls the backend to create a Stripe session.

Stripe Payment Flow

1

POST /api/order/place

The frontend posts the full order payload — items, address, and amount — along with the auth token.The backend:
  1. Saves a new Order document to MongoDB with payment: false
  2. Clears the user’s cartData in the User document
  3. Builds a Stripe line_items array from the ordered items plus a Delivery Charges line item
  4. Creates a Stripe Checkout session and returns session_url
2

Redirect to Stripe

The frontend replaces the current page with the Stripe-hosted checkout URL:
Using replace removes the order page from browser history so the customer cannot navigate back to it after paying.
3

Stripe redirects back

After the customer completes or cancels payment, Stripe redirects to:
4

POST /api/order/verify

The Verify page immediately calls POST /api/order/verify with { success, orderId }.
  • success = “true” → sets payment: true on the order, then redirects to /myorders
  • success = “false” → deletes the order document, then redirects to /
All Stripe line items use the INR currency, as set in orderController.js. Prices are passed to Stripe in paise (price * 100).

Delivery Fee Line Item

The flat Rs.2 delivery charge is appended to the Stripe line_items array on the backend so it appears as a named line on the Stripe-hosted receipt: