Sri

SSQUARE ELITE — Guest Checkout + Admin Product Management

This project keeps the existing SSQUARE ELITE/ToyLand storefront design and adds the requested guest shopping flow, admin authentication, MySQL-backed product management, delivery rules and UPI checkout.

Customer flow

Customers do not create an account and do not log in.

Store → Add to Cart → Cart → Checkout → Customer Details
     → Delivery Calculation → Order Summary → UPI Payment → Order Confirmation

Delivery rules

The server recalculates the subtotal, stock and delivery amount from the MySQL product catalogue, so the final amount is not trusted from the browser.

Payment

Only UPI is offered.

UPI ID: sriram170620@okaxis

The app builds a dynamic upi://pay request using the final order amount and also displays a QR code. The QR image is generated from that UPI URI by the QR image service used in the frontend.

The application intentionally does not mark an order as paid when the customer only opens the UPI payment page. The order becomes paid/placed only after the customer confirms payment. A real UPI payment-verification gateway/webhook would be required for automatic server-side verification.

Admin

Admin login: /admin-login.html

The dashboard can:

Product data is stored in MySQL and is therefore persistent across page refreshes and server restarts. New products automatically appear on the customer store because the store reads the product catalogue from /api/products.

Admin credentials

For local development, set these in .env:

ADMIN_NAME=SSQUARE ELITE Admin
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=replace_with_a_strong_password
JWT_SECRET=replace_with_a_long_random_secret

When ADMIN_EMAIL and ADMIN_PASSWORD are set, startup creates or updates that account as an admin. Passwords are stored as bcrypt hashes in MySQL.

You can also create/update an admin from a machine that can reach the database:

node scripts/make-admin.js admin@example.com "StrongPassword123!" "Store Admin"

Installation

npm install

Create .env from .env.example and fill in the MySQL credentials.

Then run:

npm start

Development mode:

npm run dev

Open:

http://localhost:3000/

Admin:

http://localhost:3000/admin-login.html

GoDaddy Node.js Hosting

GoDaddy’s managed MySQL environment supplies:

DB_HOST
DB_PORT
DB_NAME
DB_USER
DB_PASSWORD

Add these application secrets yourself:

CLIENT_URL=https://ssquareelite.online
JWT_SECRET=<long random secret>
ADMIN_JWT_EXPIRES_IN=8h
ADMIN_NAME=SSQUARE ELITE Admin
ADMIN_EMAIL=<your admin email>
ADMIN_PASSWORD=<strong admin password>

Restart the app after changing secrets.

The server automatically creates the MySQL tables and seeds starter products only when the products table is empty.

Project structure

Sri-main/
├── server.js
├── app.js
├── package.json
├── package-lock.json
├── config/
│   └── db.js
├── middleware/
│   └── auth.js
├── models/
│   ├── User.js
│   ├── Product.js
│   └── Order.js
├── routes/
│   ├── admin-auth.js
│   ├── admin.js
│   ├── checkout.js
│   └── products.js
├── scripts/
│   ├── make-admin.js
│   ├── seed.js
│   └── seed-data.js
└── public/
    ├── index.html
    ├── admin-login.html
    ├── admin.html
    ├── success.html
    ├── js/app.js
    ├── css/style.css
    └── img/uploads/

WhatsApp

Customer help opens:

https://wa.me/918072894491?text=Hi%2C%20I%20have%20a%20question%20regarding%20my%20order%2Fproduct.

Number: 8072894491

Important security notes

Admin login troubleshooting

If the admin login says it is not working, check these values in the hosting application’s Environment Variables (not only in .env.example):

ADMIN_USERNAME=admin
ADMIN_EMAIL=your-real-admin-email@example.com
ADMIN_PASSWORD=your-strong-password
JWT_SECRET=a-random-secret-at-least-32-characters-long

After changing any of these values, restart/redeploy the Node.js application. The server will create or update the configured admin account automatically.

You can check the application without exposing secrets:

https://your-domain.com/health
https://your-domain.com/api/admin/auth/status

/health should return ok: true. The admin status endpoint should show adminBootstrapConfigured: true and jwtConfigured: true.

The admin login accepts either the configured ADMIN_USERNAME or the configured ADMIN_EMAIL.

Category filtering and WhatsApp orders

The eight category cards now filter products by category and scroll to the filtered product list. Existing starter products are migrated to the matching categories on startup.

UPI is still a manual payment method. A UPI QR/deep link does not provide a reliable server-side payment-success callback, so the success page has an I Have Paid — Confirm Order button. That action confirms the order, reduces stock, marks it paid, and triggers WhatsApp notifications.

WhatsApp Cloud API setup

Set these environment variables in GoDaddy:

WHATSAPP_GRAPH_VERSION=vXX.X
WHATSAPP_ACCESS_TOKEN=...
WHATSAPP_PHONE_NUMBER_ID=...
WHATSAPP_ADMIN_TO=919344714369
WHATSAPP_TEMPLATE_LANG=en_US
WHATSAPP_ADMIN_TEMPLATE=...
WHATSAPP_CUSTOMER_TEMPLATE=...

The system sends the paid order to 9344714369, including customer details, item names/quantities, total and publicly hosted product images when available. It also sends the customer a bill message to the mobile number entered at checkout and includes a bill URL.

Meta may require an approved WhatsApp message template for business-initiated messages outside the customer-service window. Configure the optional admin/customer template names above if free-form messages are rejected.

Updated checkout / category flow

Important UPI note

A plain UPI deep link/QR does not provide this Node.js app with automatic bank-side payment verification. The current flow therefore confirms the order only after the customer taps I Have Paid — Confirm Order. For automatic verification, replace this confirmation step with a payment gateway such as Razorpay/PhonePe/PayU and its server-side webhook.

WhatsApp Cloud API

For business-initiated WhatsApp messages, Meta may require approved message templates. Set WHATSAPP_ADMIN_TEMPLATE and WHATSAPP_CUSTOMER_TEMPLATE to approved template names when free-form messages are rejected. The customer receipt document also requires the public CLIENT_URL to be HTTPS and reachable by Meta.