← Blog
DTE

Generar TED y código PDF417 en un DTE: guía para developers

Cómo generar el TED del DTE: estructura del bloque DD, firma FRMT con SHA1withRSA, el CAF y la codificación en código PDF417 del SII.

Equipo Emitir5 min de lectura

El TED es la pieza del DTE que más confunde a quien lo implementa por primera vez. No es un campo más del XML: es una firma electrónica independiente, con su propia llave, su propia regla de serialización y su propia representación visual en el código PDF417. Esta guía cubre cómo se arma y cómo se codifica, con el léxico exacto del instructivo del SII.

Si vienes llegando al tema, primero conviene leer qué es el TED y para qué sirve. Acá vamos directo a la implementación.

Qué es el TED

TED significa Timbre Electrónico del DTE. Es una firma electrónica calculada sobre los campos representativos del documento, e incluye el CAF que el SII te entregó para ese rango de folios. Su función es permitir que cualquiera valide la autenticidad del documento solo con lo que está impreso, sin consultar el XML completo.

El TED tiene dos partes: el bloque DD (Datos del Documento) y el bloque FRMT (la firma sobre DD).

Estructura del bloque DD

El bloque DD contiene los datos que se firman. Estos son los campos:

  • versión del TED
  • RE: RUT del emisor
  • TD: tipo de documento
  • F: folio
  • FE: fecha de emisión
  • RR: RUT del receptor
  • RSR: razón social del receptor (hasta 40 caracteres)
  • MNT: monto total
  • IT1: descripción del primer ítem (hasta 40 caracteres)
  • el CAF tal como lo entregó el SII, sin modificaciones
  • TSTED: timestamp de generación del timbre

Una regla que no es opcional: el TED debe ser un espejo del encabezado del DTE. RE, TD, F, RR y MNT tienen que coincidir con los valores del documento. Si no coinciden, el resultado es rechazo o inconsistencia al validar.

Codificación de caracteres

Dentro del DD, los campos RSR (razón social del receptor) e IT1 (descripción del primer ítem) se codifican con entidades XML predefinidas y en ISO-8859-1, no en UTF-8. Es un punto clásico de fallo: una "ñ" o un acento codificado mal rompe la verificación del timbre. Trunca ambos campos a 40 caracteres antes de codificar.

El CAF dentro del DD

El CAF se incluye en el TED tal como lo entregó el SII, sin ninguna modificación. No reformatees ni reordenes su contenido. Si necesitas repasar cómo funciona la asignación de folios y el archivo CAF, está explicado acá.

La firma FRMT

El bloque FRMT es la firma del bloque DD. Aquí hay dos diferencias importantes respecto a la firma del XML completo:

  1. No usa XMLDSig. Por la restricción de espacio del PDF417, el SII define un esquema de firma compacto en su instructivo, distinto del XMLDSig que firma el documento completo.
  2. La llave es la del CAF. La firma se genera con la llave privada RSA entregada dentro del CAF, no con el certificado digital del contribuyente. El algoritmo es SHA1withRSA.

La regla de serialización (lo crítico)

Antes de firmar, el bloque DD se serializa siguiendo una regla precisa: se eliminan todos los caracteres que estén entre el tag de cierre de un elemento y el tag de inicio del siguiente, sin modificar el contenido de los elementos terminales.

En la práctica esto significa quitar los saltos de línea, espacios y tabulaciones que tu serializador XML mete por estética entre nodos, pero dejar intacto el texto dentro de cada nodo. Si firmas sobre un DD "bonito" con indentación, la firma no validará. Esta es la causa número uno de timbres rechazados.

Cómo se codifica en PDF417

Una vez que tienes el TED completo (DD más FRMT), se codifica como código de barras 2D PDF417 en la representación impresa del DTE, es decir, en el PDF que se entrega o se imprime. El validador del receptor lee ese PDF417, reconstruye el TED y verifica la firma contra el CAF.

Flujo de implementación (pseudocódigo)

A modo ilustrativo, el flujo es así. No es una API real; es la secuencia lógica:

# 1. Armar el bloque DD
dd = {
  version, RE, TD, F, FE, RR,
  RSR = codificar_iso8859_1(truncar(razon_social, 40)),
  MNT,
  IT1 = codificar_iso8859_1(truncar(desc_item_1, 40)),
  CAF = caf_del_sii_sin_modificar,
  TSTED = timestamp_actual()
}

# Validar espejo del encabezado
assert dd.RE == dte.RE and dd.TD == dte.TD and dd.F == dte.F
assert dd.RR == dte.RR and dd.MNT == dte.MNT

# 2. Serializar segun la regla del SII
#    (sin caracteres entre tag de cierre y siguiente tag de apertura)
dd_string = serializar_compacto(dd)

# 3. Firmar con la llave privada del CAF
firma = sign(dd_string, llave_privada_rsa_del_caf, algoritmo="SHA1withRSA")
FRMT = base64(firma)

# 4. Componer el TED y codificarlo en PDF417
ted = componer_ted(dd, FRMT)
pdf417 = codificar_pdf417(ted)   # va en el PDF del DTE

Reglas clave que no puedes saltarte

  • Serializa el DD eliminando los caracteres entre tags, sin tocar el contenido de los nodos.
  • Firma con la llave del CAF y SHA1withRSA, no con el certificado del emisor.
  • RSR e IT1 en ISO-8859-1 con entidades XML, truncados a 40.
  • Incluye el CAF sin modificaciones.
  • RE, TD, F, RR y MNT deben ser espejo del encabezado del DTE.

Errores comunes

  • Indentación en el DD firmado. El serializador deja saltos de línea entre nodos y la firma deja de validar.
  • Llave equivocada. Firmar el TED con el certificado del contribuyente en vez de la llave del CAF.
  • UTF-8 en vez de ISO-8859-1 en RSR o IT1, que corrompe acentos y "ñ".
  • Desajuste con el encabezado, típicamente en MNT cuando hay redondeos o impuestos calculados aparte.
  • CAF manipulado al reformatearlo o reordenar campos.

Cuando algo falla, lo más rápido es contrastar el TED contra el resto del documento. Puedes apoyarte en el validador de XML DTE para verificar que el encabezado y el timbre sean consistentes antes de imprimir.

Cierre

El TED y el PDF417 concentran varias reglas frágiles: serialización exacta, llave correcta, codificación de caracteres y espejo del encabezado. En Emitir generamos el TED y el código PDF417 por ti desde el backend, para que no tengas que pelear con SHA1withRSA ni con la serialización del DD. Está en etapa temprana: si te interesa, súmate a la lista de espera.

Preguntas frecuentes

¿Qué es el TED de un DTE?+

El TED (Timbre Electrónico del DTE) es una firma electrónica calculada sobre los campos representativos del documento. Incluye el bloque DD con esos datos más el CAF, y la firma FRMT generada con la llave privada RSA del CAF.

¿Por qué el TED no usa XMLDSig como el resto del DTE?+

Por restricción de espacio del código PDF417. La firma del TED se rige por el instructivo del SII y se calcula con SHA1withRSA sobre una serialización compacta del bloque DD, sin la envoltura de XMLDSig.

¿Con qué llave se firma el TED?+

Con la llave privada RSA que el SII entrega dentro del CAF, usando el algoritmo SHA1withRSA. No se usa el certificado digital del emisor que firma el XML completo.

¿Cómo se serializa el bloque DD antes de firmar?+

Se elimina todo carácter entre el tag de cierre de un elemento y el tag de inicio del siguiente, sin modificar el contenido de los elementos terminales. Sobre ese string se calcula la firma. Cualquier desviación hace fallar la verificación del timbre.

¿Qué se imprime exactamente en el código PDF417?+

El TED completo (bloque DD más FRMT) codificado como código de barras 2D PDF417, en la representación impresa del DTE en PDF.

¿Qué errores rompen la validación del TED con más frecuencia?+

Serializar mal el DD (espacios entre tags), usar otra llave que no sea la del CAF, codificar caracteres fuera de ISO-8859-1 en RSR o IT1, o que RE, TD, F, RR o MNT no coincidan con el encabezado del DTE.

Emite DTE del SII desde tu backend

Emitir es la API de facturación electrónica para Chile. En construcción.

Unirme a la lista de espera