Saltar a contenido

Bienvenido a TiFacturaOnlineNext

Si recién caés al proyecto, esta es tu puerta de entrada. TiFacturaOnlineNext es el backend headless de facturación electrónica AFIP de Tipre: un servicio que recibe datos de un comprobante, le pide a AFIP el CAE (la autorización fiscal), persiste el resultado y deja la factura lista para emitir. No tiene cara visible para el cliente final — lo consumen otros sistemas (un POS, un panel de operación) por SOAP y REST. Antes de abrir una sola clase, conviene entender qué problema resuelve, de dónde viene y por qué está armado como está.

Ver toda la documentación en PDF

Qué problema resuelve y para quién

En Argentina, ninguna factura es válida sin que AFIP la autorice. Esa autorización es un código —el CAE— que el organismo otorga comprobante por comprobante, online, por un web service SOAP (WSFEv1), tras autenticarte con un token firmado (WSAA). El problema operativo es doble: ese trámite es lento y frágil (depende de la red y de que AFIP esté arriba), y al mismo tiempo es obligatorio — sin CAE no hay venta facturada.

TiFacturaOnlineNext resuelve eso encapsulando todo el diálogo con AFIP detrás de un contrato estable:

  • Emisión online (CAE). Recibe el comprobante, obtiene/renueva el token WSAA, firma el pedido, llama a WSFEv1 y devuelve el CAE. Toda la complejidad de certificados, firma CMS y reintentos queda adentro.
  • Operación offline (CAEA). Cuando AFIP no responde, el sistema usa un CAEA —un código de autorización anticipado, otorgado por adelantado para una quincena— para que el comercio pueda seguir facturando, e informa a AFIP en diferido lo emitido. Esa es la red de seguridad del negocio.

El cambio de fondo: migración Seam/JBoss → Spring Boot, sin reescribir el negocio

Este repo no es un sistema nuevo: es la migración de un backend legacy que corría sobre JBoss EAP 7 / Seam 2.3.1 / JAX-WS hacia Spring Boot 4 (Java 17, namespace jakarta). La regla de oro del proyecto —escrita en CLAUDE.md del repo de código— es que NO se altera la lógica de negocio: el CAE/CAEA emitido, el WSDL publicado, el contrato REST y los PDFs deben ser funcionalmente idénticos a producción. El cómo se logró eso es lo más interesante del proyecto y está en Migración Seam/JBoss → Spring Boot.

La idea central: "shim, no reescritura"

La dependencia del código legacy a Seam resultó superficial y mecánica (sin conversaciones, sin @Out, @In en sólo 3 clases). Por eso la estrategia no fue reescribir todo, sino construir una capa de compatibilidad (seam-compat) que reimplementa el subconjunto de la API de Seam que la app realmente usa, respaldada por Spring. Lo notable: esa capa vive en el paquete org.jboss.seam.* a propósito, para que el código de negocio compile sin tocar un solo import.

Concepto Qué significa acá
Shim La capa seam-compat: clases en org.jboss.seam.* que imitan a Seam pero por dentro son Spring.
Lift & shift El código de negocio (entidades, queries, cliente AFIP) se mueve tal cual, sólo se adapta a jakarta.*.
Rojo La minoría de clases acopladas a Seam Faces/Mail/Document/Security que se reescriben funcionalmente.

Por qué importa entender esto primero

Vas a abrir Trx.java y ver import org.jboss.seam.log.Logging; arriba de una entidad JPA. No es un error ni un olvido: es deliberado. Ese import resuelve contra seam-compat, no contra el Seam original. Si no sabés esto, vas a "arreglar" algo que está perfecto. El detalle vive en La capa seam-compat.

Qué expone el sistema

TiFacturaOnlineNext es un solo proceso Spring Boot que publica tres superficies:

graph TD
    subgraph Cliente["Consumidores"]
        POS["POS / sistema de ventas"]
        OPS["Operador<br/>(Cockpit UI)"]
    end

    subgraph App["TiFacturaOnlineNext — Spring Boot 4"]
        SOAP["SOAP (Apache CXF · SOAP 1.2)<br/>TrxWS · CaeaWS<br/>TiFacturaOnlineManagerWS"]
        REST["REST (Spring MVC)<br/>/caeaWS · /fecaeaSolicitar · /api/cockpit"]
        JOBS["Jobs Quartz<br/>(tabla Tareas)"]
        CORE["Lógica de negocio<br/>(lift & shift sobre seam-compat)"]
        SOAP --> CORE
        REST --> CORE
        JOBS --> CORE
    end

    DB[("SQL Server")]
    AFIP["AFIP / ARCA<br/>WSAA + WSFEv1<br/>(SOAP · red externa)"]

    POS -->|"SOAP + REST"| SOAP
    POS -->|"REST"| REST
    OPS -->|"REST /api/cockpit"| REST
    CORE -->|"JPA / Hibernate"| DB
    CORE -.->|"SOAP firmado (CMS)<br/>red externa"| AFIP

Los bordes externos del sistema

El proceso es uno solo, pero tiene dos dependencias de red que pueden fallar: SQL Server (persistencia) y AFIP/ARCA (la autorización fiscal, por SOAP). El borde con AFIP es el delicado: requiere certificado .p12, firma CMS con BouncyCastle, y un token WSAA que se renueva y se cachea. Cuando ese borde se cae, entra a jugar el CAEA. El detalle del diálogo con AFIP está en Cliente AFIP y el flujo completo en El ciclo de facturación.

El stack, de un vistazo

Los datos exactos (versiones, dependencias por SPEC) están en Backend TiFacturaOnlineNext. El resumen:

Pieza Valor (verificado en pom.xml)
Runtime Spring Boot 4.0.7 (Spring Framework 7)
Lenguaje / JDK Java 17, namespace jakarta.*
Persistencia Spring Data JPA / Hibernate 7.2.x, SQL Server (mssql-jdbc)
SOAP Apache CXF 4.2.2 (cxf-spring-boot-starter-jaxws), contract-first
REST Spring MVC (@RestController)
Scheduling Quartz (spring-boot-starter-quartz), tareas desde la tabla Tareas
Firma CMS / WSAA BouncyCastle 1.78.1 (bcprov/bcpkix-jdk18on)
Compatibilidad seam-compat propio (paquetes org.jboss.seam.*)
artifactId tifactura-spring · grupo com.tipre · main class com.tipre.tifacturaonlinemanager.Application

Atención con el JDK

El EMPEZAR-ACA.md del repo de código advierte: para el proyecto real usá JDK 17 (LTS). En JDK 21/25 los stubs JAXB/JAX-WS viejos de AFIP y CXF pueden romper por encapsulación/reflection. No te ahorres ese dolor de cabeza.

Cómo leer esta documentación

El onboarding es un recorrido en tres tramos. No saltees el primero por más que quieras tocar código ya.

  1. Entender el sistema (estás acá). Seguí con Arquitectura del sistema para captar cómo encajan las piezas, y con Migración Seam/JBoss → Spring Boot para entender la estrategia "shim, no reescritura" que explica casi todas las decisiones raras del código. La capa seam-compat y las Invariantes sagradas son lo que no podés romper. Cuando aparezca un término que no conozcas —CAE, CAEA, WSAA, WSFEv1, ente facturador, punto de venta— está definido en el Glosario del dominio.

  2. Referencia técnica. Acá viven los datos exactos: el modelo de dominio, la persistencia, el cliente AFIP, las APIs SOAP y REST, los jobs Quartz, el Cockpit y la configuración por perfiles. El cliente AFIP y el ciclo de facturación son lo más delicado: leelos enteros antes de tocar nada que los roce.

  3. Empezar a programar. Recién entonces levantás el backend en local contra SQL Server y AFIP de homologación. El material de arranque está en Setup del entorno.

Regla de oro del proyecto

No se altera el comportamiento observable. El diff del WSDL es bloqueante: ningún cambio que altere el WSDL publicado se mergea sin aprobación. Si un test de paridad falla, el fix iguala al legacy — no "mejora" la lógica. Y si para que algo compile tenés que tocar una clase de negocio, casi siempre falta algo en seam-compat: agregalo ahí, no en el negocio.