ED06 - Comprobantes, DMS, factura electrónica: orden, trazabilidad retrógrada/progresiva

Problema

Un empresario empieza con el archivo de comprobantes y se enfrenta a la pregunta: ¿Cómo ordeno los comprobantes de forma conforme a GoBD y cómo los hago trazables?

La práctica actual en las pymes:

Afirmación central

El archivo de comprobantes conforme a GoBD significa:

  1. Cada comprobante tiene una identidad inequívoca (DocID): la uuidV7 (Object ID) ya es por sí sola la identidad inequívoca del comprobante, independientemente del nombre del archivo. Además, cada comprobante recibe un hash SHA-256 como comprobación criptográfica de integridad. La clave compuesta V7GUID:uuidV7 sirve para la organización del archivo (p. ej., por tipo de comprobante) y para las consultas de BD (p. ej., con EF Core en una Vertical App), no para la identidad en sí.
  2. Cada comprobante tiene un sidecar: .gc.md con clasificación (V7GUID), identidad del objeto (uuidV7), taxonomía, estado de obsolescencia, momento de registro (en uuidV7 como marca de tiempo de 48 bits). Excepción (a partir de 261011): los comprobantes que se incorporan a un proceso de firma (digital comprobante propio, p. ej., comprobante de restauración) llevan sus metadatos de sidecar completamente en *.gcsig.md (bloque source integrado, esquema gcsig-1.4); se elimina un .gc.md separado — sin sidecars en conflicto.
  3. Cada asiento contable referencia su comprobante: source_sha256 en la entrada del diario → comprobante
  4. Trazabilidad retrógrada: desde el asiento contable → comprobante → entrada del diario → uuidV7 se puede resolver
  5. Trazabilidad progresiva: desde el comprobante → asiento contable → libro mayor → balance de apertura se puede resolver
  6. Factura electrónica: el XML es el documento original, no el PDF (desde 2025, § 14 UStG, EN 16931)

Compliance by Design: el orden de los comprobantes no surge mediante una clasificación posterior, sino mediante campos obligatorios estructurales (SHA-256, V7GUID, sidecar) y pre-commit hooks que comprueban cada asiento contable en busca de referencia de comprobante.

Tipos de comprobante y sus particularidades GoBD

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart TD B["Beleg"] B --> P["Papierbeleg
(Scan erforderlich)"] B --> PDF["PDF-Beleg
(sonstige Rechnung)"] B --> EML["E-Mail
(EML + Anhang)"] B --> XML["E-Rechnung
(XML - Ur-Dokument)"] P --> S["Scan → SHA-256
+ Sidecar"] PDF --> SH["SHA-256
+ Sidecar"] EML --> EM["EML archiviert
+ Anhang extrahiert
+ Sidecar"] XML --> XV["XML unverändert
+ Sidecar
+ Validierung (EN 16931)"] style B fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style P fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style PDF fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style EML fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style XML fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style S fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style SH fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style EM fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style XV fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
Tipo de comprobante Particularidad GoBD Plazo de conservación
Comprobante en papel Se requiere escaneo (§ 147 Abs. 2 AO); el original puede destruirse si el escaneo cumple GoBD 8 años (§ 147 Abs. 3 AO)
Comprobante PDF («otra factura») Desde 2025 ya no es «factura electrónica»; SHA-256 + sidecar; ¿evaluable automáticamente? No: el PDF no está estructurado 8 años
Correo electrónico (EML + adjunto) El buzón de correo electrónico no es un archivo; la EML debe archivarse con el adjunto; verificación del remitente 6 años (§ 147 Abs. 1 Nr. 2/3 AO)
Factura electrónica (XML) El XML es el documento original (desde 2025, § 14 UStG); conservar sin cambios; validación EN 16931; evaluable automáticamente 8 años

Importante: factura electrónica desde 2025: Desde el 1 de enero de 2025, la factura electrónica es obligatoria para las operaciones B2B entre empresas nacionales (§ 14 UStG). Un PDF simple ya no es una factura electrónica: es una «otra factura». Solo existe factura electrónica cuando se emite, transmite y recibe en un formato electrónico estructurado (XML, EN 16931). Véase ED01 «Factura electrónica: los formatos XML son documentos originales en la AO».

Clasificación de comprobantes en el repositorio Git

Estructura de directorios

ORG-1/sources/                    # Belegarchiv (Tenant: ORG-1)
├── eingangsrechnungen/           # Eingangsrechnungen (Lieferanten)
│   ├── 260815/                   # Nach Datum (YYMMDD)
│   │   ├── rechnung_001.xml      # E-Rechnung (XRechnung)
│   │   ├── rechnung_001.xml.gc.md  # Sidecar
│   │   └── rechnung_002.pdf      # Sonstige Rechnung (PDF)
│   │   └── rechnung_002.pdf.gc.md  # Sidecar
├── ausgangsrechnungen/           # Ausgangsrechnungen (Kunden)
├── lohnbelege/                   # Lohnabrechnungen
├── sv-bescheide/                 # SV-Bescheide, VBG-Bescheide
├── vertraege/                    # Verträge (periodenübergreifend)
├── korrespondenz/                # E-Mails, Briefe
└── sonstige/                     # Sonstige Belege

Sidecar por comprobante (obligatorio)

Cada comprobante recibe un sidecar .gc.md con la clave compuesta V7GUID:uuidV7:

{
  "$schema": "https://gitcover.org/schemas/v7g-sidecar-2.0.schema.json",
  "V7GUID": "<V7GUID-Class-aus-Registry>",
  "docUid": "019f2c6f-0900-7001-8000-000000000001",
  "sha256": "ab94670c0dd8499c27ef2feddd1d9c5925977d55a52150a6fca0f6567d2e5e79",
  "title": "260815_Rechnung_001.xml",
  "original_filename": "Rechnung_001.xml",
  "locations": [
    {
      "unc_path": "./ORG-1/sources/eingangsrechnungen/260815/rechnung_001.xml",
      "from": "260815",
      "to": null,
      "note": "Primärspeicherort"
    }
  ],
  "v7g_taxonomy": [
    {
      "v7guid": "019f2c6f-0900-7000-8000-000000000000",
      "taxonomy": "ORG-1/Eingangsrechnung",
      "valid_from": "260815",
      "valid_to": null,
      "note": "Tenant: ORG-1, Category: Eingangsrechnung, Sphäre: wirtschaftlich"
    }
  ],
  "gcpn": {
    "prima_nota_ref": "GB-2026-08-001",
    "journal_entry_ref": "J-2026-08-001"
  },
  "obsolescence": {
    "status": "active",
    "superseded_by": null,
    "superseded_at": null
  }
}

Clave compuesta V7GUID:uuidV7: organización del archivo y consulta:

  • uuidV7 (Object ID): ya es por sí sola la identidad única (DocID) del comprobante, generada con una marca de tiempo predefinida, con la marca de tiempo de 48 bits anclada en el GUID
  • V7GUID (Class): clasifica el tipo de comprobante desde el registro de .gitcover (tipo de comprobante, organización del archivo, consulta de BD en la Vertical App con EF Core)
  • v7g_taxonomy[].v7guid: Object ID del comprobante clasificado
  • gcpn.prima_nota_ref / journal_entry_ref: referencia cruzada al libro mayor/diario (trazabilidad progresiva)
  • La clave compuesta V7GUID:uuidV7 sirve para la organización del archivo y la consulta; la identidad del comprobante es la uuidV7 por sí sola
  • No hay un campo datetime separado: el tiempo está en uuidV7

Trazabilidad retrógrada y progresiva

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart LR subgraph RET["Retrograd (Prüfer vom Buchungssatz rückwärts)"] direction LR BS["Buchungssatz
SKR04 6000 an 1600"] BS --> SR["source_sha256
im Tagebucheintrag"] SR --> BE["Beleg
(SHA-256 match)"] BE --> SC["Sidecar .gc.md
V7GUID:uuidV7"] SC --> DE["Tagebucheintrag
uuidV7"] end subgraph PRO["Progressiv (Prüfer vom Beleg vorwärts)"] direction LR BE2["Beleg
(SHA-256)"] BE2 --> SC2["Sidecar .gc.md
gcpn.journal_entry_ref"] SC2 --> BS2["Buchungssatz
SKR04"] BS2 --> GB["Grundbuch
(JSON)"] GB --> EB["Eröffnungsbilanz"] end style BS fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style SR fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style BE fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style DE fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style BE2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style BS2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style GB fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style EB fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
Dirección Inicio Resolución mediante Destino Referencia GoBD
Retrógrada Asiento contable (SKR04) source_sha256 → comprobante → sidecar uuidV7 Entrada del diario Rz. 146 (trazabilidad)
Progresiva Comprobante (SHA-256) Sidecar gcpn.journal_entry_ref → asiento contable → libro mayor Balance de apertura Rz. 147 (verificabilidad)

Referencia GoBD: La trazabilidad retrógrada corresponde a GoBD Rz. 146 (trazabilidad: «un tercero experto en un tiempo razonable»). La trazabilidad progresiva corresponde a GoBD Rz. 147 (verificabilidad). Ambas están garantizadas by Design mediante SHA-256 + V7GUID + sidecar, no mediante referencias cruzadas manuales.

Localización: docUid en lugar de nombre/ruta (261026)

Cada referencia de comprobante en una factura contiene la docUid del comprobante original, no el nombre ni la ruta: en el XML como cac:AdditionalDocumentReference/cbc:ID (uuidV7), en el sidecar/GCPN como docUid. El registro DMS adopta la misma docUid como object_id; no inventa una segunda identidad. Así, un comprobante se puede localizar de forma inequívoca mediante la docUid, aunque se renombre o se mueva.

La Action que crea o almacena un comprobante se gestiona como pgid (puerta de enlace de proceso, clase V7GUID): produced_by_pgid para la creación (p. ej., creación de factura 180), stored_by_pgid para el registro DMS (p. ej., 183). Catálogo: GCUV/TOP/compliance/process_gateways.json; valores normativos de 8 bits: OSS/TOP/.gitcover/dictionaries/gateway_ids.json.

GCPN de un solo archivo: Para cada factura existe un .gcpn.md, que contiene el XML (documento original) y el PDF (vista) en documents[], el flujo de trabajo create→pdf→present→accept→sign→register, así como events y relations (contrato/comprobantes de costes). XML/PDF siguen siendo archivos separados; se elimina un .gc.md separado. De forma progresiva (Rz. 147) se lee desde el GCPN hacia los documentos; de forma retrógrada (Rz. 146), desde la docUid en el DMS, pasando por el GCPN, hasta los comprobantes.

Regla de promoción: Tras el escaneo del repositorio y la creación del sidecar, un .gc.md puede enriquecerse en el GCPN; los datos JSON del sidecar se incorporan (GCPN = superconjunto, .gc.md = subconjunto). Después, el .gc.md separado es redundante y puede eliminarse; la historia de Git sigue siendo la prueba GoBD, el GCPN es la SSoT.

Identidad de factura: invoice_id es una uuidV7 (criterio de ordenación/referencia); invoice_no es solo texto. Seller/Buyer se referencian mediante su Party-uuidV7 (creditor/vendor o debitor/customer), no mediante nombres reales (PII).

Factura electrónica: el XML es el documento original

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart TD ER["E-Rechnung empfangen
(XML oder ZUGFeRD)"] ER --> V["Validierung
EN 16931 / XRechnung-Schema"] V -->|gültig| A["Ablage im Git-Repo
XML unverändert"] V -->|ungültig| R["Fehler-Logging
+ manuelle Prüfung"] A --> S["Sidecar .gc.md
SHA-256 + V7GUID:uuidV7"] S --> B["Buchungssatz
source_sha256 → XML"] B --> N["Nachverfolgbarkeit
retrograd + progressiv"] style ER fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style V fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style A fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style R fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style S fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style B fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style N fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33

XRechnung vs. ZUGFeRD

Formato Estructura Documento original Visualización
XRechnung XML puro (EN 16931) Archivo XML Se requiere visor de XML (p. ej., ELSTER (e-rechnung.elster.de)[https://e-rechnung.elster.de]
ZUGFeRD Híbrido: PDF + XML incorporado Parte XML (determinante desde 2025, BMF FAQ 12a) Imagen PDF (solo visualización auxiliar)

Importante: ZUGFeRD desde 2025: En caso de discrepancias entre la parte XML y la parte de imagen PDF, desde 2025 es determinante la parte estructurada (XML) (BMF FAQ Frage 12a). La imagen PDF ya no es la que prevalece. El sidecar debe referenciar el XML como documento original, no el PDF.

Pre-Commit-Hook para facturas electrónicas

El pre-commit hook comprueba en las facturas electrónicas:

Comprobación Error si
El archivo XML tiene una estructura XRechnung/ZUGFeRD válida Estructura XML no válida
Sidecar .gc.md presente Sidecar ausente
sha256 del sidecar coincide con el archivo XML Discrepancia de hash (archivo modificado)
v7g_taxonomy clasificado como factura electrónica Clasificación ausente
Ningún campo datetime/date en el sidecar (tiempo en uuidV7) Campo redundante

Archivado de correo electrónico

Los correos electrónicos son cartas comerciales o de negocio en el sentido del § 147 Abs. 1 Nr. 2/3 AO y, por tanto, deben conservarse 6 años. Muchos empresarios no archivan los correos electrónicos; eso es una infracción de GoBD.

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart LR EM["E-Mail empfangen
(EML/MBOX)"] EM --> EX["Anhang extrahiert
(PDF, XML)"] EM --> AR["EML archiviert
(unverändert)"] EX --> SH["SHA-256 pro Anhang"] AR --> SH2["SHA-256 der EML"] SH --> SC["Sidecar .gc.md
pro Beleg"] SH2 --> SC2["Sidecar .gc.md
für E-Mail"] style EM fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style EX fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style AR fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style SH fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SH2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style SC2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
Paso Acción Referencia GoBD
Recibir correo electrónico Guardar el archivo EML sin cambios § 147 Abs. 1 Nr. 2 AO (cartas comerciales recibidas)
Extraer el adjunto Guardar el adjunto PDF/XML por separado + SHA-256 Evaluabilidad automática (§ 147 Abs. 6 AO)
Sidecar por comprobante .gc.md para EML y para cada adjunto Trazabilidad (Rz. 146)
Verificación del remitente Cabeceras DKIM/SPF documentadas en el sidecar Valor probatorio del correo electrónico

Consejo práctico: Un repositorio Git puede archivar correos electrónicos (EML/MBOX) y adjuntos (PDF, XML) en paralelo, con una separación clara por tipo de comprobante en el sidecar (v7g_taxonomy). El pre-commit hook comprueba que cada EML tenga un sidecar y que cada adjunto esté clasificado por separado.

Integridad de comprobantes (pre-commit hook)

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart TD C["Commit mit Buchungssatz"] C --> H["Pre-Commit-Hook"] H --> P1{"source_sha256
vorhanden?"} P1 -->|nein| R1["Commit abgelehnt
Belegreferenz fehlt"] P1 -->|ja| P2{"Beleg existiert
im Repo?"} P2 -->|nein| R2["Commit abgelehnt
Beleg nicht gefunden"] P2 -->|ja| P3{"Sidecar .gc.md
vorhanden?"} P3 -->|nein| R3["Commit abgelehnt
Sidecar fehlt"] P3 -->|ja| P4{"SHA-256 match?"} P4 -->|nein| R4["Commit abgelehnt
Beleg verändert"] P4 -->|ja| OK["Commit akzeptiert
Beleg-Vollständigkeit OK"] style C fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style H fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P1 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P3 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P4 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style R1 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R3 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R4 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style OK fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
Comprobación Error si Referencia GoBD
source_sha256 presente Referencia de comprobante ausente Rz. 146 (trazabilidad)
El comprobante existe en el repositorio Comprobante no archivado § 147 Abs. 1 Nr. 4 AO (comprobante de contabilización)
Sidecar presente Clasificación ausente Rz. 146 (trazabilidad)
Coincidencia SHA-256 Comprobante modificado posteriormente Rz. 146 (inmutabilidad)

Leverage de riesgo

Hoy (cheap) Mañana (seguro ante auditoría) Riesgo mitigado
SHA-256 por comprobante ID de comprobante inequívoca, independiente del nombre del archivo Impugnación de la autenticidad del comprobante
Sidecar con clave compuesta V7GUID:uuidV7 Acto de clasificación trazable Impugnación de la clasificación
source_sha256 por asiento contable Trazabilidad retrógrada Impugnación de la asignación del comprobante
gcpn.journal_entry_ref en el sidecar Trazabilidad progresiva Impugnación del asiento
XML de factura electrónica sin cambios + sidecar Conforme al § 14b UStG (integridad) No deducibilidad del IVA soportado
EML de correo electrónico archivada + sidecar Conforme al § 147 Abs. 1 Nr. 2 AO Pérdida de pruebas en litigios con autoridades
El pre-commit hook comprueba la integridad de los comprobantes Ningún asiento contable sin comprobante Infracción GoBD «no completo»

Requisito de Harness (vista previa)

Derivable de ED06:

ID Requisito Prioridad
FA-2.1 SHA-256 como ID de comprobante MUST
FA-2.2 Sidecar por comprobante — *.gc.md o (en comprobantes firmados/comprobantes propios) integrado en *.gcsig.md MUST
FA-2.3 Sidecar con clave compuesta V7GUID:uuidV7 MUST
FA-2.8 Funcionalidad DMS: clasificación de comprobantes MUST
FA-2.9 Integración de factura electrónica: importación XRechnung/ZUGFeRD, validación SHOULD
FA-2.10 Archivado de correo electrónico: EML + SHA-256 + sidecar MUST
FA-2.11 Orden GoBD: índice por ejercicio fiscal MUST
FA-2.12 Trazabilidad retrógrada MUST
FA-2.13 Trazabilidad progresiva MUST
FA-2.14 Pre-commit hook: comprobar la integridad de los comprobantes MUST
FA-2.15 Flujo de escaneo: papel → escaneo → SHA-256 → sidecar SHOULD

La lista completa de requisitos está en Harness-Anforderungen.md.

Fuentes

Topología de fuentes y enlaces de referencia CDN

Rol Ubicación Propósito
Primary / SSoT git.gitcover.org/GCC Depósito canónico (firmado con GPG, versionado)
Public OSS Mirror / CDN codeberg.org/gitcover-commons Espejo de solo lectura; descubrimiento FLOSS
Community Hub github.com/gitcover-commons Issues y Discussions; referencia de código fuente en Codeberg

Nota: Esta asignación de fuentes, espejo y Community Hub refleja el estado actual y puede cambiar. Consulte la fuente canónica correspondiente en gitcover.org para conocer el estado actual.