Ce qu'est PrizeX
PrizeX est une plateforme de lots, de jeux et de place de marché écrite en PHP : enchères, loterie, coffrets mystère, un ensemble de jeux d'arcade, une boutique e-commerce multi-vendeurs et une économie de portefeuille et de crédits — le tout dans une seule application auto-hébergée. Elle repose sur une architecture à extensions et à thèmes, avec un panneau d'administration et 38 extensions de passerelle de paiement couvrant cartes, portefeuilles, crypto et acteurs régionaux, plus 3 moyens de paiement manuels créés par le noyau.
Aucune dépendance à un SaaS : vous installez PrizeX sur votre propre hébergement, la base de données vous appartient et la licence vous donne des mises à jour à vie. Chaque activité (enchères, loterie, coffrets mystère, jeux, boutique) s'active et se désactive indépendamment depuis le panneau d'administration — une installation neuve peut fonctionner comme un produit mono-activité ou comme la suite complète.
Le code du noyau ne dépend jamais strictement d'une extension. Chaque activité, chaque passerelle de paiement et chaque connexion via un réseau social est une extension placée sous plugins/, que l'on peut activer, désactiver ou supprimer sans casser le reste du site.
Préfixe de table tbl_, pas d'ORM, des requêtes préparées dans la quasi-totalité des cas. Chaque extension possède ses propres tables et les fait évoluer via un installeur idempotent db_delta().
Ce qu'il faut pour le faire tourner
PrizeX tourne sur un hébergement mutualisé standard ou un VPS — aucune configuration serveur particulière au-delà d'un serveur web capable de réécrire les URL.
* Plusieurs fichiers de database/migrations/ utilisent ADD COLUMN IF NOT EXISTS, une syntaxe propre à MariaDB. MySQL 8.0/8.4 la rejette — utilisez MariaDB comme base de données, en développement comme en production.
Mettre en route une installation neuve
Il n'y a pas d'assistant pour une nouvelle installation — vous importez directement le schéma et vous configurez le fichier d'environnement.
- Installez les dépendances PHP :
composer install - Copiez le modèle de fichier d'environnement et renseignez vos identifiants de base de données :
cp .env.example .env - Importez
database/production.sqldans la base indiquée dans votre.env: cela crée le schéma complet. - Remplacez le compte administrateur livré par défaut (voir l'encadré ci-dessous), puis connectez-vous sur
/admin/.
database/production.sql contient une ligne tbl_admin (admin@wowcodes.in) dont l'empreinte de mot de passe est identique sur toutes les installations. Supprimez-la et insérez la vôtre avant la mise en production :
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);En développement local, le serveur PHP intégré fonctionne sans Apache : php -S localhost:8000 router.php — attention, ce serveur ignore totalement .htaccess, si bien que router.php réimplémente les mêmes règles de routage à la main (voir Configuration du serveur web).
Variables d'environnement
Tous les réglages propres à l'environnement vivent dans .env, chargé via vlucas/phpdotenv. Copiez .env.example vers .env (ignoré par git) et renseignez les vraies valeurs pour chaque environnement — au minimum les identifiants de base de données, avant l'import du schéma.
Les réglages généraux du site qui ne dépendent pas de l'environnement (nom de l'application, devise, extensions actives, thème actif et interrupteurs par activité) vivent en base, dans tbl_settings, et se gèrent depuis le panneau d'administration plutôt que dans des fichiers.
Configuration du serveur web
Les règles de routage et de sécurité — URL propres, blocage de l'accès direct à .env/connection.php/aux journaux, et interdiction faite aux contenus téléversés de s'exécuter comme du PHP — sont définies dans les fichiers .htaccess répartis dans le projet. Apache et LiteSpeed/OpenLiteSpeed les lisent nativement.
Sous nginx, utilisez nginx.conf.example, qui reprend chacune de ces règles dans un bloc server{} nginx — ajustez server_name, root et le socket PHP-FPM pour votre environnement.
.htaccess (production), router.php (serveur de développement local php -S) et nginx.conf.example (nginx) réimplémentent chacun les mêmes règles de routage, de leur côté. Ajouter une nouvelle URL propre suppose donc de mettre à jour les trois.
Architecture des requêtes
Chaque page de la vitrine (index.php, item.php, …) démarre en passant par includes/header.php, dans cet ordre :
connection.php ouvre la session, se connecte via mysqli avec les identifiants du .env, charge tbl_settings dans des constantes comme APP_NAME et CURRENCY, puis connecte l'utilisateur courant et enregistre une empreinte d'appareil. plugins_load() démarre toutes les extensions actives et déclenche le hook plugins_loaded — c'est à ce moment précis que la liste réelle des activités actives devient connue, et c'est pourquoi header.php revérifie ensuite les anciens indicateurs de réglages (boutique, multi-vendeurs, enchères, loterie) face à l'état réel des extensions actives.
Le panneau d'administration ne refait pas ce démarrage de son côté — admin/includes/connection.php applique une configuration de session et d'erreurs propre à l'administration, puis inclut le même includes/connection.php racine.
Système d'extensions
Une extension, c'est plugins/<slug>/plugin.php — des métadonnées en commentaire d'en-tête, analysées sans exécuter le fichier — plus un plugin.json facultatif pour un descriptif de catalogue plus riche. Les extensions actives sont stockées sous forme de tableau JSON dans tbl_settings.active_plugins.
- Propriété des tables — chaque extension définit son propre
includes/schema.php, appelé à l'activation, qui s'appuie sur l'utilitaire idempotentdb_delta()(CREATE TABLE IF NOT EXISTS+ALTER TABLE ADD COLUMNuniquement additif). Une extension ne touche jamais aux tables d'une autre. - Les registres se chargent en premier —
add_admin_page,add_route,add_cron_job,add_api_routeetregister_modulesont tous définis avant le chargement de la moindre extension : les appels de premier niveau d'une extension ne provoquent donc jamais d'erreur fatale, même si celle-ci finit inactive. - Suppression propre — supprimer une extension exécute son
uninstall.phpet retire son dossier ; rien en dehors deplugins/<slug>/ne doit dépendre strictement de ses fichiers, si bien que le reste du site continue de fonctionner une fois l'extension partie.
Système de thèmes
Un thème vit dans assets/themes/<slug>/ — un manifest.php, un theme.css, un functions.php pour les hooks de thème et un dossier components/ facultatif. Le thème actif est stocké dans tbl_settings.active_theme, avec editorial en repli si rien n'est défini.
La résolution d'un composant se fait dans cet ordre : le dossier components/ du thème actif, puis le répertoire de composants déclaré par le register_module() d'une extension, puis le components/ racine partagé. Concrètement, la version partagée par défaut n'existe qu'une seule fois, dans components/, et n'importe quel thème — ou n'importe quelle extension d'activité active — peut remplacer un chemin de composant précis par sa propre copie.
Base de données
Préfixe de table tbl_, mysqli brut, des requêtes préparées dans la quasi-totalité des cas. Les fichiers SQL, par ordre d'autorité :
database/core-schema.sql— les tables du noyau uniquement, maintenues à la main ; les tables des activités et des extensions en sont volontairement exclues.database/production.sql— généré (schéma du noyau + routine d'installation propre à chaque extension, exporté depuis une base jetable). C'est ce fichier que vous importez pour une installation neuve.database/sandbox.sql— jeu de données de démonstration, pour le développement local.database/migration.sql— script de mise à niveau consolidé et idempotent, pour les installations existantes.database/migrations/<slug>/up.sql(+down.sqlquand la migration est réversible) — un fichier par migration.
Modules
Tous les modules sont livrés dans la même installation et s'activent indépendamment depuis le panneau d'administration.
Enchères
Enchères en direct, avec espace vendeur multi-vendeurs et moteur de commissions. Extension principale : plugins/auction.
Loterie
Tirages sur billets, avec calendriers, lots et notifications aux gagnants configurables. Extension principale : plugins/lottery.
Coffret mystère
Pools de lots configurables, avec animations de révélation — l'utilisateur achète un coffret et découvre instantanément ce qu'il a gagné. Extension : plugins/mystery-box.
Jeux et récompenses
Un ensemble de jeux d'arcade sous games/, plus les extensions d'engagement et de gains :
Boutique et place de marché
Une couche e-commerce multi-vendeurs, avec promotions et outils de mise en avant. Extensions principales : plugins/shop, plugins/multivendor.
Portefeuille, crédits et investissement
Un portefeuille commun à toute la plateforme, partagé par tous les modules.
Parrainage et récompenses
Authentification, confiance et conformité
Utilitaires
Panneau d'administration
Le panneau d'administration vit sous admin/ et ne refait pas le démarrage de la vitrine — il applique une configuration de session et d'erreurs propre à l'administration, puis inclut le même includes/connection.php racine. Les pages s'enregistrent via add_admin_page(), qui gère l'entrée dans la barre latérale, le contrôle des droits, la protection CSRF et l'habillage d'authentification ; les actions JSON réservées à l'administration s'enregistrent via add_admin_ajax() et sont routées par admin/ajax.php?action=<slug>.
Articles, bannières, pages, menus, blog.
Gestion des passerelles automatiques et manuelles, validation des paiements manuels, exports de versements.
Groupes d'utilisateurs, rôles, fiches vendeurs, connexion à la place d'un utilisateur.
Exports de transactions, de commandes et d'utilisateurs, journaux des tâches cron, suivi des erreurs, journal d'activité des administrateurs.
Campagnes e-mail, modèles, newsletters, notifications push, journal des notifications.
Activation et désactivation des extensions et des thèmes, réglages SEO page par page, réglages généraux du site.
Thèmes de vitrine
Cinq thèmes sont livrés sous assets/themes/ et se changent installation par installation depuis le panneau d'administration. Chaque thème conserve sa propre copie des composants partagés, dans son propre dossier components/.
Un rendu simple et moderne, avec des cartes blanches et des ombres douces — un choix sûr et polyvalent pour presque n'importe quelle boutique.
Un rendu épuré façon magazine, avec des tons papier chaleureux et une typographie nette, pour une vitrine soignée et rassurante.
Thème de repli par défautUn thème sombre, audacieux et luxueux, rehaussé d'accents dorés — pensé pour donner une impression d'excitation et de haut de gamme.
Un rendu chaleureux et richement décoré, inspiré des marchés traditionnels, avec prise en charge des langues écrites de droite à gauche.
Un rendu saisonnier festif et inquiétant — fonds violet profond et éclats orange citrouille lumineux.
Passerelles de paiement
Les 38 passerelles automatiques appartiennent chacune à une extension : chacune vit dans son propre dossier plugins/gateway-<slug>/ et s'enregistre auprès du noyau via add_payment_gateway(). Il suffit d'en activer une pour qu'elle fonctionne ; rien dans le répartiteur de paiement (payment_processor.php) n'est codé en dur pour une passerelle précise.
Les 3 moyens manuels sont des lignes gateway_type = 'manual' créées par le noyau, sans code d'initialisation ni de vérification à configurer — elles se contentent d'afficher des instructions de paiement ou un QR code. L'extension manual-gateway-builder permet à un administrateur d'ajouter d'autres moyens de paiement manuels sur mesure sans toucher au code.
Certaines passerelles (Stripe, Razorpay, Midtrans, Venmo) enregistrent en plus un hook render, pour les parcours de paiement qui réclament du JS côté client — l'amorçage de Stripe Checkout, ou un SDK Razorpay/Midtrans/Braintree qui exige qu'un identifiant de commande ou un jeton soit d'abord généré côté serveur. Toutes les autres passerelles fonctionnent sans le moindre branchement supplémentaire dans le noyau.
Couches API et AJAX
api/v1/— API REST authentifiée par JWT, pour l'application mobile et les consommateurs externes.api/v1/middleware/*.phpvalide l'en-têteAuthorization: Bearer <token>. Les extensions ajoutent leurs propres points de terminaison viaadd_api_route().ajax/— AJAX interne authentifié par cookie de session, pour le JS de la vitrine elle-même (panier, codes promo, notifications). Aucune couche de jetons : il s'appuie sur la session PHP ouverte parconnection.php.- Le dossier
api/de premier niveau — des points de terminaison divers, non versionnés, commegeo_location.php,exchange-rate.phpetofferwall_postback.php.
Application mobile
mobile/ est un projet Capacitor + Ionic distinct — une enveloppe WebView autour du site en ligne, ni une SPA autonome ni un simple consommateur de api/v1. Son capacitor.config.ts fait pointer server.url vers votre domaine. Il a son propre package.json et ne se construit pas depuis la racine du projet :
cd mobile
npm run sync
npm run open:ios
npm run open:androidMises à jour et migrations
Faites une sauvegarde avant d'exécuter database/migration.sql ou l'un des database/migrations/<slug>/up.sql sur une base en production :
mysqldump --single-transaction -u<user> -p<pass> <db> > pre-deploy-$(date +%Y%m%d-%H%M%S).sqlLa plupart des migrations sont accompagnées d'un down.sql qui annule ce seul changement. Quelques-unes, qui transforment des données existantes au lieu de se contenter d'ajouter des structures, sont livrées avec un down.sql expliquant pourquoi il ne fait rien — pour celles-là, restaurez la sauvegarde d'avant déploiement si vous devez revenir en arrière.
Notes de sécurité
- Changez les identifiants du compte administrateur livré par défaut immédiatement après l'import (voir Installation).
.env,connection.phpet les fichiers de journaux sont bloqués en accès HTTP direct par les règles.htaccess/ nginx livrées avec le produit — ne supprimez pas ces règles.- Les contenus téléversés sont servis de façon à ne jamais pouvoir s'exécuter comme du PHP, une règle appliquée au niveau de la configuration du serveur web et non de l'application.
- Les identifiants des passerelles de paiement se configurent passerelle par passerelle depuis le panneau d'administration et sont stockés côté serveur — jamais exposés à la vitrine.
Tests
Il n'y a pas de suite PHPUnit. composer test lance bin/run-probes.php, qui rassemble tous les fichiers probe_*.php présents sous includes/_probes/ et dans le dossier _probes/ propre à chaque extension, exécute chacun comme un sous-processus CLI et vérifie son code de sortie.
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)Questions fréquentes
Support et ressources
Toujours bloqué, ou besoin de quelque chose que cette page ne couvre pas ?