Repository navigation
Tipos de Factura
El SDK soporta todos los tipos de factura definidos por la AEAT a través del enum InvoiceType:
| Enum | Código AEAT | Descripción |
|---|---|---|
InvoiceType.F1 |
F1 | Factura (art. 6, 7.2 y 7.3 RD 1619/2012) — factura estándar |
InvoiceType.F2 |
F2 | Factura simplificada (art. 7.2 y 7.3 RD 1619/2012) |
InvoiceType.F3 |
F3 | Factura emitida en sustitución de facturas simplificadas facturadas y declaradas |
InvoiceType.F4 |
F4 | Asiento resumen de facturas. No admitido: el esquema de la AEAT que usa el SDK no lo incluye |
InvoiceType.R1 |
R1 | Rectificativa (art. 80.1, 80.2 y 80.6 LIVA) |
InvoiceType.R2 |
R2 | Rectificativa (art. 80.3 LIVA) |
InvoiceType.R3 |
R3 | Rectificativa (art. 80.4 LIVA) |
InvoiceType.R4 |
R4 | Rectificativa (resto de causas) |
InvoiceType.R5 |
R5 | Rectificativa de facturas simplificadas |
Para rectificativas (R1-R5), ver la página específica: Facturas rectificativas.
invoice.setInvoiceType(InvoiceType.F1); // Recomendado: usando el enum
invoice.setInvoiceType("F1"); // Alternativa legacy: usando el código como String (deprecated)Invoice.getInvoiceType() (heredado de la interfaz VeriFactuInvoice) siempre devuelve el código como String; usa Invoice.getInvoiceTypeEnum() si necesitas el enum de vuelta.
Cada factura necesita al menos un Breakdown (desglose). El constructor recibe códigos AEAT en formato String, no enums:
public Breakdown(String claveRegimen, String calificacionOperacion,
double taxRate, double baseAmount, double taxAmount)-
claveRegimen: código deClaveRegimen— usaRegimeType.XXX.getCode()para no memorizar los códigos numéricos (p. ej.RegimeType.GENERAL.getCode()→"01"). -
calificacionOperacion: código deCalificacionOperacion— usaOperationType.XXX.getCode()(p. ej.OperationType.S1.getCode()→"S1", sujeta y no exenta sin inversión del sujeto pasivo). -
taxRate: tipo impositivo en porcentaje (21.0,10.0,4.0,0.0...). -
baseAmount/taxAmount: base imponible y cuota repercutida.
⚠️ No existe una claseTaxType. Si ves referencias aTaxType.IVAen código o documentación antigua, es un error — ese tipo nunca existió en el SDK.
| Enum | Código | Descripción |
|---|---|---|
RegimeType.GENERAL |
01 | Régimen general |
RegimeType.EXPORTACION |
02 | Exportación |
RegimeType.BIENES_USADOS |
03 | Bienes usados |
RegimeType.ORO_INVERSION |
04 | Oro de inversión |
RegimeType.AGENCIAS_VIAJES |
05 | Agencias de viajes |
RegimeType.GRUPO_ENTIDADES |
06 | Grupo de entidades (nivel avanzado) |
RegimeType.CRITERIO_CAJA |
07 | Criterio de caja |
RegimeType.IPSI_IGIC |
08 | IPSI / IGIC |
| ... | 09-15 | Ver RegimeType.java para el resto (agencias mediadoras, cobros por cuenta de terceros, arrendamientos, IVA pendiente de devengo, inversión del sujeto pasivo) |
| Enum | Código | Descripción |
|---|---|---|
OperationType.S1 |
S1 | Sujeta y no exenta — sin inversión del sujeto pasivo |
OperationType.S2 |
S2 | Sujeta y no exenta — con inversión del sujeto pasivo |
OperationType.S3 |
S3 | Sujeta y exenta |
OperationType.N1 |
N1 | No sujeta por reglas de localización |
OperationType.N2 |
N2 | No sujeta por otras causas |
Reglas de envío de la AEAT según la calificación: en S1 el tipo impositivo y la cuota repercutida son obligatorios; en S2 (solo F1, F3 y R1-R4) el SDK envía tipo 0 y cuota 0, que la AEAT exige; en N1/N2 y en las operaciones exentas (Breakdown#setOperacionExenta, E1 a E8) no se envían tipo, cuota ni recargo, solo la base. El impuesto de cada línea es IVA por defecto; Breakdown#setTax("03") indica IGIC, "02" IPSI y "05" otros (las reglas de tipos y recargos de IVA solo se aplican al IVA).
Invoice invoice = new Invoice();
invoice.setInvoiceNumber("F2026-001");
invoice.setIssueDate(LocalDate.now());
invoice.setInvoiceType(InvoiceType.F1);
invoice.setTotalAmount(121.00);
invoice.setTaxAmount(21.00);
invoice.setBreakdowns(Collections.singletonList(
new Breakdown(RegimeType.GENERAL.getCode(), OperationType.S1.getCode(), 21.0, 100.00, 21.00)));Igual que la estándar, sin destinatario obligatorio:
Invoice invoice = new Invoice();
invoice.setInvoiceNumber("FS2026-001");
invoice.setIssueDate(LocalDate.now());
invoice.setInvoiceType(InvoiceType.F2);
invoice.setTotalAmount(12.10);
invoice.setTaxAmount(2.10);
invoice.setBreakdowns(Collections.singletonList(
new Breakdown(RegimeType.GENERAL.getCode(), OperationType.S1.getCode(), 21.0, 10.00, 2.10)));InvoiceType.F4 existe en el enum, pero el esquema de la AEAT que usa el SDK (ClaveTipoFacturaType) no lo incluye: InvoiceValidator lo rechaza ("Tipo de factura no admitido por la AEAT: F4") y AeatClient no lo envía.
Las facturas simplificadas que sustituye se indican con FacturasSustituidas (opcional para la AEAT, que solo la admite en F3). El emisor de cada una es el de la configuración salvo que se indique otro:
invoice.setInvoiceType(InvoiceType.F3);
invoice.setSubstitutedInvoices(Arrays.asList(
new InvoiceReference("FS2026-001", LocalDate.of(2026, 10, 2)),
new InvoiceReference("FS2026-002", LocalDate.of(2026, 10, 3))));Regla de la AEAT por tipo de factura (la AEAT rechaza el registro si no se cumple):
| Tipo | Destinatarios |
|---|---|
| F1, F3, R1, R2, R3, R4 | Obligatorios (al menos uno) |
| F2, R5 | No admitidos |
Un destinatario con NIF español se crea con nombre y NIF:
Recipient recipient = new Recipient("Cliente S.L.", "B12345674"); // nombre, NIF
invoice.setRecipients(Collections.singletonList(recipient));Con país y tipo de documento, el destinatario se envía en el bloque IDOtro (CodigoPais, IDType, ID) en lugar de NIF:
new Recipient("Client SARL", "FR12345678901", "FR", "02"); // nombre, identificador, país ISO 3166-1 alfa-2, tipo
new Recipient("John Smith", "P1234567", "GB", "03");| Tipo | Documento |
|---|---|
02 |
NIF-IVA (el prefijo del identificador ya indica el país) |
03 |
Pasaporte |
04 |
Documento oficial del país de residencia |
05 |
Certificado de residencia |
06 |
Otro documento probatorio |
07 |
No censado |
Reglas de la AEAT: con país ES solo valen los tipos 03 y 07; el tipo 07 exige país ES y se acepta con errores (hay que subsanarlo cuando el NIF se cense); el tipo 02 no necesita país, debe tener la estructura del NIF-IVA de un Estado miembro (por ejemplo FR + 11 caracteres, DE + 9 dígitos) y solo vale en F1, F3 y R1-R4; el identificador no puede superar 20 caracteres.
La marca FacturaSinIdentifDestinatarioArt61d = S solo se admite en F2 y R5, que no llevan destinatarios:
invoice.setInvoiceType(InvoiceType.F2);
invoice.setWithoutRecipientIdentification(true);Con la marca no se aplica el límite de 3.000 € de las facturas simplificadas. Una F1 sin destinatario no es válida: si no se puede identificar al cliente, emite una F2.
invoice.setQualifiedSimplified(true) envía FacturaSimplificadaArt7273 = S; solo vale en F1, F3 y R1-R4.
Ejemplos completos y compilables: InvoiceTypesExample.java.