Che cos'è PrizeX
PrizeX è una piattaforma PHP per premi, gaming e marketplace: aste, lotteria, mystery box, un gruppo di giochi arcade, un negozio e-commerce multi-venditore e un'economia a portafoglio e monete — tutto in un'unica applicazione self-hosted. Arriva con un'architettura a plugin e temi, un pannello di amministrazione e 38 plugin di gateway di pagamento che coprono carte, portafogli elettronici, crypto e processori regionali, più 3 metodi di pagamento manuali già inseriti dal kernel.
Non c'è alcun vincolo SaaS: lo installi sul tuo hosting, il database è tuo e la licenza ti dà aggiornamenti a vita. Ogni verticale (aste, lotteria, mystery box, giochi, negozio) si attiva o si disattiva in modo indipendente dal pannello di amministrazione — un'installazione nuova può funzionare come prodotto a verticale singolo oppure come suite completa.
Il codice core non dipende mai in modo rigido da un plugin. Ogni verticale, gateway di pagamento e login social è un plugin dentro plugins/ che si può attivare, disattivare o eliminare senza rompere il resto del sito.
Prefisso delle tabelle tbl_, nessun ORM, quasi ovunque prepared statement. Ogni plugin possiede e migra le proprie tabelle tramite un installer idempotente basato su db_delta().
Su cosa gira
PrizeX gira su un normale hosting condiviso o su un VPS — non serve alcuna configurazione particolare del server, a parte un server web in grado di riscrivere gli URL.
* Diversi file dentro database/migrations/ usano l'estensione ADD COLUMN IF NOT EXISTS, disponibile solo su MariaDB. MySQL 8.0/8.4 la rifiuta — usa MariaDB come database, sia in sviluppo sia in produzione.
Avviare un'installazione da zero
Per una nuova installazione non c'è una procedura guidata: importi direttamente lo schema e configuri il file di ambiente.
- Installa le dipendenze PHP:
composer install - Copia il modello del file di ambiente e inserisci le credenziali del tuo database:
cp .env.example .env - Importa
database/production.sqlnel database indicato nel tuo.env— così viene creato lo schema completo. - Sostituisci l'account amministratore preinstallato (vedi il riquadro qui sotto), poi accedi da
/admin/.
database/production.sql include una riga tbl_admin (admin@wowcodes.in) il cui hash della password è identico su ogni installazione. Eliminala e inserisci la tua prima di andare online:
php -r "echo password_hash('your-password', PASSWORD_BCRYPT), \"\n\";"DELETE FROM tbl_admin;
INSERT INTO tbl_admin (username, email, password, image, status, permission_settings)
VALUES ('yourname', 'you@example.com', '<hash from the command above>', '', 1, 1);Per lo sviluppo locale, il server PHP integrato funziona senza Apache: php -S localhost:8000 router.php — tieni presente che questo server ignora completamente .htaccess, quindi router.php reimplementa a mano le stesse regole di routing (vedi Configurazione del server web).
Variabili di ambiente
Tutte le impostazioni specifiche dell'ambiente vivono in .env, caricato tramite vlucas/phpdotenv. Copia .env.example in .env (escluso dal versionamento) e imposta i valori reali per ogni ambiente — le credenziali del database, come minimo, prima di importare lo schema.
Le impostazioni globali del sito che non dipendono dall'ambiente (nome dell'app, valuta, plugin attivi, tema attivo e interruttori dei singoli verticali) vivono nel database, in tbl_settings, e si gestiscono dal pannello di amministrazione anziché nei file.
Configurazione del server web
Le regole di routing e di sicurezza — URL leggibili, blocco dell'accesso diretto a .env/connection.php/log e prevenzione dell'esecuzione come PHP dei contenuti caricati — sono definite nei file .htaccess distribuiti in tutto il progetto. Apache e LiteSpeed/OpenLiteSpeed li leggono in modo nativo.
Su nginx, usa nginx.conf.example, che replica ognuna di quelle regole in un blocco server{} di nginx — adatta server_name, root e il socket PHP-FPM al tuo ambiente.
.htaccess (produzione), router.php (server di sviluppo locale php -S) e nginx.conf.example (nginx) reimplementano ciascuno le stesse regole di routing in modo indipendente. Aggiungere un nuovo URL leggibile significa aggiornarli tutti e tre.
Architettura delle richieste
Ogni pagina della vetrina (index.php, item.php, …) si avvia passando per includes/header.php, in quest'ordine:
connection.php avvia la sessione, si collega tramite mysqli usando le credenziali di .env, carica tbl_settings in costanti come APP_NAME e CURRENCY ed effettua il login dell'utente corrente insieme a una riga di fingerprint del dispositivo. plugins_load() avvia tutti i plugin attivi e lancia l'hook plugins_loaded — è a questo punto che diventa noto l'insieme reale e aggiornato dei verticali attivi, ed è per questo che subito dopo header.php ricontrolla i vecchi flag delle impostazioni (shop, multivendor, auction, lottery) rispetto allo stato di attivazione effettivo dei plugin.
Il pannello di amministrazione non duplica questo bootstrap — admin/includes/connection.php imposta la configurazione di sessione e di errore specifica dell'area amministrativa, poi include lo stesso includes/connection.php della root.
Sistema dei plugin
Un plugin è plugins/<slug>/plugin.php — metadati nel commento di intestazione, letti senza eseguire il file — più un plugin.json facoltativo per informazioni di catalogo più ricche. I plugin attivi sono memorizzati come array JSON in tbl_settings.active_plugins.
- Proprietà delle tabelle — ogni plugin definisce il proprio
includes/schema.php, richiamato all'attivazione, che usa l'helper idempotentedb_delta()(CREATE TABLE IF NOT EXISTS+ soltantoALTER TABLE ADD COLUMNadditivi). Un plugin non tocca mai le tabelle di un altro plugin. - I registri si caricano per primi —
add_admin_page,add_route,add_cron_job,add_api_routeeregister_modulesono tutti definiti prima che venga caricato un qualsiasi plugin, così le chiamate di primo livello di un plugin non generano mai un errore fatale, nemmeno se quel plugin resta inattivo. - Rimozione pulita — eliminando un plugin viene eseguito il suo
uninstall.phpe la sua cartella viene rimossa; nulla al di fuori diplugins/<slug>/dovrebbe includere in modo obbligatorio i suoi file, quindi il resto del sito continua a funzionare anche senza quel plugin.
Sistema dei temi
Un tema vive in assets/themes/<slug>/ — un manifest.php, un theme.css, un functions.php per gli hook del tema e una cartella components/ facoltativa. Il tema attivo è memorizzato in tbl_settings.active_theme, con editorial come ripiego se non ne è impostato nessuno.
La risoluzione dei componenti controlla, in quest'ordine: la cartella components/ del tema attivo, poi la directory dei componenti dichiarata da un plugin con register_module(), infine la cartella components/ condivisa nella root. In pratica questo significa che il file predefinito condiviso esiste una sola volta in components/, e qualsiasi tema — o plugin verticale attivo — può sovrascrivere un determinato percorso di componente con la propria copia.
Database
Prefisso delle tabelle tbl_, mysqli puro, quasi ovunque prepared statement. I file SQL, in ordine di autorità:
database/core-schema.sql— solo le tabelle del kernel, mantenute a mano; le tabelle dei verticali e dei plugin sono escluse di proposito.database/production.sql— generato (schema core + la routine di installazione di ogni plugin, esportata da un database di appoggio). È questo il file da importare per una nuova installazione.database/sandbox.sql— dataset dimostrativo con dati di esempio per lo sviluppo locale.database/migration.sql— script di aggiornamento consolidato e idempotente per le installazioni esistenti.database/migrations/<slug>/up.sql(+down.sqldove è reversibile) — un file per ogni singola migrazione.
Moduli
Ogni modulo arriva nella stessa installazione e si attiva o disattiva in modo indipendente dal pannello di amministrazione.
Aste
Offerte in tempo reale con portale venditori multi-venditore e motore delle commissioni. Plugin principale: plugins/auction.
Lotteria
Estrazioni a biglietti con calendari, premi e notifiche ai vincitori configurabili. Plugin principale: plugins/lottery.
Mystery box
Montepremi configurabili con animazioni di apertura — gli utenti acquistano una box e vedono subito cosa hanno vinto. Plugin: plugins/mystery-box.
Giochi e ricompense
Un gruppo di giochi arcade dentro games/, più i plugin di coinvolgimento e guadagno:
Negozio e marketplace
Un livello e-commerce multi-venditore con strumenti di promozione e merchandising. Plugin principali: plugins/shop, plugins/multivendor.
Portafoglio, monete e investimenti
Un portafoglio unico per tutta la piattaforma, condiviso da ogni modulo.
Referral e ricompense
Autenticazione, affidabilità e conformità
Utility
Pannello di amministrazione
Il pannello di amministrazione vive dentro admin/ e non duplica il bootstrap della vetrina — imposta la configurazione di sessione e di errore specifica dell'area amministrativa, poi include lo stesso includes/connection.php della root. Le pagine si registrano con add_admin_page(), che si occupa della voce nella barra laterale, del controllo delle capability, del CSRF e dell'interfaccia di autenticazione; le azioni JSON riservate all'amministrazione si registrano con add_admin_ajax() e vengono smistate da admin/ajax.php?action=<slug>.
Articoli, banner, pagine, menu, blog.
Gestione dei gateway automatici e manuali, revisione dei pagamenti manuali, esportazione dei pagamenti in uscita.
Gruppi di utenti, ruoli, dati dei venditori, impersonificazione.
Esportazione di transazioni, ordini e utenti, log dei cron, tracciamento degli errori, log delle attività di amministrazione.
Campagne email, template, newsletter, notifiche push, log delle notifiche.
Attivazione e disattivazione di plugin e temi, impostazioni SEO per singola pagina, impostazioni globali del sito.
Temi della vetrina
Cinque temi sono inclusi dentro assets/themes/ e si possono cambiare, installazione per installazione, dal pannello di amministrazione. Ogni tema conserva la propria copia dei componenti condivisi nella sua cartella components/.
Un aspetto semplice e moderno, con schede bianche e ombre morbide — una scelta sicura e versatile per quasi ogni tipo di negozio.
Un aspetto pulito in stile magazine, con toni caldi da carta stampata e una tipografia nitida, per una vetrina curata e affidabile.
Tema di riserva predefinitoUn tema scuro deciso e lussuoso, con accenti dorati — pensato per trasmettere adrenalina e fascia alta.
Un aspetto caldo e riccamente decorato, ispirato ai mercati tradizionali, con supporto per le lingue da destra a sinistra.
Un aspetto stagionale spettrale e festoso — sfondi viola profondo con accenti luminosi color arancio zucca.
Gateway di pagamento
I 38 gateway automatici appartengono ai plugin — ognuno vive nella propria cartella plugins/gateway-<slug>/ e si registra nel kernel tramite add_payment_gateway(). Attivarne uno è sufficiente perché funzioni; nel dispatcher del checkout (payment_processor.php) non c'è nulla scritto a mano per un gateway specifico.
I 3 metodi manuali sono righe con gateway_type = 'manual' inserite dal kernel, senza codice di init/verify da configurare: mostrano semplicemente le istruzioni di pagamento o un codice QR. Il plugin manual-gateway-builder permette a un amministratore di aggiungere altri metodi di pagamento manuali personalizzati senza toccare il codice.
Alcuni gateway (Stripe, Razorpay, Midtrans, Venmo) registrano anche un hook render per i flussi di checkout che richiedono JS lato client — l'avvio di Stripe Checkout, oppure un SDK Razorpay/Midtrans/Braintree che ha bisogno di un ID ordine o di un token generato prima lato server. Tutti gli altri gateway funzionano senza alcun collegamento aggiuntivo al kernel.
Livelli API e AJAX
api/v1/— API REST autenticata con JWT, per l'app mobile e per i consumatori esterni.api/v1/middleware/*.phpconvalida l'headerAuthorization: Bearer <token>. I plugin aggiungono i propri endpoint tramiteadd_api_route().ajax/— AJAX interno autenticato con cookie di sessione, per il JS della vetrina stessa (carrello, coupon, notifiche). Nessun livello a token: si appoggia alla sessione PHP creata daconnection.php.- Cartella
api/di primo livello — endpoint vari non versionati, comegeo_location.php,exchange-rate.phpeofferwall_postback.php.
App mobile
mobile/ è un progetto Capacitor + Ionic separato — un wrapper WebView attorno al sito live, non una SPA a sé stante e nemmeno soltanto un consumatore di api/v1. Il suo capacitor.config.ts punta server.url al tuo dominio. Ha un proprio package.json e non viene compilato dalla root del progetto:
cd mobile
npm run sync
npm run open:ios
npm run open:androidAggiornamenti e migrazioni
Fai uno snapshot prima di eseguire database/migration.sql o un qualsiasi database/migrations/<slug>/up.sql su un database in produzione:
mysqldump --single-transaction -u<user> -p<pass> <db> > pre-deploy-$(date +%Y%m%d-%H%M%S).sqlLa maggior parte delle migrazioni include un down.sql corrispondente che annulla soltanto quella modifica. Alcune, che trasformano dati esistenti invece di limitarsi ad aggiungere struttura, includono un down.sql che spiega perché non fa nulla — in quei casi, se devi tornare indietro, ripristina il dump fatto prima del deploy.
Note sulla sicurezza
- Cambia le credenziali dell'amministratore preinstallato subito dopo l'importazione (vedi Installazione).
.env,connection.phpe i file di log sono bloccati all'accesso diretto via HTTP dalle regole.htaccess/ nginx incluse nel prodotto — non rimuovere quelle regole.- I contenuti caricati vengono serviti in modo che non possano essere eseguiti come PHP: il vincolo è imposto a livello di configurazione del server web, non a livello applicativo.
- Le credenziali dei gateway di pagamento si impostano gateway per gateway dal pannello di amministrazione e restano memorizzate lato server — non vengono mai esposte alla vetrina.
Test
Non esiste una suite PHPUnit. composer test esegue bin/run-probes.php, che raccoglie ogni file probe_*.php presente in includes/_probes/ e nella cartella _probes/ di ciascun plugin, eseguendoli uno per uno come sottoprocesso CLI e controllandone il codice di uscita.
composer test # run every probe
php plugins/<slug>/_probes/probe_*.php # run a single probe directly
php bin/run-probes.php --all # also run destructive probes (skipped by default)Domande frequenti
Supporto e risorse
Sei ancora bloccato o ti serve qualcosa che questa pagina non copre?