# NEON KEY STORE — Installation Guide

## 1. Files
- `database.sql` — full MySQL schema + default settings
- `admin_panel.php` — complete admin backend + UI
- `user_panel.php` — complete user + reseller backend + UI (role auto-detected from session)

## 2. MySQL Setup
1. Create a MySQL database (e.g. `key_store`) and a MySQL user with full privileges on it.
2. Import `database.sql` via phpMyAdmin or:
   ```
   mysql -u YOUR_USER -p key_store < database.sql
   ```

## 3. PHP Configuration
Open **both** `admin_panel.php` and `user_panel.php` and edit the top config block in each:
```php
define('DB_HOST', 'localhost');
define('DB_NAME', 'key_store');
define('DB_USER', 'your_db_username');
define('DB_PASS', 'your_db_password');
```
Upload both files to your PHP 8+ hosting (InfinityFree, cPanel, XAMPP, etc). No Composer, no Node, no build step required.

## 4. Create the First Admin
Run this once via phpMyAdmin's SQL tab (replace email/password):
```sql
INSERT INTO users (name, email, password, role, status, balance)
VALUES ('Admin', 'admin@example.com', '$2y$10$REPLACE_WITH_A_REAL_HASH', 'admin', 'active', 0);
```
To generate the hash, run this PHP snippet once on your server (delete the file afterward):
```php
<?php echo password_hash('YourStrongPassword123', PASSWORD_DEFAULT);
```
Paste the resulting hash into the SQL above, then log in at `admin_panel.php` with your email/password.

## 5. Google Login Setup (optional)
1. Go to [Google Cloud Console](https://console.cloud.google.com/) → create a project.
2. Configure the OAuth consent screen.
3. Create OAuth 2.0 credentials → Web application.
4. Add your site's domain (e.g. `https://yourdomain.com`) as an **Authorized JavaScript origin**.
5. Copy the **Client ID** into Admin → Settings → Google Client ID, and enable Google Login.
6. Never expose the Client Secret — this app only needs the Client ID for the frontend `Google Identity Services` button; token verification happens server-side via Google's `tokeninfo` endpoint.

## 6. First-Time Configuration Checklist
1. Log in to `admin_panel.php`.
2. **Products** → Add your first product (name, banner, description).
3. **Plans** → Add plan(s) for that product (e.g. "1 Day", price for user & reseller).
4. **Key Inventory** → Add Key (single) or Bulk Import Keys (paste one key per line) for that product/plan.
5. Verify stock shows correctly under Key Inventory → Stock Summary.
6. Open `user_panel.php`, register a test user account.
7. Add wallet balance: submit a payment request as the user, then approve it from Admin → Payments.
8. Test a purchase from the Store — confirm a real key is assigned and stock decreases.
9. From the same test account, click **Request Reseller Access** (on the Home page).
10. Approve the request from Admin → Resellers → Pending Requests.
11. Log back in as that user — the UI now shows the Reseller Dashboard/Store/Inventory/Customers.
12. Buy wholesale inventory as the reseller, then sell a key to a customer email from **Inventory → Sell**.
13. Confirm the sale appears under **Customers** and **Dashboard profit stats**.
14. Try Admin → Settings → Maintenance Mode to confirm the maintenance screen displays correctly on `user_panel.php`.

## 7. Security Notes
- All prices, stock counts, and role checks are recalculated server-side on every request — nothing is trusted from the browser.
- Purchases use `SELECT ... FOR UPDATE` inside a MySQL transaction to lock and atomically assign keys, preventing two buyers from getting the same key.
- Passwords are hashed with `password_hash()`/`password_verify()`; sessions are regenerated on login; all state-changing requests require a CSRF token.
- No key is ever auto-generated — every `key_code` must be entered or bulk-imported by an admin, and `key_code` has a unique database constraint.

## 8. Deployment Notes
- Works on any standard PHP 8+ / MySQL shared hosting (InfinityFree, cPanel, XAMPP, Apache).
- No Node.js, npm, or Firebase involved anywhere in the stack.
- If you enable payment screenshot uploads, you'll need to add a standard PHP file-upload handler and store files in a writable folder — the `screenshot_url` field currently expects a URL (e.g. an image hosted externally or uploaded separately).
