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 sí 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.
-
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.
-
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.
-
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.