Introduction

Last updated: June 2026

Thank you for choosing PrizeX by WowCodes! PrizeX is a full-featured PHP + MySQL prize platform supporting auctions, lotteries, mystery boxes, a shop, games, investments, and a companion mobile API — all from one codebase.

If you run into any issues, contact our support team at hello@wowcodes.in or via WhatsApp. We appreciate your purchase.

What's new in this build: Credentials moved to .env, HTTP security headers, CSRF protection, login rate limiting, Server-Sent Events for live auction bids, async email job queue, CDN-ready asset helper, optional Redis sessions, PHPStan + PHPUnit + GitHub Actions CI, and structured JSON logging via Monolog.

Installation

Server Requirements

PrizeX is tested for Apache-based PHP hosting with MySQL. Minimum requirements:

  • PHP 8.3 or higher (8.3.30 fully supported)
  • MySQL 8.0+ or MariaDB 10.6+
  • Composer 2.x
  • PHP extensions: mysqli, gd, mbstring, curl, openssl, fileinfo, json, zip
  • Optional (for Redis sessions): php-redis extension

Verify installed extensions: php -m | grep -E "mysqli|gd|mbstring|curl|openssl"

Can be installed on a subdomain like app.yourdomain.com or your root domain. cPanel and hPanel hosting are the easiest environments for non-technical setup.

Upload Files

  • Open your hosting panel and go to File Manager.
  • Navigate to your domain or subdomain's root directory.
  • Upload the Website.zip downloaded from CodeCanyon.
  • Right-click the zip and choose Extract. The Website/ contents should be at the web root, not inside a sub-folder.
CSS and images won't load if files are at yourdomain.com/Website/ instead of yourdomain.com/. Make sure you extract directly into the domain root.

Create & Import Database

  • In cPanel go to MySQL Database Wizard. Create a database, a user, and grant All Privileges.
  • Open phpMyAdmin, select the new database, click the Import tab, and upload one of:
    • database/sandbox.sql — clean install, no sample data
    • database/production.sql — includes sample users, auctions, orders, and coins for a live demo

Import one SQL file only for a fresh install. Use sandbox.sql for a clean start or production.sql for demo/sample data.

Configure .env Changed

Database credentials and all environment-specific settings are stored in a .env file at the project root — never hardcoded into PHP files.

  1. Copy the template: cp .env.example .env
  2. Open .env and fill in your database credentials:
DB_HOST=localhost
DB_NAME=your_database_name
DB_USER=your_database_user
DB_PASSWORD=your_database_password
One file connects everything. The same .env is read by the website, admin panel, API, and all payment gateways — you only update it in one place.
Never commit .env to Git. It is listed in .gitignore by default. Use .env.example as the safe template to share with your team.

Install Composer Dependencies

PrizeX uses Composer to manage PHP libraries (payment SDKs, PHPMailer, phpdotenv, QR code, Stripe, etc.).

cd /path/to/Website
composer install --no-dev --optimize-autoloader

This creates the vendor/ directory. If it already exists in the zip, run composer install anyway to ensure everything is up to date.

If composer is not found on your server, install it globally: brew install composer (macOS) or follow getcomposer.org.

Start the Server

Production (Apache): Point your document root to the Website/ directory. The bundled .htaccess handles pretty URLs automatically.

Local development: Use PHP's built-in server with the provided router:

php -S localhost:8000 router.php

Open http://localhost:8000 in your browser. Admin panel is at http://localhost:8000/admin.

Default admin credentials are in the tbl_admin table (password is hashed with bcrypt).

Environment Configuration

All runtime configuration lives in the .env file. This section covers every available variable and optional features that can be toggled by setting them.

.env Reference

Copy .env.example to .env and fill in the values relevant to your setup. All optional variables can be left blank to use the default behaviour.

# ── Database (required) ──────────────────────────────────────
DB_HOST=localhost
DB_NAME=your_database_name
DB_USER=your_database_user
DB_PASSWORD=your_database_password

# ── Application ───────────────────────────────────────────────
APP_ENV=production          # or: development

# ── Tailwind CSS ──────────────────────────────────────────────
# Set to 1 after running: npm run build:css
# Leave empty to use the CDN fallback (no build step needed)
APP_TAILWIND_BUILD=

# ── CDN (optional) ────────────────────────────────────────────
# All asset() calls prefix this URL.  Leave empty for root-relative paths.
APP_CDN_URL=

# ── Redis sessions (optional) ─────────────────────────────────
REDIS_SESSION=             # Set to 1 to enable
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_SESSION_TTL=86400

# ── Logging ───────────────────────────────────────────────────
LOG_LEVEL=info              # debug | info | warning | error

Tailwind CSS Build New

By default, PrizeX loads Tailwind from the CDN — no build step required. For production deployments, compiling a single minified CSS file eliminates the ~350 KB CDN script and removes the runtime JIT overhead.

  1. Install Node.js 18+ and run: npm install
  2. Build once: npm run build:css — generates assets/css/app.css
  3. Set APP_TAILWIND_BUILD=1 in your .env
  4. For live reload during development: npm run watch
The compiled assets/css/app.css is excluded from Git (.gitignore). Run the build step as part of your deployment pipeline (see GitHub Actions CI section).

CDN Setup New

All static asset references in PHP files use the asset() helper. When APP_CDN_URL is set in .env, every asset('images/logo.png') call automatically becomes https://cdn.yourdomain.com/images/logo.png.

# .env
APP_CDN_URL=https://your-cdn-domain.com

To migrate assets to a CDN (Cloudflare R2, AWS S3 + CloudFront, or similar):

  1. Upload /assets/, /images/, and /games/ directories to your CDN bucket.
  2. Set APP_CDN_URL to your CDN base URL.
  3. Configure your CDN to serve with proper Cache-Control headers (e.g., max-age=31536000 for versioned assets).

Redis Sessions New

By default, PHP stores sessions on the local filesystem. This breaks when you run multiple servers behind a load balancer (each server would have different session files). Redis-backed sessions solve this by storing all sessions in a shared in-memory store.

To enable:

  1. Install the php-redis extension on your server.
  2. Ensure a Redis instance is reachable.
  3. Set in .env:
REDIS_SESSION=1
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=yourpassword   # leave empty if no auth
REDIS_SESSION_TTL=86400       # 1 day in seconds

If Redis is unavailable or the extension is not loaded, the app silently falls back to file-based sessions — no downtime.

Security

PrizeX ships with a layered security model active by default. This section explains each layer so you understand what's in place and how to configure it.

HTTP Security Headers

Every response — including API calls and AJAX endpoints — automatically includes the following headers via includes/security_headers.php:

  • X-Frame-Options: SAMEORIGIN — prevents clickjacking
  • X-Content-Type-Options: nosniff — stops MIME-type sniffing
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy — disables camera, microphone, geolocation, payment APIs
  • Strict-Transport-Security — enforces HTTPS (sent only when HTTPS is detected)
  • Content-Security-Policy — restricts script/style/font sources to known CDN domains
  • X-Powered-By should be removed to avoid exposing PHP version details (set expose_php=Off in php.ini)
No configuration is needed — headers are sent on every request automatically. To tighten the CSP as you migrate away from CDN-loaded scripts, edit includes/security_headers.php.

CSRF Protection

Every state-changing form and AJAX request is protected against Cross-Site Request Forgery via includes/csrf.php:

  • A unique per-session token is generated and verified on every POST request.
  • HTML forms include a hidden csrf_token field automatically injected in the header.
  • AJAX requests must include the token as an X-CSRF-Token header (auto-attached by the fetch wrapper in the frontend).
  • On a token mismatch, the server returns 403 Forbidden — or for AJAX, a JSON error.
If you see "Invalid CSRF token" errors after login, clear your browser cookies and log in again to get a fresh token. This commonly happens when testing with multiple tabs or browser profiles.

Rate Limiting New

IP-based rate limiting is applied to authentication endpoints to prevent brute-force attacks:

  • Login: 5 attempts per 15 minutes. Exceeded attempts redirect back to the login page with an error.
  • Registration: 3 attempts per hour.
  • Rate limit counters are stored in tbl_rate_limits (auto-created on first use — no migration needed).
  • Counters are cleared automatically on successful authentication.

The helper is in includes/rate_limiter.php and can be applied to any endpoint by calling rate_limit_check($mysqli, 'action_name', $max, $window_seconds).

Auth Guard New

Route-level authentication is enforced by includes/auth_guard.php, loaded on every page via includes/header.php. It replaces per-page session_check.php includes with a single centralised whitelist.

  • Public routes (home, auctions listing, login, register, etc.) are explicitly whitelisted — guests can access them freely.
  • Any route not on the whitelist requires a valid session.
  • Unauthenticated users are redirected to /login?redirect=<original URL>.
  • AJAX requests from unauthenticated users receive a 401 JSON response instead of an HTML redirect.
  • "Remember me" cookie is checked before bouncing a guest — if valid, the session is restored automatically.

User Side

PrizeX is a mobile-first PWA (Progressive Web App). Users get an app-like experience on any smartphone without downloading anything from an app store.

Registration & Login

  • Sign up with Google, Facebook, or Apple SSO — one tap, no password needed.
  • Or register with email/phone + password (minimum 6 characters; email format is validated server-side).
  • Login is rate-limited: 5 failed attempts per 15 minutes triggers a temporary lock.
  • Open redirect protection is active — post-login redirects are sanitised to same-origin paths only.
  • "Remember me" sets a secure, HttpOnly cookie valid for the configured session lifetime (default: 1 day).

Recharge Wallet

Users can add coins to their wallet using any configured payment method:

  • Online gateways — Stripe, Razorpay, PayPal, and 30+ others (see Payment Setup)
  • Manual payment — UPI, bank transfer, QR code; admin verifies and approves
  • Gift voucher — redeem a code for instant coin credit

Wallet operations use atomic SQL updates (SET wallet = wallet - ? WHERE wallet >= ?) to prevent race conditions and double-spending across concurrent bids or purchases.

Gift Voucher

From the Gift Voucher section users enter a voucher code. If valid and active, coins are credited to their wallet immediately.

Refer & Earn

  • Each user gets a unique referral code visible on the /refer page.
  • When a referred user registers, the referrer receives coins (amount configured in Admin → Referral Settings).

View Transactions

  • Full transaction history at /my-transactions — type, amount, timestamp, and status.
  • Credits shown in green, debits in red for instant visual clarity.
  • Auction bids, ticket purchases, winnings, and wallet recharges all appear here.

Manage Profile

  • Edit name, profile photo, phone, and address from /edit-profile.
  • Name cannot be left empty; password changes require a minimum of 6 characters.
  • Delivery addresses managed separately at /address.

PWA & Install Prompt

  • PrizeX registers a service worker (service-worker.js) for offline caching and push notification support.
  • A manifest.json enables "Add to Home Screen" on Android (standard Web App Manifest banner).
  • iOS users see a custom install instruction sheet (since iOS doesn't support the standard Web App Manifest install prompt).
  • Dark mode is supported via Tailwind's class strategy with a FOUC-prevention inline script. User preference is persisted in localStorage.
  • RTL layout is applied automatically for Arabic, Hebrew, Persian, Urdu, and 3 other RTL languages via dir="rtl" on the <html> tag.

Live Features

PrizeX uses Server-Sent Events (SSE) to push real-time updates to the browser — no page refresh needed.

Live Auction Streaming New

The auction detail page (/auction/{slug}) shows the live current bid and winning user in real time. This is powered by ajax/auction_stream.php, a Server-Sent Events endpoint.

How it works:

  • When a user opens an auction, the browser opens one persistent HTTP connection to the SSE endpoint.
  • The server polls the database every 5 seconds and only sends an event when the bid or winner changes — so zero bandwidth is wasted when nothing changes.
  • A keepalive comment is sent every 30 seconds to keep the connection alive through proxies.
  • The connection is recycled every 5 minutes to prevent stale state.
  • If SSE is unavailable (rare legacy environments), the page automatically falls back to the previous 5-second polling behaviour.

Apache note: SSE works out of the box on Apache in most environments. If you are behind reverse proxies/CDN, disable response buffering for this endpoint so events stream immediately.

# Apache example for SSE endpoint
<Location "/ajax/auction_stream.php">
    Header set Cache-Control "no-cache"
</Location>

Admin Panel

The admin panel is at /admin. It provides full control over users, products, payments, content, and platform settings. Admin sessions expire after 24 hours.

Manage Users

  • Search by name, email, or phone.
  • View wallet balance, total bids, and transaction history per user.
  • Block, unblock, or delete user accounts.
  • Manually credit or debit coins from a user's wallet.

Manage Sellers

  • Approve or reject seller applications submitted via /become-seller.
  • View seller-specific wallet and earnings.
  • Sellers can list items for the Shop and manage their own orders.

Wallet Recharge

  • Define coin packages — the amount of coins a user gets per payment.
  • Set bonus coins for larger recharge amounts to incentivise top-ups.
  • Each package can be enabled or disabled independently.

Email Campaigns New

  • Create and schedule bulk email campaigns from the admin panel.
  • Target all users, a specific group, or individual users.
  • Emails are dispatched asynchronously via the job queue — the campaign cron enqueues individual sends, and the queue worker processes them in the background.
  • Per-recipient tracking: open tracking via pixel, sent/failed counts updated in real time.
  • Supports template variables: {{user_name}}, {{user_email}}, {{site_name}}, {{site_url}}.

Manage Orders

  • View all shop orders with user, item, quantity, and payment status.
  • Approve or reject manual payment submissions with screenshot evidence.
  • Track payment gateway responses and mark orders dispatched.

App Settings

  • App name, logo (light and dark variants), favicon, and currency symbol.
  • Timezone, default language, and maintenance mode toggle.
  • Mobile app download links (iOS / Android) shown on the home page.
  • Feature toggles: Games (beta), Invest, Flash Sales, Mystery Boxes.

Payment Gateway Details

  • Enable or disable any of the 35+ supported gateways individually.
  • Enter API keys, secrets, and webhook URLs for each gateway.
  • Test mode vs live mode toggle per gateway.
  • Only enabled gateways appear in the user recharge flow.

Referral Settings

  • Set the number of coins rewarded to the referrer on each successful signup.
  • Optionally reward the newly registered user too (welcome bonus).

Privacy Policy & Legal Pages

Edit Privacy Policy, Terms of Service, Cookie Policy, and Cancellation Policy directly from Admin → Settings. Content is stored in the database and rendered at /privacy, /terms, /cookie, /cancellation.

Social Login Setup

PrizeX supports one-tap login with Google, Facebook, and Apple. Once configured in Admin → Settings → APIs, each provider adds a button to the login and registration pages. OAuth state validation (CSRF) and open-redirect protection are active on all three flows.

Google Login Setup

  1. Go to Google Cloud Console and create a project.
  2. Enable the OAuth 2.0 consent screen and configure scopes (email, profile).
  3. Create credentials → OAuth Client ID → Web application.
  4. Add the redirect URI: https://yourdomain.com/sso-login/google.php
  5. Copy the Client ID and Client Secret into Admin → Settings → 🔐 APIs.

Troubleshooting: Ensure your domain is verified and the redirect URI matches exactly (no trailing slash difference).

Facebook Login Setup

  1. Go to Facebook Developer Portal and create an App.
  2. Add Facebook Login product → Settings.
  3. Add your domain to App Domains.
  4. Set redirect URI: https://yourdomain.com/sso-login/facebook.php
  5. Copy the App ID and App Secret into Admin → Settings → 🔐 APIs.

Troubleshooting: The app must be in Live mode (not Development) for non-admin users to log in.

Apple Login Setup

  1. Log into your Apple Developer Account.
  2. Create a Services ID (this is the client_id) and enable Sign In with Apple.
  3. Generate an Auth Key (.p8 file) and note the Key ID and Team ID.
  4. Add redirect URI: https://yourdomain.com/sso-login/apple.php
  5. Store credentials in tbl_credentials:
    • client_id — your Services ID
    • team_id — your Apple Team ID
    • key_id — the Auth Key ID
    • private_key — contents of the .p8 file
Apple only returns the user's name on the very first login. PrizeX saves it immediately. Ensure your redirect URI is registered under the Services ID — not just the App ID.
Apple JWT tokens are verified against Apple's public keys (RS256) — the previous alg: none bypass vulnerability is patched.

Payment Setup

PrizeX supports 35+ payment gateways. Enable, disable, and configure each from Admin → Settings → Payment Gateway. API keys and secrets are stored in the database — never hardcoded.

Overview

  • Each gateway has an enable/disable toggle in the admin panel.
  • All payment amounts are validated server-side against the expected value — client-side amount tampering is blocked.
  • Payment status updates use the correct paid_at column (a bug affecting 28 gateway files that caused silent payment failures has been fixed).
  • Manual payment methods (QR, UPI, bank transfer) require admin approval before coins are credited.

Manual Gateways

  • PayTM QR (Manual)
  • UPI (Manual)
  • Bank Transfer (Manual)
  • Cashmaal

Users submit payment proof (screenshot or transaction ID). Admins review from the Manual Payments section and approve or reject.

Indian Payment Gateways

  • Razorpay
  • Paytm Gateway
  • Instamojo
  • PayU
  • Amazon Pay
  • Cashfree
  • Aamarpay

For each, obtain your Merchant ID, API Key, and Secret from the gateway dashboard and enter them in Admin → Payment Settings.

International Gateways

  • Stripe
  • PayPal
  • 2Checkout
  • Authorize.Net
  • Braintree
  • BlueSnap
  • Checkout.com
  • GoCardless
  • Mollie
  • Mercado Pago
  • OpenPix
  • Midtrans
  • Paystack
  • Flutterwave
  • Payeer
  • Wise
  • NMI

Crypto Gateways

  • NOWPayments
  • MoonPay
  • Coinbase Commerce
  • Blockchain.com
  • Binance Pay
  • CoinGate
  • CoinPayments

These require wallet addresses or API credentials from the respective platforms. Most accept multiple cryptocurrencies.

Wallet-Based & Regional Options

  • Venmo
  • M-Pesa (Kenya)
  • Nagad (Bangladesh)
  • bKash (Bangladesh)
  • Skrill
  • SSLCommerz

Test the complete payment flow before going live — especially for region-specific gateways that may have currency or country restrictions.

Integration Notes

  • Set your base currency in Admin → App Settings before enabling gateways — many gateways reject requests in unsupported currencies.
  • To add a new gateway not in the list, contact WowCodes support.
  • Stripe payment amounts are validated server-side against the expected amount to prevent client-side price tampering.

REST API

PrizeX exposes a REST API at /api/v1/ consumed by the companion mobile app. All responses are JSON.

Overview

  • Base URL: https://yourdomain.com/api/v1/
  • All responses return Content-Type: application/json.
  • Error responses follow the shape: {"status": "error", "message": "...", "code": "..."}.
  • Success responses include {"status": "success", "data": {...}}.

Authentication (JWT)

The API uses stateless JWT bearer tokens. No session cookies are used for API requests.

  1. Call POST /api/v1/auth/login with {"email": "...", "password": "..."}.
  2. The response includes a short-lived access token (7 days) and a refresh token (30 days).
  3. Pass the access token in subsequent requests: Authorization: Bearer <token>
  4. When the access token expires, call POST /api/v1/auth/refresh with the refresh token to get a new pair.
# Login
curl -X POST https://yourdomain.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"yourpassword"}'

# Authenticated request
curl https://yourdomain.com/api/v1/user/profile \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
The JWT secret is auto-generated per installation and stored in tbl_settings.jwt_secret. It is never hardcoded in source code.

Available Endpoints

Controllers live in api/v1/controllers/:

  • auth — login, register, forgot password, refresh token
  • user — profile, edit profile, wallet balance
  • auctions — list, detail, bid placement
  • bids — user bid history
  • lotteries — list, detail, ticket purchase
  • mystery_boxes — list, open
  • shop — item list, detail, order placement
  • wallet — recharge, transactions
  • investments — available plans, user investments
  • withdrawals — request, history
  • winners — recent winners feed
  • notifications — list, mark read
  • referral — referral code, referred users
  • support — open ticket, list tickets
  • search — cross-entity search
  • app — general settings (currency, features, maintenance mode)

OpenAPI Documentation New

API controllers are annotated with OpenAPI 3.0 attributes (via zircote/swagger-php). Generate a machine-readable spec:

# Install dev dependencies first
composer install

# Generate the OpenAPI spec
vendor/bin/openapi api/v1 -o docs/openapi.json --format json

The generated docs/openapi.json can be imported into Postman, Insomnia, or viewed in Swagger UI. The CI/CD pipeline generates it automatically on every push to main.

Live Chat Setup

PrizeX integrates with tawk.to for free real-time customer support chat.

Tutorial

  1. Visit tawk.to and create a free account.
  2. Click Administration ⚙️ in the left sidebar.
  3. Under Property Settings, copy your Property ID.
  4. Go to Chat Widget and copy the Widget ID.
  5. In your admin panel, go to Settings → 🔐 API tab.
  6. Scroll to Tawk.to Live Chat and paste the Property ID in Client ID and Widget ID in Client Secret.
  7. Save. The chat bubble will appear on your website immediately.

✅ Test by visiting your support page and confirming the chat bubble appears at the bottom right.

Cron Jobs

Background tasks (winner declaration, investment interest, email dispatch, push notifications) are run by cron scripts in the cron/ directory. Set these up on your server after installation.

All Cron Scripts

Add these lines to your crontab (crontab -e on SSH, or via cPanel Cron Jobs):

# Declare auction winners — every minute
* * * * * /usr/bin/php /path/to/Website/cron/declare_auction-winner.php >> /dev/null 2>&1

# Declare lottery winners — every minute
* * * * * /usr/bin/php /path/to/Website/cron/declare_lottery-winner.php >> /dev/null 2>&1

# Investment interest calculation — every hour
0 * * * * /usr/bin/php /path/to/Website/cron/investment_interest.php >> /dev/null 2>&1

# Email campaign dispatcher — every 5 minutes
*/5 * * * * /usr/bin/php /path/to/Website/cron/email_campaign.php >> /dev/null 2>&1

# Notify users when an auction they follow starts — every minute
* * * * * /usr/bin/php /path/to/Website/cron/notify_auction_start.php >> /dev/null 2>&1

# Job queue worker (see below) — every minute
* * * * * /usr/bin/php /path/to/Website/cron/process_queue.php >> /dev/null 2>&1
Replace /usr/bin/php with the correct PHP binary path for your server. Run which php via SSH to find it. On cPanel, it's often /usr/local/bin/php.

Job Queue Worker New

The job queue (includes/JobQueue.php) decouples slow background work from the cron scripts that schedule it. Instead of email_campaign.php blocking on SMTP for every recipient in a single run, it enqueues individual email jobs and exits immediately. The queue worker then processes them on the next minute tick.

Worker features:

  • Row-level locking prevents two simultaneous cron runs from processing the same job.
  • Failed jobs are automatically retried with exponential back-off (2attempt minutes).
  • Jobs that exceed their retry limit are marked failed (not deleted) for investigation.
  • Old done/failed records are pruned automatically (randomly ~2% of runs, older than 14 days).

Current job types handled by the worker:

  • send_email — dispatched by email_campaign.php for each recipient
  • notify_push — dispatched for push notification delivery

To dispatch a custom job from any PHP file:

require_once __DIR__ . '/includes/JobQueue.php';

JobQueue::dispatch($mysqli, 'send_email', [
    'recipient_id' => 42,
    'to'           => 'user@example.com',
    'subject'      => 'Your prize is waiting!',
    'body'         => '<p>Hello...</p>',
]);

Upgrade Guide

How to upgrade PrizeX from one version to the next while keeping your data safe.

Step-by-Step

  1. Backup everything
    Export your database from phpMyAdmin (Export → Quick → SQL). Download your entire images/ folder. Keep a copy of your .env file.
  2. Upload the new version
    Upload and extract the new Website.zip into a temporary directory on your server (e.g., /tmp/prizex_new/). Do not overwrite your live site yet.
  3. Update environment config
    Copy your existing .env to the new directory. Compare .env.example between the old and new versions and add any new variables.
  4. Migrate the database
    In phpMyAdmin, export only data (not structure) from your current database (Custom export → uncheck Structure for all tables).
    Drop all tables in the database, import the new version's database/production.sql, then import your data export to restore your records.
  5. Go live
    Replace your live website files with the new version. Copy your backed-up images/ folder back in. Run composer install --no-dev --optimize-autoloader.
  6. Verify
    Open your website, log in as admin, check a few auction pages, and confirm payments are working.
If anything goes wrong, restore your database backup from Step 1 and revert to the old code. Always test in a staging environment before upgrading production.

Developer Tools

PrizeX ships with a full quality-gate pipeline for developers: static analysis, automated tests, CI/CD, and structured logging. All tools are opt-in and require the dev Composer dependencies.

composer install  # installs dev tools alongside runtime deps

PHPStan — Static Analysis New

PHPStan finds type errors, undefined variables, and incorrect method calls without running the code. Configured at level 5 in phpstan.neon.

vendor/bin/phpstan analyse

Scans includes/, ajax/, cron/, and api/. Vendor packages and payment gateways are excluded.

PHPUnit — Automated Tests New

Unit tests live in tests/Unit/. Run the suite:

vendor/bin/phpunit

Current test coverage includes SettingsService (cache invalidation), JobQueue (handler registration and dispatch signature), and asset() helper (with and without CDN).

To add a test for a new service, create a class in tests/Unit/ extending PHPUnit\Framework\TestCase. The bootstrap in tests/bootstrap.php loads .env so tests can read environment variables without a live DB.

GitHub Actions CI/CD New

The pipeline (.github/workflows/ci.yml) runs on every push to main or develop and on pull requests:

  • PHP Quality Gates — installs Composer deps, runs PHPStan, then PHPUnit.
  • Tailwind CSS Build — installs Node deps, runs npm run build:css, uploads compiled CSS as an artifact.
  • OpenAPI Docs — generates docs/openapi.json from controller annotations (main branch only), uploaded as an artifact.

Secrets required in your GitHub repository settings: none for the CI checks. Add DEPLOY_KEY or SERVER_SSH if you extend the pipeline with a deploy step.

Structured Logging New

Application events are written as JSON lines to logs/app.log (rotating 14-day history) via Monolog. JSON format makes logs ingestible by Grafana Loki, DataDog, or any log aggregator.

// Available anywhere after includes/connection.php is loaded
Logger::info('payment.initiated', ['gateway' => 'stripe', 'amount' => 49.99]);
Logger::error('auction.winner_declare_failed', ['auction_id' => 12, 'reason' => $e->getMessage()]);
Logger::warning('rate_limit.exceeded', ['ip' => $_SERVER['REMOTE_ADDR'], 'action' => 'login']);

Set LOG_LEVEL=debug in .env for verbose output during development. Default is info.

The logs/ directory is excluded from Git. Ensure the web server user has write permission: chmod 755 logs/

Troubleshooting

Common issues and how to resolve them. If your issue persists after trying these steps, contact support with your PHP version, hosting type, and a screenshot of the error.

Installation Issues

  • ✔️ Extract Website.zip directly into the domain root — not into a sub-folder.
  • ✔️ Confirm PHP 8.3+ with MySQLi: php -v and php -m | grep mysqli
  • ✔️ Run composer install — if vendor/ is missing, almost nothing will work.
  • ✔️ File permissions: chmod -R 755 images/ logs/
  • ⚠️ Both MySQL 8.0+ and MariaDB 10.6+ are supported. Older versions may have compatibility issues.
  • ⚠️ Re-upload files if extraction was incomplete or folders are missing.

Database Connection Errors

  • 🛠️ Check credentials in .env — not in includes/connection.php (credentials are no longer stored there).
  • 🛠️ Ensure the DB user has full privileges on the target database.
  • 🛠️ If using a remote DB host, whitelist your server's IP in the DB panel.
  • 🛠️ Confirm vendor/ exists and vendor/vlucas/phpdotenv is present — without it, .env cannot be loaded.
  • 🛠️ Connection errors are logged to logs/app.log (if Monolog is installed) or PHP's default error log. Check there for the exact message.

Blank Pages / White Screen

  • 🧩 PrizeX has a built-in fatal error handler that shows "Something went wrong" instead of a blank page. If you see a completely blank page, the error is happening before the handler loads — usually a missing file or PHP parse error.
  • 🧩 Check the PHP error log (set in your server's php.ini or in cPanel → PHP → Error Log).
  • 🧩 Check logs/app.log for structured error entries.
  • 🧩 For temporary verbose output during debugging, set LOG_LEVEL=debug in .env.
  • ⚠️ If required files are missing after extraction, re-upload and extract the zip.

Payment Gateway Failures

  • ✅ Confirm API keys are entered in Admin → Settings → Payment Gateway.
  • ⚠️ Check you are in Live mode, not Test/Sandbox mode on the gateway dashboard.
  • ⚠️ Verify your base currency is set correctly — many gateways reject unsupported currencies silently.
  • ⚠️ For Stripe: ensure webhook secret is configured and the webhook endpoint is reachable from the internet (not just localhost).

App or Website Not Loading

  • 🌐 Confirm your domain or subdomain points to the directory containing index.php.
  • 📶 Hard-refresh the browser (Ctrl+Shift+R / Cmd+Shift+R) to clear cached files after an update.
  • ⚙️ Open browser DevTools (F12) → Console and Network tabs for JS or 404 errors.
  • 🎨 If CSS fails to load, ensure files are at the web root (not in a subdirectory). If APP_TAILWIND_BUILD=1, run npm run build:css to generate assets/css/app.css.
  • 🔒 If SSE auction streams show no updates, check Apache/reverse-proxy buffering and caching settings (see Live Auction Streaming section).

Cron / Automation Issues

If winners aren't being declared, interest isn't calculated, or emails aren't sending automatically:

  • Verify cron jobs are set up with the correct script paths (see Cron Jobs section).
  • Check the correct script names — declare_auction-winner.php, declare_lottery-winner.php, investment_interest.php, email_campaign.php, notify_auction_start.php, process_queue.php.
  • Run a script manually to test: php /path/to/Website/cron/declare_auction-winner.php
  • Confirm the PHP binary path with: which php
  • Some shared hosts run cron via HTTP — check your host's documentation if SSH-style cron doesn't work.
  • For email campaigns: ensure process_queue.php is also set up as a cron job (every minute). Email jobs are enqueued by email_campaign.php and processed separately by the worker.

Still Need Help?

  • 🗨️ Email: hello@wowcodes.in
  • 📩 WhatsApp or CodeCanyon comment on your purchase.
  • 📎 Always include: PHP version (php -v), hosting type, screenshot of the error, and the contents of logs/app.log if available.