Repository navigation
Facturas Rectificativas
Las facturas rectificativas (InvoiceType.R1 a R5) requieren informar correctionType (obligatorio en R1-R5 y solo admitido en ellas) y, en general, la factura que corrigen (setRectifiedInvoices, opcional para la AEAT). El tipo de rectificación determina cómo interpreta la AEAT la corrección:
-
"S"(Sustitución): la nueva factura sustituye por completo a la original. Hay que informar además los importes originales en el bloqueImporteRectificacion. -
"I"(Por diferencia / Incremento): la factura rectificativa solo declara la diferencia respecto a la original. No se informaImporteRectificacion.
invoice.setCorrectionType("S"); // o "I"AeatClient mapea este valor a RegistroFacturacionAltaType.TipoRectificativa mediante ClaveTipoRectificativaType.fromValue(...).
Invoice invoice = new Invoice();
invoice.setInvoiceNumber("FR2026-001");
invoice.setIssueDate(LocalDate.now());
invoice.setInvoiceType(InvoiceType.R1);
invoice.setCorrectionType("S");
// Importes NUEVOS (los de esta factura rectificativa): base 150 + cuota 31,50
invoice.setTotalAmount(181.50);
invoice.setTaxAmount(31.50);
// Importes ORIGINALES de la factura que se corrige -> bloque ImporteRectificacion
invoice.setCorrectedBaseAmount(100.00);
invoice.setCorrectedTaxAmount(21.00);
invoice.setCorrectedSurchargeAmount(5.20); // Opcional: recargo de equivalencia original
invoice.setBreakdowns(Collections.singletonList(
new Breakdown(RegimeType.GENERAL.getCode(), OperationType.S1.getCode(), 21.0, 150.00, 31.50)));
invoice.setRectifiedInvoices(Collections.singletonList(
new InvoiceReference("F2026-001", LocalDate.of(2026, 1, 15)))); // la factura que se corrigeAeatClient solo construye el bloque ImporteRectificacion cuando:
-
correctionTypees"S", y - el tipo de factura es corrective (
R1-R5), y - tanto
correctedBaseAmountcomocorrectedTaxAmountno sonnull(correctedSurchargeAmountes opcional).
Si falta correctedBaseAmount o correctedTaxAmount en una rectificativa por sustitución, el registro no se envía: InvoiceValidator lo rechaza ("La rectificativa por sustitución necesita correctedBaseAmount y correctedTaxAmount") y la respuesta es status=error.
Invoice invoice = new Invoice();
invoice.setInvoiceNumber("FR2026-002");
invoice.setIssueDate(LocalDate.now());
invoice.setInvoiceType(InvoiceType.R1);
invoice.setCorrectionType("I");
invoice.setTotalAmount(29.00); // Solo la diferencia
invoice.setTaxAmount(5.00);
invoice.setBreakdowns(Collections.singletonList(
new Breakdown(RegimeType.GENERAL.getCode(), OperationType.S1.getCode(), 21.0, 24.00, 5.00)));
invoice.setRectifiedInvoices(Collections.singletonList(
new InvoiceReference("F2026-001", LocalDate.of(2026, 1, 15))));Los importes de una rectificativa por diferencias pueden ser negativos (p. ej. un abono): son legales y InvoiceValidator no los trata como error. No es necesario informar correctedBaseAmount/correctedTaxAmount en este caso.
| Tipo | Causa legal |
|---|---|
R1 |
Error fundado en derecho y las causas del art. 80.1, 80.2 y 80.6 LIVA |
R2 |
Art. 80.3 LIVA (concurso de acreedores) |
R3 |
Art. 80.4 LIVA (créditos incobrables) |
R4 |
Resto de causas |
R5 |
Rectificación de facturas simplificadas |
Consulta con tu asesoría fiscal la causa correcta para cada caso; el SDK no valida qué código R1-R5 corresponde a cada situación, solo transmite el que le indiques.
La factura que se corrige se indica con setRectifiedInvoices, una lista de InvoiceReference (IDFacturaRectificada en el XML):
invoice.setRectifiedInvoices(Arrays.asList(
new InvoiceReference("F2026-001", LocalDate.of(2026, 1, 15)), // mismo emisor que la configuración
new InvoiceReference("B12345674", "F2026-002", LocalDate.of(2026, 1, 20)))); // otro emisorCada referencia lleva número y fecha de expedición (el SDK la envía con formato dd-MM-yyyy) y, opcionalmente, el NIF del emisor. La AEAT solo admite esta agrupación en R1-R5. Si una rectificativa no indica ninguna, InvoiceValidator avisa (no bloquea): la factura rectificada se identifica así salvo en los rappels y casos autorizados por la AEAT. Las clases originalInvoiceNumber/originalIssueDate mencionadas en documentación antigua nunca existieron: esta es la forma de referenciar la original.
Ejemplos completos: InvoiceTypesExample.java (rectificativeBySubstitution() / rectificativeByDifference()).