Saltar al contenido principal

Pendientes para Producción — OnnixConnect SIFEN

Última actualización: 2026-04-10 Propósito: Checklist de todo lo que hay que ajustar/configurar antes y durante el deploy a producción.


1. Infraestructura del servidor

1.1 Crontab del sistema (FAC-83)

* * * * * cd /var/www/onnixconnect && php artisan schedule:run >> /dev/null 2>&1
  • El scheduler dispara SincronizarEstadosSifenJob cada 5 minutos.
  • Doc completa: docs/guias-tecnicas/SCHEDULER_Y_CRON_SETUP.md

1.2 Supervisor para Horizon / queue:work (FAC-96)

Crear /etc/supervisor/conf.d/onnixconnect-worker.conf:

[program:onnixconnect-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/onnixconnect/artisan queue:work redis --queue=critica,lotes,default --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/onnixconnect/worker.log
stopwaitsecs=3600
sudo supervisorctl reread && sudo supervisorctl update
sudo supervisorctl start onnixconnect-worker:*

1.3 Redis

  • Verificar que Redis esté corriendo y accesible desde el servidor.
  • REDIS_HOST, REDIS_PORT, REDIS_PASSWORD en .env.
  • Horizon depende de Redis para las colas.

1.4 PostgreSQL

  • Migrar: php artisan migrate --force.
  • Tabla nueva: sifen_eventos (migración 2026_04_09_140000).
  • Verificar que las tablas sifen_emitters, sifen_dtes, sifen_dte_items, sifen_logs existan.

2. Configuración del .env de producción

# SIFEN
SIFEN_ENV=prod # ← cambiar de 'test' a 'prod'
SIFEN_SSL_VERIFY=true

# App
APP_ENV=production
APP_DEBUG=false
APP_URL=https://facturacion.onnixsa.com.py

# Queue
QUEUE_CONNECTION=redis

# Log
LOG_CHANNEL=daily # o 'stack' con daily + slack para alertas
LOG_LEVEL=info

2.1 Endpoints de producción (ya configurados en config/sifen.php)

sync https://sifen.set.gov.py/de/ws/sync/recibe
async https://sifen.set.gov.py/de/ws/async/recibe-lote
evento https://sifen.set.gov.py/de/ws/eventos/evento
consulta https://sifen.set.gov.py/de/ws/consultas/consulta
consulta_lote https://sifen.set.gov.py/de/ws/consultas/consulta-lote
consulta_ruc https://sifen.set.gov.py/de/ws/consultas/consulta-ruc
qr https://ekuatia.set.gov.py/consultas/qr?

NOTA: Los endpoints de prod NO llevan .wsdl al final (a diferencia de test). Verificar que config/sifen.php los tenga correctos antes de deploy.


3. Certificado digital

  • Subir el archivo .p12 de producción a storage/app/private/sifen/certs/.
  • Configurar cert_p12_path y cert_p12_password_enc (cifrado AES-256-CBC de Laravel) en la tabla sifen_emitters.
  • Verificar con: php artisan tinker --execute="app(\App\Domains\Sifen\Services\Signing\CertificadoService::class)->extraerPem(\App\Domains\Sifen\Models\SifenEmitter::find(1));"
  • El certificado debe ser el de producción emitido por Documenta/eSign para el RUC del emisor.
  • Verificar fecha de vencimiento del cert — renovar antes de que expire.

4. Timbrado de producción

  • Crear registro en sifen_emitters con el timbrado vigente de producción.
  • Verificar dFeIniT (fecha inicio del timbrado) sea correcta.
  • Los números de documento deben ser correlativos sin saltos — si hay saltos, inutilizar los rangos antes de emitir.

5. Datos del emisor

  • Verificar que dNomEmi en producción sea la razón social real (no el texto de prueba "DE generado en ambiente de prueba...").
  • Confirmar: RUC, DV, dirección, departamento, distrito, ciudad, teléfono, email, actividades económicas.
  • dNomFanEmi (nombre fantasía) debe ser el registrado en la SET.

6. Logs y monitoreo

6.1 Rotación de logs

# Laravel ya rota con LOG_CHANNEL=daily (14 días por defecto)
# Verificar en config/logging.php que 'days' => 30 para producción

6.2 Logs SOAP en disco

Los request/response SOAP se guardan en storage/app/private/sifen/logs/{Y-m}/.

  • En producción estos crecen — configurar limpieza periódica (ej. borrar logs > 90 días).
  • Agregar al scheduler:
Schedule::command('model:prune --model=SifenLog')->daily();
// o un command custom para limpiar storage/app/private/sifen/logs/

6.3 Sentry (FAC-91/92 — pendiente)

  • Configurar SENTRY_LARAVEL_DSN en .env.
  • Las excepciones de SifenConnectionException y RuntimeException en las Actions se loguean pero también deberían reportarse a Sentry.

7. Seguridad

  • APP_DEBUG=false en producción (NUNCA true).
  • APP_KEY debe ser única por ambiente — no compartir entre test/prod.
  • Sanctum: verificar SANCTUM_STATEFUL_DOMAINS en .env.
  • Rate limiting en endpoints de auth (throttle:login ya configurado).
  • HTTPS obligatorio — APP_URL=https://....
  • El archivo .p12 y la APP_KEY nunca deben estar en el repo.

8. Tests pre-deploy

8.1 Smoke test rápido (5 minutos)

# 1. Verificar que el server responde
curl https://facturacion.onnixsa.com.py/api/sifen/health

# 2. Verificar certificado
php artisan tinker --execute="app(\App\Domains\Sifen\Services\Signing\CertificadoService::class)->extraerPem(\App\Domains\Sifen\Models\SifenEmitter::find(1));"

# 3. Verificar scheduler
php artisan schedule:list

# 4. Verificar workers
supervisorctl status onnixconnect-worker:*

# 5. Verificar Redis
redis-cli ping

8.2 Test funcional (con factura real de prueba)

  1. Emitir 1 factura sync: POST /api/sifen/dtes/sync → debe dar 0260.
  2. Emitir 2 facturas como lote: POST /api/sifen/dtes/lote → debe dar 0300, luego esperar 5 min y verificar approved.
  3. Cancelar la factura sync: POST /api/sifen/eventos/cancelacion → debe dar 0600.
  4. Inutilizar un rango pequeño: POST /api/sifen/eventos/inutilizacion → debe dar 0600.
  5. Consultar DTE cancelado: GET /api/sifen/dtes/{id}cancelado: true.

9. Migración de datos del legacy (si aplica)

  • Definir si se migran DTEs históricos del sistema Java al OnnixConnect.
  • Si se migran: importar CDCs, estados y números de documento para evitar colisiones de numeración.
  • Si NO se migran: definir desde qué número arranca OnnixConnect y inutilizar los anteriores.

10. Pendientes de código (no bloqueantes para deploy)

PendienteTicketPrioridad
KuDE PDF con watermark "CANCELADO" para DTEs cancelledMedia
Panel Filament v3 (Empresa, Cert, Usuario, Rol)FAC-90Media
Sentry Self-HostedFAC-91Media
Instrumentar con tags SentryFAC-92Baja
Prometheus + exportersFAC-93Baja
Prueba de estrés 4500 comprobantesFAC-94Alta (pre-prod)
Prueba resiliencia fallo Redis mid-loteFAC-95Media
Deploy en Plesk + SupervisorFAC-96Alta (bloqueante)
Endpoints prod sin .wsdl — verificar que funcionenAlta
Redis Cache Tags para estados de comprobantesFAC-85Baja
Componente MonitorLoteFacturas (polling)FAC-86Media
Componente ComprobantesRechazados + reenvíoFAC-87Media
Componente ControlIngresoSifen (50k+ paginado)FAC-88Media
Componentes UI Cancelación/InutilizaciónFAC-89Media

11. Checklist final pre-deploy

  • .env configurado con SIFEN_ENV=prod
  • Endpoints de prod sin .wsdl (verificar contra SIFEN prod)
  • Certificado .p12 de producción subido y verificado
  • Timbrado de producción registrado en sifen_emitters
  • Razón social real en dNomEmi (no texto de prueba)
  • php artisan migrate --force ejecutado
  • Crontab configurado
  • Supervisor + workers corriendo
  • Redis operativo
  • APP_DEBUG=false, APP_ENV=production
  • HTTPS configurado
  • Smoke test pasado (health + cert + factura sync + lote + cancelación)
  • Logs verificados en laravel.log y sifen/logs/
  • Backup de BD antes de la primera factura real