Procesos de Asignación del Número de Control
Este anexo describe el proceso mediante el cual la plataforma de imprenta digital de ZENTTO GLOBAL TECHNOLOGY, C.A. asigna el número de control a los documentos de los emisores, valida su estructura, los registra de forma automatizada y garantiza su integridad, en cumplimiento de los artículos 29 a 32 de la Providencia Administrativa SNAT/2024/000102. La numeración es de generación propia.
1. Formato del número de control (Art. 30)
El artículo 30 establece que el número de control es consecutivo y único por emisor, se
identifica con la denominación «Nº de Control» y se compone de un identificador de dos (2)
dígitos y un secuencial de hasta ocho (8) dígitos; la primera vez el identificador es
00 y el secuencial 1. La plataforma lo implementa exactamente:
| Elemento | Implementación |
|---|---|
| Identificador (2 dígitos) | Campo "Prefix" de fiscal."NcfdSequence", por defecto 00 hasta que el SENIAT asigne uno distinto |
| Serie | Campo "SerieNumero" (por defecto 01) y series propias en imprenta."ControlSerie" |
| Secuencial (hasta 8 dígitos) | LPAD(numero, 8, '0') — relleno a ocho dígitos del consecutivo |
| Primer número | Identificador 00 y secuencial 1 (formateado 00000001) |
| Consecutivo y único por emisor | La secuencia se lleva por "RifEmisor" (clave primaria de fiscal."NcfdSequence") |
El número de control completo se construye en formato IDENTIFICADOR-SERIE-SECUENCIAL
(por ejemplo 00-01-00001234) en la función fiscal.fn_assign_ncfd,
y como PREFIJO + SECUENCIAL de ocho dígitos en la asignación por serie propia de
imprenta.fn_assign_control_serie.
2. Correlativo atómico (consecutivo sin huecos)
La asignación del número de control es atómica: se realiza dentro de una
transacción de base de datos con bloqueo de fila (SELECT ... FOR UPDATE) e
incremento en la misma transacción, de modo que bajo concurrencia no se producen huecos ni
duplicados. Existen dos funciones PL/pgSQL verificadas:
fiscal.fn_assign_ncfd(p_rif)— incrementa"LastNumber"conUPDATE ... RETURNINGsobre la fila del emisor (bloqueo implícito de fila) y devuelve el número de control formateado. Crea el emisor conLastNumber = 0si no existe (idempotente).imprenta.fn_assign_control_serie(p_company_id, p_tipo_doc, p_serie)— selecciona la serie activa conFOR UPDATE, calcula el siguiente número dentro del rango[Desde, Hasta], incrementa"Correlativo"y marca la serie comoAGOTADAal alcanzar el límite. Devuelve"NumeroControl"y"SerieId".
sequenceDiagram
participant E as Emisor / Integrador
participant API as Imprenta digital (API)
participant Z as Validación (Zod)
participant DB as PostgreSQL (función atómica)
participant H as Cadena de integridad
E->>API: Documento canónico (HTTPS)
API->>Z: Validar estructura del documento
Z-->>API: Estructura válida
API->>DB: fn_assign_control_serie (SELECT FOR UPDATE + incremento)
DB-->>API: Número de control + SerieId
API->>H: Encadenar SHA-256 por RIF emisor
H-->>API: Hash del registro
API->>DB: Registrar consumo (ConsumoControl) y documento (DigitalInvoice)
API-->>E: Número de control asignado (inalterable)
3. Cadena de integridad (hash-chain SHA-256)
Cada documento al que se asigna número de control queda encadenado mediante un hash SHA-256 calculado de forma determinística por RIF emisor. El hash combina, en orden fijo, el número de control, el RIF emisor, la fecha de emisión, el tipo de documento, el total, el hash del registro anterior y la marca temporal. De este modo, cualquier alteración, inserción o eliminación rompe la cadena y se detecta en la verificación.
| Elemento | Implementación |
|---|---|
| Cálculo del hash | computeHash() — SHA-256 sobre la cadena canónica NCFD | RifEmisor | FechaEmision | TipoDoc | Total | HashAnterior | Timestamp |
| Encadenamiento | Campo "HashAnterior" de fiscal."DigitalInvoice" apunta al "XmlHashSha256" del registro previo del mismo emisor |
| Verificación | verifyChainIntegrity(rifEmisor) — recalcula la cadena completa y reporta la posición del primer registro corrupto, o confirma que está íntegra |
graph LR E0["Registro N-1
HashActual = H(N-1)"] -->|HashAnterior| E1["Registro N
computeHash + HashActual"] E1 -->|HashAnterior| E2["Registro N+1
HashActual"] E2 --> V["verifyChainIntegrity
recalcula → OK o ALTERADA"]
4. Validación de la estructura (Art. 29.4)
Antes de asignar el número de control, la plataforma valida la estructura del documento
transmitido. La validación se realiza con esquemas Zod sobre el documento canónico
(CanonicalDocument / EmitDocumentRequest), de modo que solo se
asigna número de control a documentos con estructura correcta y campos obligatorios
presentes. La validación abarca, entre otros: tipo de documento, datos del emisor y del
receptor, líneas de detalle, alícuotas de IVA y totales. El RIF del emisor se normaliza y se
valida su formato antes de la asignación (assignNcfd).
5. Solicitud del RIF y datos del emisor (Art. 29.2 y 29.3)
La plataforma exige el RIF del emisor para asignar el número de control: la función
assignNcfd valida el formato del RIF antes de invocar la asignación, y la
secuencia se lleva por "RifEmisor". Los datos del emisor (RIF y nombre) quedan
incluidos en el registro fiscal del documento ("RifEmisor",
"NombreEmisor" de fiscal."DigitalInvoice"), de manera que cada
número de control queda asociado de forma inequívoca al emisor que lo solicitó.
6. Registro automatizado (Art. 32)
Cada asignación se registra automáticamente, sin intervención del operador. El registro automatizado conserva la información exigida por el artículo 32:
| Información (Art. 32) | Campo registrado |
|---|---|
| RIF del emisor | "RifEmisor" |
| Fecha de asignación | "FechaEmision", "CreatedAt" y "EmitidoAt" (consumo) |
| Tipo de documento | "TipoDocumento" |
| Numeración de control consecutiva | "NCFD" / "NumeroControl" |
| Numeración de cada formato | "Serie", "SerieCorrelativo" y "NumeroDocumento" |
| Identificación de la factura | "InvoiceId" y "PayloadJson" (instantánea completa del documento) |
El registro reside en fiscal."DigitalInvoice" (documento y cadena de
integridad) y en imprenta."ConsumoControl" (evento de asignación por número de
control). Adicionalmente, cada operación queda trazada en la bitácora inmutable
audit."AccessLog".
7. Dimensiones tipográficas (Art. 31)
El número de control se genera con denominación «Nº de Control» y con un formato legible y
consistente: identificador de dos dígitos, serie y secuencial de ocho dígitos con relleno de
ceros (LPAD(..., 8, '0')), lo que asegura un ancho fijo y una presentación
uniforme en todos los documentos. La representación impresa del documento se produce con
tamaños y proporciones que mantienen el número de control claramente identificable y legible,
conforme a las dimensiones tipográficas exigidas por el artículo 31.
8. Resultado de la asignación
Una vez asignado, el número de control es inalterable: cualquier corrección posterior se realiza mediante nota de crédito o nota de débito que referencia el documento afectado, y el registro original se preserva íntegro dentro de la cadena de integridad. El detalle de la estructura documental se desarrolla en el anexo de estructura de los documentos.
ZENTTO GLOBAL TECHNOLOGY, C.A. — RIF J-50849797-0 — Asignación del número de control (Art. 29 a 32 SNAT/2024/000102) — v1.0.0.