Guía de Instalación
Todo lo que necesitas para instalar Systema v1.0 en un servidor nuevo, desde cero hasta tener el sistema operativo con licencia activa.
| Componente | Mínimo | Recomendado | Estado |
|---|---|---|---|
| PHP | 7.4 | 8.1+ | Obligatorio |
| MySQL | 5.7 | 8.x | Obligatorio |
| Extensión PDO MySQL | — | — | Obligatorio |
| Extensión cURL | — | — | Obligatorio para licencias |
| Extensión OpenSSL | — | — | Obligatorio para licencias |
| Extensión GD | — | — | Recomendado para QR |
| Extensión ZipArchive | — | — | Recomendado para bulk PDF |
| allow_url_fopen | — | — | Opcional (usa cURL) |
| Memory limit | 128M | 256M+ | Para dompdf |
| HTTPS | — | — | Muy recomendado |
tudominio.com/systema/status.php una vez instalado.El ZIP de Systema v1.0 contiene estos ficheros. Todos van dentro de una carpeta en el servidor, por ejemplo public_html/systema/.
├── index.php ← Login con validación de licencia
├── dashboard.php · leads.php · clientes.php
├── facturacion.php · presupuestos.php · resultados.php
├── configuracion.php · presentador.php
├── status.php ← Panel de mantenimiento
├── layout.php · layout_end.php · auth.php · logout.php
├── activate.php · check.php · reset_password.php · kpi_engine.php
├── actualizaciones.php · historial.php · changelog.php
├── resultado_publico.php ← Portal contable por token, sin login
├── config/
│ ├── settings.php ← Se genera automáticamente. NO subir a git.
│ └── version.php ← Versión y changelog interno
├── assets/
│ └── core.css · core.js · favicon.png
├── PHPMailer/
│ └── PHPMailer.php · SMTP.php · Exception.php
├── modules/
│ ├── _db.php
│ ├── facturacion/ create · update · delete · duplicate · get_items · pdf_render · pdf_export · send_email · track_open · update_estado · update_vencimiento · import · import_sql
│ ├── presupuestos/ create · update · delete · duplicate · get_items · convert · pdf_render · pdf_export · send_email · track_open · update_estado
│ ├── clientes/ create · update · delete · update_estado · import · export
│ ├── leads/ create · update · delete · convert
│ ├── configuracion/ save_fiscal · save_smtp · save_plantilla · save_marca · delete_marca · save_verifactu · save_seguridad · save_acceso · save_db · save_php · save_ui · get_marcas · test_smtp · test_db · mark_seen
│ ├── resultados/ create · delete · generate · get_facturas · send · status · cleanup · update
│ └── presentador/ calcular · calcular_inline · generar_pdf · generar_txt · pdf_publico · historial
├── vendor/ ← fpdf186 · FPDI-master · dompdf* · masterminds* · phpmailer*
│ * dompdf y masterminds se instalan aparte (ver Paso 5)
├── assets/resultados/ ← Se crea automáticamente. Almacena ZIPs fiscales ({año}/T1.zip ... T4.zip)
└── presentador/templates/ ← m303.pdf · m130.pdf · m390.pdf (plantillas AEAT)
.gitignore.systema/ con todos los ficheros.
public_html/ (o www/ según el hosting).
systema/ al directorio raíz del dominio. Quedará accesible en tudominio.com/systema/.
Si quieres que sea la raíz del dominio, sube el contenido directamente en public_html/.
config/ necesita permisos de escritura para que PHP pueda crear settings.php. Permisos recomendados: 755 en carpetas, 644 en ficheros.
tudominio.com/systema/ ves la pantalla de Configuración en lugar del login, es normal — significa que no hay settings.php todavía y el sistema te pide que lo configures. Continúa con el Paso 3.Crear la base de datos
tudominio.com/phpmyadmin o desde el panel de control de tu hosting (cPanel, Plesk, etc.).
systema_db → cotejamiento utf8mb4_unicode_ci → Crear.
host, usuario, contraseña y nombre de la BD — los necesitarás en el Paso 3.
systema_5.0.5.sql que está en la raíz del ZIP → Continuar.
Verás que se crean 12 tablas y 2 vistas.
clientes, configuracion, email_tracking, facturas, factura_items, leads, marcas, presentaciones_historial, presupuestos, presupuesto_items, series_numeracion, resultados_anuales Nueva v0.5.5. Más las vistas v_dashboard_facturas y v_dashboard_presupuestos.public_token en facturas, prefijo_factura y siguiente_factura en marcas, claves VeriFactu QR en configuración, y la nueva tabla resultados_anuales con sus 12 campos. No uses ficheros SQL de versiones anteriores.¿Actualizas desde v0.5? Ejecuta solo el ALTER:
ALTER TABLE resultados_anuales ADD COLUMN zip_status ENUM('procesando','preparado','error') DEFAULT NULL, ADD COLUMN zip_generado_at DATETIME DEFAULT NULL, ADD COLUMN zip_expires_at DATETIME DEFAULT NULL;O importa directamente el
systema_5.0.5.sql completo en una instalación nueva.El fichero config/settings.php es el cerebro de la instalación. Contiene las credenciales de BD, la contraseña de acceso al sistema y los datos de licencia. Tienes dos formas de crearlo:
Opción A — Desde el panel web (recomendado)
Accede a tudominio.com/systema/. Si no hay settings.php, el sistema redirige automáticamente a configuracion.php donde puedes introducir las credenciales de BD desde el navegador. El fichero se crea solo.
Opción B — Directamente por FTP
Crea el fichero config/settings.php manualmente con este contenido exacto:
<?php
return array (
// ── Base de datos ─────────────────────────────
'db_host' => 'localhost', // host MySQL de tu hosting
'db_port' => '3306',
'db_user' => 'tu_usuario_bd', // usuario MySQL
'db_pass' => 'tu_password_bd', // contraseña MySQL
'db_name' => 'systema_db', // nombre de la BD
// ── Acceso al sistema ─────────────────────────
'password' => 'TU_PASSWORD_ACCESO', // contraseña para entrar en Systema
'admin_nombre' => 'Nombre Apellido',
'admin_email' => '[email protected]',
// ── Licencia (se rellena automáticamente) ─────
'licencia_secret' => 'Sy5t3m4_L1c_S3cr3t0_R4f3lG1l_2026_xK9mP2qW',
'licencia_token' => '', // se inyecta automáticamente desde el panel de licencias
'licencia_domain' => '', // se rellena automáticamente
'licencia_cache' => 0, // timestamp de última validación (0 = forzar validación)
);
licencia_secret debe ser idéntica a la constante LIC_SECRET del fichero config.php del servidor central de licencias en rafelgil.com/licencias/. Si no coinciden, la validación siempre fallará.Verificar que funciona
Accede a tudominio.com/systema/. Debe aparecer el login con el fondo de fotos rotativas y el formulario de contraseña. Si redirige a configuracion.php, las credenciales de BD son incorrectas o la BD no está creada.
Una vez dentro del sistema, ve a Configuración y rellena estas secciones en orden:
Datos Fiscales
Razón social, NIF/CIF, dirección completa, email, teléfono, IBAN y forma de pago. Estos datos aparecen en todas las facturas emitidas.
Email SMTP
Configura el servidor de correo para enviar facturas a clientes. Necesitas:
| Campo | Ejemplo |
|---|---|
| Host SMTP | smtp.tuhosting.com |
| Puerto | 587 (TLS) · 465 (SSL) |
| Usuario | [email protected] |
| Contraseña | Contraseña del email |
| Cifrado | tls o ssl |
| Nombre remitente | Tu Empresa |
| Email From | [email protected] |
Usa el botón Test SMTP en Status para verificar la conexión antes de enviar facturas reales.
Plantilla PDF
Pega el HTML de tu plantilla de factura. Usa los marcadores {{numero}}, {{cliente_nombre}}, {{total}}, etc. Para activar el QR de VeriFactu añade {{qr_code}} donde quieras que aparezca.
Marcas
Crea al menos una marca emisora. La marca define el prefijo de numeración de facturas (ej: RG{YEAR}- → RG2026-0001) y el prefijo de presupuestos.
{YEAR} en el prefijo se sustituye automáticamente por el año actual. Así F{YEAR}- genera F2026-0001, F2026-0002, etc.Interfaz UI — Zoom Nuevo v0.5.5
En Configuración → Interfaz UI puedes ajustar el zoom de la interfaz (70%–125%) para adaptarlo a tu pantalla. El valor se guarda en el servidor y en el navegador — no se pierde al limpiar caché.
| Pantalla | Zoom recomendado |
|---|---|
| Portátil 13" / 14" | 80% |
| Portátil 15" / 16" | 85% – 90% |
| Monitor 24" | 100% – 110% |
| Monitor 27" o más | 110% – 125% |
dompdf no está incluido en el ZIP principal por su tamaño. Sin él, el visor HTML de facturas funciona pero la exportación a PDF no.
Opción A — Instaladores web (recomendado)
El ZIP incluye el fichero systema_PDF_install_dompdf-mm.v03.zip. Extráelo y encontrarás dos instaladores PHP. Súbelos a la raíz de Systema y ábrelos desde el navegador — instalan dompdf y Masterminds automáticamente.
Opción B — FTP manual
Descarga dompdf v2.0.4 y Masterminds html5-php v2.7.6 desde GitHub y súbelos a:
vendor/dompdf/— dompdf v2.0.4vendor/masterminds/— html5-php v2.7.6
status.php → Sector E · PDF Engine que aparecen DomPDF v2: INSTALLED y Masterminds HTML5: INSTALLED.Systema v0.5.5 incluye un cron job para limpiar automáticamente los ZIPs de resultados anuales que han caducado (más de 14 días). Sin este cron los archivos se acumulan en disco indefinidamente.
Configurar en Plesk
/usr/bin/php -f /var/www/vhosts/SERVIDOR/DOMINIO/systema/modules/resultados/cleanup.php
Sustituye SERVIDOR y DOMINIO por los valores reales de tu hosting. En Hostalia la ruta suele ser /var/www/vhosts/XXXXXXXX.servicio-online.net/tudominio.com/systema/.
0 3 * * * — se ejecutará cada día a las 3:00 AM.
0 resultado(s) limpiados. si no hay nada caducado — eso confirma que el cron funciona correctamente.
¿Qué limpia el cron?
- Busca registros en
resultados_anualesconzip_status = 'preparado'yzip_expires_at < NOW(). - Elimina los archivos
T1.zip,T2.zip,T3.zip,T4.zipdeassets/resultados/{año}/. - Resetea
zip_status = NULLpara que puedas regenerar cuando quieras.
Systema v1.0 incorpora un sistema de licencias que te permite controlar qué instalaciones están activas. Si un cliente deja de pagar, puedes pausar su licencia desde el panel central y a los 7 días el sistema dejará de funcionar para él.
🌐 Servidor central
En rafelgil.com/licencias/ vive el panel de gestión. Aquí creas, activas y pausas licencias.
🔑 Token por instalación
Cada cliente tiene un token único generado con HMAC-SHA256. Sin token válido no puede entrar.
⚡ Caché de 7 días
El cliente no llama al servidor central en cada login. La validación se cachea 7 días para máxima velocidad y resiliencia.
👻 Invisible al cliente
El sistema es completamente transparente. El cliente solo ve un mensaje genérico si la licencia expira.
Flujo completo
settings.php con las credenciales y el licencia_secret.
rafelgil.com/licencias/, creas la licencia para el dominio del cliente y pulsas Inyectar.
activate.php en el servidor del cliente y escribe el token directamente en config/settings.php. Sin FTP adicional.
Esta configuración se hace una sola vez en rafelgil.com y no se toca más.
1 · Crear la BD de licencias
En phpMyAdmin de rafelgil.com, crea una BD nueva llamada rafelgil_licencias (o el nombre que quieras). Importa el fichero licencias_bd.sql. Se crean dos tablas: licencias y licencias_log.
2 · Subir los ficheros del panel central
Sube estos tres ficheros a rafelgil.com/licencias/:
├── config.php ← clave privada + contraseña del panel + credenciales BD
├── check.php ← endpoint silencioso que consultan los clientes
└── index.php ← tu panel de gestión completo
3 · Editar config.php
Abre licencias/config.php y rellena:
define('LIC_SECRET', 'Sy5t3m4_L1c_S3cr3t0_R4f3lG1l_2026_xK9mP2qW'); // NO cambiar
define('LIC_PANEL_PASS', '$2y$12$...'); // hash bcrypt de tu contraseña
// Contraseña por defecto: Systema2026! — CÁMBIALA
define('LIC_DB_HOST', 'localhost');
define('LIC_DB_NAME', 'rafelgil_licencias');
define('LIC_DB_USER', 'tu_usuario');
define('LIC_DB_PASS', 'tu_password');
4 · Cambiar la contraseña del panel
La contraseña por defecto es Systema2026!. Para cambiarla, genera un nuevo hash y sustitúyelo en config.php:
// Ejecuta esto en cualquier servidor PHP para generar el hash:
echo password_hash('TU_NUEVA_PASSWORD', PASSWORD_DEFAULT);
Pega el resultado en config.php como valor de LIC_PANEL_PASS.
5 · Verificar acceso al panel
Entra en https://rafelgil.com/licencias/. Debes ver el formulario de login. Introduce tu contraseña y verás el panel de gestión con la tabla de licencias vacía.
Acceso para clientes cloud — Login Landing
Los clientes en la modalidad cloud no necesitan recordar la URL de su instalación. Desde systemafacil.com, el cliente introduce su email y es redirigido automáticamente a su instalación. Este sistema funciona mediante LOGIN LANDING/lookup.php que consulta la URL de instalación en la base de datos central de licencias.
Este es el proceso completo cada vez que instalas Systema para un cliente nuevo.
systema/ va en el servidor del cliente.
systema.sql, crear usuario MySQL con permisos.
licencia_secret:
'licencia_secret' => 'Sy5t3m4_L1c_S3cr3t0_R4f3lG1l_2026_xK9mP2qW',
'licencia_token' => '',
'licencia_domain' => '',
'licencia_cache' => 0,
rafelgil.com/licencias/ → + Nueva licencia → introduce el dominio del cliente (ej: susana.com) → fecha de fin opcional → notas → Crear licencia.
https://susana.com/systema) → Inyectar.
El panel llama a activate.php y escribe el token en el settings.php del cliente sin que tengas que hacer nada más.
activate.php del cliente no es accesible (firewall, URL incorrecta, permisos), el panel te mostrará el error. En ese caso, copia el token manualmente desde la columna de la licencia y pégalo en el settings.php del cliente como 'licencia_token' => 'TOKEN_AQUI'.| Acción | Qué hace |
|---|---|
| + Nueva licencia | Crea una licencia para un dominio. Genera el token automáticamente. Permite añadir fecha de fin y notas. |
| Inyectar | Llama al activate.php del cliente y escribe el token en su settings.php automáticamente. |
| Pausar | Cambia el estado a pausada. El servidor dejará de validar esa licencia. El cliente tiene hasta 7 días de caché antes de que el login falle. |
| Activar | Reactiva una licencia pausada o expirada. |
| Editar | Modifica las notas internas y la fecha de fin de la licencia. |
| Log | Muestra el historial de eventos de esa licencia: activaciones, pausas, checks del cliente, inyecciones de token. |
Columnas del panel
| Columna | Descripción |
|---|---|
| Dominio | El dominio del cliente tal como se registró (sin www, sin https). |
| Estado | Activa Pausada Expirada |
| Último check | Última vez que el Systema del cliente validó su licencia con el servidor central. |
| Fecha fin | Fecha de caducidad automática. Si está vacía, no caduca nunca. |
| Notas | Notas internas — nombre del cliente, plan contratado, observaciones. |
Cuando un cliente deja de pagar
settings.php sigue siendo válida hasta 7 días desde la última validación exitosa. Durante ese tiempo puede seguir entrando con normalidad.
Si el cliente paga y quieres reactivar
Pulsa Activar en el panel. La próxima vez que el cliente intente entrar, la validación será exitosa y podrá acceder con normalidad. La caché se actualiza automáticamente.
Caducidad automática por fecha
Si configuraste una Fecha fin al crear la licencia, el servidor central la marca automáticamente como Expirada cuando se supera esa fecha. No necesitas hacer nada manualmente.
licencia_cache de su settings.php (ponerla a 0) por FTP. Con eso, el siguiente intento de login valida en tiempo real.El módulo de Resultados permite generar cierres fiscales anuales y enviarlos al contable con un portal seguro de descarga. No requiere configuración adicional — funciona con la BD y SMTP ya configurados.
Requisitos previos
- dompdf instalado — es el motor que genera los PDFs de las facturas para los ZIPs.
- SMTP configurado — necesario para enviar el email al contable.
- Plantilla PDF configurada — debe existir en Configuración → Plantilla PDF.
- Carpeta
assets/resultados/con permisos de escritura — se crea automáticamente conmkdir()la primera vez. Si no se crea, crea la carpeta manualmente y dale permisos755. - Cron configurado (ver Paso 6) — para limpiar ZIPs caducados automáticamente.
Cómo generar el primer resultado
assets/resultados/{año}/T1.zip ... T4.zip.
resultado_publico.php?token=XYZ) donde puede ver y descargar los ZIPs por trimestre.
Novedades v0.5.6
- Editar resultado — click en cualquier fila de la lista abre el modal con los datos precargados. Permite cambiar email del contable, nombre, observaciones y estado.
- Botón descarga ZIP por trimestre — icono en la columna de acciones con dropdown hover que muestra T1/T2/T3/T4. Solo aparecen los trimestres que existen en disco.
- Generación compatible con hosting compartido — la generación del ZIP ya no requiere
exec()nipcntl. Compatible con Hostalia y cualquier hosting con PHP 7.4+ sin esas funciones. - Email al contable rediseñado — mismo diseño visual que el email de facturas. Tabla de contenido con Excel, ZIPs y desglose trimestral.
- Nuevo endpoint
modules/resultados/update.php— gestiona la edición de datos del resultado desde el panel.
ALTER TABLE requerido para v0.5.6
Si vienes de v0.5.5, ejecuta este SQL en phpMyAdmin antes de usar el módulo:
ALTER TABLE `resultados_anuales`
ADD COLUMN `email_tracking_id` VARCHAR(64) NULL AFTER `enviado_at`,
ADD COLUMN `email_abierto` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_tracking_id`,
ADD COLUMN `email_abierto_at` DATETIME NULL AFTER `email_abierto`;
modules/resultados/cleanup.php para limpiar.VeriFactu Fase A genera un QR en cada factura que apunta a un visor en el propio servidor donde el cliente o Hacienda pueden verificar la factura.
pdf_render.php:
https://tudominio.com/systema/modules/facturacion/pdf_render.php
{{qr_code}} en la plantilla
En Configuración → Plantilla PDF, coloca el marcador {{qr_code}} donde quieras que aparezca el QR en la factura. Normalmente en la cabecera junto al número de factura.
public_token generan el token automáticamente la primera vez que se exportan o envían.
Una vez instalado, accede a tudominio.com/systema/status.php y pulsa REFRESH. El panel escanea 9 sectores del sistema y te dice exactamente qué está bien y qué no.
| Sector | Qué verifica | Resultado esperado |
|---|---|---|
| A · DB Engine | Conexión MySQL, versión, uptime | NOMINAL |
| B · Index Integrity | Los 20 índices de rendimiento v0.4 | NOMINAL todos en verde |
| C · Table Sizes | Tamaño y filas de cada tabla | NOMINAL |
| D · SMTP Stack | Configuración SMTP, tracking | NOMINAL si has configurado SMTP |
| E · PDF Engine | dompdf, Masterminds, FPDF, FPDI, /tmp | NOMINAL si instalaste dompdf |
| F · AEAT Presentador | Plantillas M303, M130, M390 | NOMINAL |
| G · PHP Runtime | Versión PHP, memoria, timeouts | NOMINAL con PHP 7.4+ |
| H · Extensions | PDO, cURL, OpenSSL, mbstring, JSON, GD | NOMINAL todas en verde |
| I · Disk & Storage | Espacio libre, /tmp escribible, config | NOMINAL |
| J · Core File Manifest | Lista los 94 archivos del core con indicador verde/rojo de existencia en disco en tiempo real | NOMINAL todos en verde |
El login redirige a configuracion.php
Las credenciales de BD en settings.php son incorrectas o la BD no está creada. Verifica db_host, db_user, db_pass y db_name. En algunos hostings el host no es localhost sino algo como PMYSQL112.dns-servicio.com.
La exportación PDF no funciona
dompdf no está instalado. Verifica en status.php → Sector E. Instala dompdf siguiendo el Paso 5.
El login muestra "Licencia caducada"
Causas posibles:
- El token no se inyectó — comprueba que
licencia_tokenensettings.phpno está vacío. - El
licencia_secretensettings.phpno coincide con elLIC_SECRETdel servidor central. - La licencia está pausada en el panel central.
- Han pasado más de 7 días desde la última validación y la licencia está pausada.
La inyección del token falla
Comprueba que activate.php está en la raíz de Systema y que la URL introducida en el panel es exactamente https://dominio.com/systema (sin barra final, con https). Si el hosting del cliente bloquea llamadas entrantes, inyecta el token manualmente en settings.php.
El envío de emails no funciona
Usa el botón SMTP HANDSHAKE en status.php para verificar conectividad TCP, y luego TEST SEND EMAIL para verificar autenticación completa. El email de prueba llega a tu dirección email_from configurada.
El QR de VeriFactu aparece roto en el PDF
La extensión GD no está instalada (necesaria para generar el QR), o la verifactu_qr_base_url en Configuración no está bien configurada. Verifica ambas cosas en status.php.
Índices en rojo en status.php → Sector B
Usa el botón REINDEX ALL v0.5 en el Sector B del panel de status. Confirma en el modal de confirmación. Los índices se recrean automáticamente.
El estado del resultado se queda en "Procesando" v0.5.5
El generate.php falló silenciosamente. Causas habituales:
- Sin plantilla PDF — ve a Configuración → Plantilla PDF y comprueba que hay HTML guardado.
- dompdf no instalado — verifica en
status.php→ Sector E. - Sin permisos en
assets/resultados/— crea la carpeta manualmente y dale permisos755. - Timeout de PHP — verifica que
max_execution_timeenstatus.php→ Sector G sea ≥ 300s.
Para depurar, accede directamente a: tudominio.com/systema/modules/resultados/generate.php?id=1 y observa si hay error.
Los ZIPs del resultado no se descargan v0.5.5
El estado es "Preparado" pero los botones de descarga no aparecen en el portal del contable. Comprueba que los archivos T1.zip-T4.zip existen en assets/resultados/{año}/ vía FTP. Si no existen, regenera el resultado.
El cron de limpieza da error v0.5.5
Verifica que la ruta en el cron es correcta. La ruta completa en Hostalia/Plesk suele ser /var/www/vhosts/XXXXX.servicio-online.net/tudominio.com/systema/modules/resultados/cleanup.php. Usa el botón "Ejecutar ahora" en la tarea programada para ver la salida y confirmar que la ruta es correcta.
El email al contable da error 500 v0.5.6
Los campos SMTP en BD deben llamarse usuario, password, puerto y cifrado. Si actualizas desde v0.5.5, verifica en Configuración → SMTP que los datos están guardados. El botón SMTP HANDSHAKE en status.php confirma la conectividad.
El enlace del email al contable da 404 v0.5.6
El sistema generaba URLs con /modules/resultado_publico.php en lugar de /resultado_publico.php. Actualiza modules/resultados/send.php a v0.5.6 para corregirlo.
El estado del resultado se queda en «Procesando» en hosting sin exec() v0.5.6
En hostings compartidos como Hostalia, exec() y pcntl_fork() están desactivados. La v0.5.6 resuelve esto generando el ZIP en el mismo proceso PHP. Actualiza modules/resultados/create.php a v0.5.6.
El Sector J de status.php muestra archivos en rojo v0.5.6
Algún archivo del core no está en el servidor. El Sector J lista los 94 archivos con indicador verde/rojo en tiempo real. Sube los archivos en rojo por FTP y recarga la página.