Corregir o anular una factura emitida
Una factura emitida no se edita. Para deshacerla o corregirla tienes cuatro caminos, y elegir bien importa: cada uno deja un rastro fiscal distinto.
Qué camino tomar
| Quieres… | Acción | Resultado |
|---|---|---|
| Dejar sin efecto la factura entera | Anular | La original pasa a canceled; se remite un registro de anulación a la AEAT. |
| Corregir el contenido de una factura correcta entregada al cliente | Rectificar | Nueva factura R1–R5 que corrige a la original. |
| Emitir una completa que sustituya a una o varias simplificadas (F2) | Sustituir | Nueva F3 que reemplaza a las F2. |
| Reenviar un registro rechazado por la AEAT por un error de remisión | Subsanar | Mismo número; se reenvía con Subsanacion=S. |
Rectificar ≠ subsanar
- ¿La AEAT rechazó el registro por un dato mal enviado (típicamente un bug de integración)? → subsanar. Ver Subsanación.
- ¿La factura es correcta a ojos de la AEAT pero el contenido tiene un error (importe, concepto…) y ya la entregaste? → rectificar.
Solo se puede subsanar una factura cuyo último registro de alta esté rejected.
Anular
Operación poco habitual
Anular es solo para una factura emitida por error —una que nunca debió existir—, no para corregir una factura válida. Para cambiar importes, conceptos o datos de una factura ya entregada se emite una rectificativa, no se anula. No forma parte de ningún flujo del día a día: si te ves anulando a menudo, casi siempre lo correcto es rectificar.
curl -X POST https://api.test.bilteo.com/api/v1/invoices/{id}/actions/cancel \
-H "Authorization: Bearer bk_live_xxx"Scope invoices:cancel. Requiere que el último registro Veri*Factu esté aceptado por la AEAT (no puedes anular lo que aún no consta). Genera un registro de anulación encadenado. La factura pasa a canceled.
Rectificativas (R1–R5)
POST /invoices/{id}/actions/rectify crea una rectificativa (en borrador) a partir de una factura emitida, enlazada a la original. Tú revisas y emites la rectificativa cuando quieras.
curl -X POST https://api.test.bilteo.com/api/v1/invoices/{id}/actions/rectify \
-H "Authorization: Bearer bk_live_xxx" -H "Content-Type: application/json" \
-d '{ "rectificative_type": "S", "rectification_cause": "law_error" }'Dos ejes
rectificative_type — cómo se expresa la corrección:
S(sustitución) — la rectificativa contiene los importes correctos totales; sustituye a la original.I(diferencias) — la rectificativa contiene solo el delta (con signo negativo si procede).
rectification_cause — el porqué legal, que determina el R-type:
| Origen | rectification_cause | R-type resultante |
|---|---|---|
| F1 | law_error o art80_126 | R1 |
| F1 | art80_3 (concurso de acreedores) | R2 |
| F1 | art80_4 (créditos incobrables) | R3 |
| F1 | other | R4 |
| F2 | simplified | R5 |
Reglas que aplica el backend:
- Una F2 solo se rectifica con causa
simplified(→ R5). Otra causa →400. - La causa
simplifiedsolo vale para F2/R5; sobre una F1 →400. - Una F3 no se rectifica directamente (emite una F3 negativa y una nueva).
- Una rectificativa no se vuelve a rectificar.
serie_id es opcional: si la serie de la original es válida para el R-type, se reutiliza; si no, debes pasar una serie de tipo rectified.
Sustitutivas (F2 → F3)
Cuando una venta se documentó como simplificada (F2) y luego el cliente pide factura completa, emites una sustitutiva (F3). El asistente lo hace en un paso desde la F2 emitida:
curl -X POST https://api.test.bilteo.com/api/v1/invoices/{f2_id}/actions/replace \
-H "Authorization: Bearer bk_live_xxx" -H "Content-Type: application/json" \
-d '{ "partner_id": "…" }'Esto crea una F3 (borrador) para ese partner_id, la enlaza como sustituta de la F2 y recalcula sus líneas agrupando las bases de la F2 por combinación de impuestos. Moneda y actividad económica se heredan de la F2; serie_id es opcional (default de F3). Scope invoices:replace_simplified.
Pasa ?issue=true para emitir la F3 en la misma petición (requiere también invoices:issue). La operación es atómica: si la emisión falla, la F3 no queda a medias.
Sustituir varias F2
Una F3 puede sustituir a varias simplificadas. Gestiona el conjunto con el sub-recurso /replaces:
| Endpoint | Efecto |
|---|---|
GET /invoices/{f3}/replaces | Lista las F2 que sustituye esta F3. |
POST /invoices/{f3}/replaces | Añade una F2 al conjunto y recalcula las líneas de la F3. |
DELETE /invoices/{f3}/replaces/{relation_id} | Quita una F2 y recalcula. |
Cada F2 sustituida pasa a estado replaced.
Ver también
- Ciclo de vida — la máquina de estados completa.
- Subsanación — el camino para registros rechazados.
- Recetario — ejemplos de rectificar y anular.