# Variables de entorno requeridas > **Leer antes del siguiente despliegue.** El arranque falla a propósito si los > secretos JWT siguen teniendo el valor que estuvo publicado en el repositorio. ## 1. Secretos que hay que definir sí o sí `.env` y `config.yml` estuvieron versionados con credenciales reales, así que **todo lo que aparecía ahí debe considerarse comprometido y rotarse**, no solo sacarse del repositorio: el historial de git lo sigue conteniendo. Genera cada valor con `openssl rand -hex 32` y cárgalos como variables de entorno del contenedor (en Coolify: *Environment Variables*): | Variable | Para qué sirve | Si no se define | |---|---|---| | `APP_JWT_SECRET` | Firma las cookies de sesión del panel | **El arranque se detiene** | | `API_JWT_SECRET` | Firma los tokens de la API v1 | **El arranque se detiene** | | `APP_KEY` | Cifra las contraseñas de SMTP e integraciones | Arranca, pero avisa en los logs | | `ADMIN_API_KEY` | Única llave de toda la API `/api/v2` | La API v2 responde 503 | Al rotar `APP_JWT_SECRET` se cierran las sesiones abiertas: hay que volver a iniciar sesión, nada más. ### Cuidado con `APP_KEY` `APP_KEY` cifra las contraseñas guardadas en la base de datos. Si la cambias, **las contraseñas cifradas con la clave anterior dejan de poder descifrarse** y hay que volver a guardarlas desde el panel: - Configuración SMTP (`/app/smtp-config`) - Credenciales de las pasarelas de pago (`/app/pasarelas`) - Cualquier otra integración con contraseña Por eso el sistema solo advierte en vez de detenerse: para que elijas el momento. ## 2. Otras credenciales a rotar Estaban en el `.env` versionado: - Contraseña de PostgreSQL - Contraseña del correo saliente - Cualquier token de integración (Coolify, Cloudflare, Hostinger, Telegram…) ## 3. Webhooks de pago Las notificaciones ahora **exigen firma válida**. Verifica en cada proveedor que el secreto de firma coincida con el configurado en `/app/pasarelas`: | Pasarela | URL del webhook | Requiere | |---|---|---| | Bold | `https://TU-DOMINIO/webhooks/bold` | Secret de firma en la config | | dLocal | `https://TU-DOMINIO/webhooks/dlocal` | Secret de firma en la config | | PayPal | `https://TU-DOMINIO/webhooks/paypal` | **Webhook ID** en la config | Para PayPal hay que crear el webhook en el panel de PayPal suscrito a los eventos `CHECKOUT.ORDER.APPROVED` y `PAYMENT.CAPTURE.COMPLETED`, y pegar el Webhook ID que devuelve en `/app/pasarelas`. Sin ese ID no se pueden verificar las notificaciones y se rechazan. > PayPal no opera en pesos colombianos. Los contratos que se cobren por PayPal > deben tener la moneda en USD (u otra soportada), o PayPal rechazará la orden. ## 4. Datos contables de ejemplo `SeedBalanceData` (27 transacciones de 2026 escritas en el código) ya **no** corre en cada arranque: si el contador editaba o borraba una, el siguiente reinicio la recreaba y el balance quedaba duplicado. Para cargarla puntualmente: ```bash SEED_BALANCE=1 ./apiv2 -config config.yml ``` ## 5. Archivos subidos `/uploads` ya no es público. Antes, sabiendo la ruta se podía descargar el RUT de un cliente o una factura sin iniciar sesión. Ahora requiere sesión en el panel; los clientes del portal siguen descargando sus documentos por los endpoints de siempre, que además validan que el archivo les pertenezca.