# Project Plan: "Become Our Family" (Quotex Referral + Postback Verification)

**Stack:** PHP 8.x + MySQL (MariaDB) + HTML/CSS/JS (no heavy framework)
**Owner:** Shakibur / V1PER X CORPORATION
**Goal:** A website where visitors join "our family" through your Quotex referral link, and are automatically verified through Quotex postbacks (registration, email confirmation, first deposit, etc.).

---

## 1. Master Prompt (copy this into each build step)

> You are a senior PHP developer. Build a production-ready PHP 8 + MySQL web application called **"Become Our Family"**.
>
> **Purpose:** Visitors sign up on my site, are redirected to my Quotex affiliate link carrying a unique `click_id`, and are later verified automatically when Quotex sends server-to-server postbacks to my endpoint.
>
> **Requirements:**
> 1. Landing page with a signup form (name, email, phone/Telegram optional, password).
> 2. On signup, create the user, generate a unique `click_id`, store it, and show a "Register on Quotex" button that redirects to my referral link with `click_id` appended as the sub-ID parameter.
> 3. A postback endpoint at `/postback/{SECRET_KEY}` accepting GET and POST with params: `status`, `click_id`, `event_id`, `site_id`, `lid`, `trader_id`, `sumdep`.
> 4. Status mapping: `reg` = registered, `conf` = email confirmed, `ftd` = first deposit, `dep` = repeat deposit, `withdrawal` = withdrawal.
> 5. Idempotency: ignore duplicate `event_id`. Log every postback (raw payload, IP, result).
> 6. User dashboard showing verification progress (steps: Signed up, Registered on Quotex, Email confirmed, First deposit) and unlocking "Family" content only at the configured verified level.
> 7. Admin panel: login, user list with filters, postback log viewer, manual verify/reject, settings (referral URL, secret key, required verification level, allowed IPs), CSV export.
> 8. Security: prepared statements (PDO), password_hash, CSRF tokens, session hardening, rate limiting on signup/login, input validation, output escaping, HTTPS-only cookies, secret key in the postback path, optional IP whitelist.
> 9. Clean folder structure, `.env`-style config file outside the web root where possible, SQL install script, and a README with deployment steps.
> 10. Responsive modern UI, mobile first.
>
> Output complete files with paths, no placeholders.

---

## 2. System Overview

```
Visitor -> Landing page -> Signup form
        -> Server creates user + click_id
        -> Redirect to Quotex referral link (?click_id=XXXX)
        -> User registers / deposits on Quotex
        -> Quotex sends POSTBACK to /postback/{SECRET}
        -> Server matches click_id -> updates user status
        -> User dashboard shows verified progress / unlocks content
```

---

## 3. Folder Structure

```
/family-site
 |-- /public              (web root)
 |    |-- index.php       (landing page)
 |    |-- signup.php
 |    |-- login.php
 |    |-- logout.php
 |    |-- go.php          (tracking redirect to Quotex)
 |    |-- dashboard.php
 |    |-- postback.php    (routed from /postback/{SECRET})
 |    |-- /admin
 |    |    |-- index.php, users.php, postbacks.php, settings.php, export.php
 |    |-- /assets (css, js, img)
 |-- /app
 |    |-- config.php
 |    |-- db.php
 |    |-- auth.php
 |    |-- helpers.php     (csrf, validation, escaping)
 |    |-- postback_handler.php
 |    |-- ratelimit.php
 |-- /sql
 |    |-- install.sql
 |-- .htaccess
 |-- README.md
```

---

## 4. Database Design

### `users`
| Column | Type | Notes |
|---|---|---|
| id | INT PK AI | |
| name | VARCHAR(100) | |
| email | VARCHAR(150) UNIQUE | |
| contact | VARCHAR(100) NULL | Telegram / phone |
| password_hash | VARCHAR(255) | |
| click_id | CHAR(32) UNIQUE | random, generated at signup |
| trader_id | VARCHAR(50) NULL | filled by postback or manually |
| qx_status | ENUM('none','reg','conf','ftd','dep') | highest status reached |
| total_deposit | DECIMAL(12,2) | sum of `sumdep` |
| is_verified | TINYINT | based on required level |
| verified_at | DATETIME NULL | |
| created_at | DATETIME | |

### `postback_events`
| Column | Type | Notes |
|---|---|---|
| id | INT PK AI | |
| event_id | VARCHAR(100) UNIQUE NULL | dedupe key |
| click_id | VARCHAR(64) | |
| status | VARCHAR(30) | |
| trader_id | VARCHAR(50) NULL | |
| sumdep | DECIMAL(12,2) | |
| raw_payload | TEXT | full request |
| ip | VARCHAR(45) | |
| result | VARCHAR(30) | matched / no_match / duplicate / rejected |
| created_at | DATETIME | |

### `clicks`
| Column | Type | Notes |
|---|---|---|
| id | INT PK AI | |
| user_id | INT FK | |
| click_id | CHAR(32) | |
| ip, user_agent | | |
| created_at | DATETIME | |

### `admins`
id, username, password_hash, created_at

### `settings`
key (PK), value. Keys: `referral_url`, `click_param_name`, `postback_secret`, `required_level`, `allowed_ips`.

### `login_attempts`
ip, identifier, attempted_at (for rate limiting)

---

## 5. Core Algorithms

### 5.1 Signup
```
1. Validate input (name, email format, password length >= 8)
2. Check rate limit for IP (e.g. 5 signups / hour)
3. Verify CSRF token
4. If email exists -> error
5. click_id = bin2hex(random_bytes(16))
6. INSERT user (password_hash, click_id, qx_status='none')
7. Start session, redirect to dashboard
```

### 5.2 Tracking Redirect (`go.php`)
```
1. Require logged-in user
2. Load referral_url and click_param_name from settings
3. Log row in `clicks`
4. Build URL: referral_url + (has '?' ? '&' : '?') + param=click_id
5. 302 redirect
```

### 5.3 Postback Handler
```
1. Verify path secret == settings.postback_secret   else 403
2. If allowed_ips set and client IP not in list     else 403
3. Read params from $_REQUEST (GET or POST)
4. Validate: status and click_id required           else 400
5. Log raw payload in postback_events (result='received')
6. If event_id present and already exists           -> result='duplicate', return 200 "OK"
7. Find user by click_id                            -> none: result='no_match', return 200 "OK"
8. Map status:
     reg  -> level 1
     conf -> level 2
     ftd  -> level 3
     dep  -> level 4 (add sumdep to total_deposit)
     withdrawal -> record only
9. Update user: qx_status = MAX(current level, new level), trader_id if provided
10. If new level >= required_level and not verified -> is_verified=1, verified_at=NOW()
11. Update event result='matched'; return 200 "OK"
```
Rules: never downgrade status; always respond 200 quickly so Quotex does not keep retrying; wrap in a DB transaction.

### 5.4 Trader ID Fallback (if sub-ID cannot be passed)
```
1. User enters their Trader ID in dashboard
2. Save as pending_trader_id
3. When postback arrives with the same trader_id (no/unknown click_id) -> match by trader_id
4. Admin can also manually approve
```

### 5.5 Dashboard Access Control
```
if user.is_verified: show Family content
else: show progress steps + next-action button
```

### 5.6 Admin Actions
- Filter users by status, search by email / trader_id
- View postback log with result and raw payload
- Manual verify / reject, edit trader_id
- Edit settings; export CSV

---

## 6. Security Checklist

- [ ] PDO prepared statements everywhere
- [ ] `password_hash` / `password_verify`
- [ ] CSRF token on all forms
- [ ] `session.cookie_httponly`, `secure`, `samesite=Lax`; regenerate ID on login
- [ ] Output escaping with `htmlspecialchars`
- [ ] Rate limiting for login and signup
- [ ] Long random postback secret; optional IP whitelist
- [ ] HTTPS enforced via `.htaccess`
- [ ] Config and `/app` outside web root or blocked
- [ ] Postback log retention policy
- [ ] Admin panel on a non-obvious path with separate login

---

## 7. Build Phases

| Phase | Deliverable |
|---|---|
| 1 | Project skeleton, config, DB install script, helpers |
| 2 | Landing page, signup, login, session security |
| 3 | `go.php` tracking and redirect to Quotex link |
| 4 | Postback endpoint, logging, dedupe, status mapping |
| 5 | User dashboard with verification progress |
| 6 | Admin panel (users, logs, settings, export) |
| 7 | Hardening: rate limits, IP whitelist, error handling |
| 8 | Testing and deployment (HTTPS, cron cleanup, README) |

---

## 8. Testing Plan

1. Open the postback URL manually with test params, confirm DB update.
2. Send the same `event_id` twice, confirm the duplicate is ignored.
3. Send an unknown `click_id`, confirm it logs `no_match`.
4. Send a wrong secret, confirm 403.
5. Run a real test registration through the referral link and confirm `reg` arrives.
6. Test all statuses in order: reg, conf, ftd, dep.
7. Confirm status never downgrades.

---

## 9. Open Questions (to answer before Phase 1)

1. Does the Quotex **Links** page accept a sub-ID / click_id parameter? What is its name?
2. Which status counts as "verified": reg, conf, or ftd?
3. What does "Family" unlock (Telegram invite, content page, badge)?
4. Hosting type (shared, VPS) and domain with HTTPS?
5. Brand name, colors, and logo for the UI?
6. Languages needed (English, Bengali)?

---

## 10. Compliance Notes

- Read the Quotex affiliate agreement before launch (allowed promotion methods, banned claims).
- Do not publish guaranteed-profit claims or fake testimonials.
- Check legal restrictions on promoting binary options in your country and your audience's countries.
- Add a Privacy Policy and Terms page, and a risk warning on the landing page.
