Fac-360

Artefactos

El XML firmado, el CDR, el PDF y el QR. Qué produce cada envío y cómo se descarga.

Un comprobante que recorre el camino completo deja archivos: el XML que se firmó, el ZIP que se mandó, el CDR que volvió, y las representaciones imprimibles. La plataforma los guarda y te los sirve.

Los siete tipos

kindQué esTipo de contenido
signed-xmlEl UBL firmado, tal cual se envióapplication/xml
submission-zipEl ZIP que viajó a SUNATapplication/zip
cdr-zipEl CDR como SUNAT lo devolvióapplication/zip
cdr-xmlEl CDR ya extraído del ZIPapplication/xml
pdf-a4Representación impresa en A4application/pdf
pdf-ticketRepresentación en formato ticketapplication/pdf
qr-pngEl QR del comprobante como imagenimage/png

Cómo se descargan

GET /api/v2/documents/{id}/artifacts            # qué hay disponible
GET /api/v2/documents/{id}/artifacts/{kind}     # uno concreto

Las dos piden el scope artifacts:read, que no está implicado por documents:read. Es deliberado: leer el estado de un comprobante y descargar su XML firmado son dos permisos distintos, y hay integraciones que quieren lo primero sin lo segundo.

El listado te dice qué existe antes de que pidas nada, que es lo que quieres si el PDF puede no estar generado todavía.

Los PDF son versionados

El XML firmado y el CDR son inmutables: son lo que ocurrió. Un PDF no — es una representación, y una plantilla puede cambiar, un logo puede actualizarse, un formato puede corregirse.

POST /api/v2/documents/{id}/pdfs                                       # genera una versión
GET  /api/v2/documents/{id}/artifacts/versions/{representationId}/{kind}  # recupera una concreta

POST .../pdfs pide el scope documents:pdf y exige Idempotency-Key. Cada generación produce una versión con su identificador, y las anteriores no se borran.

Por eso existe la ruta con versions/: si imprimiste un comprobante en marzo y la plantilla cambió en junio, puedes recuperar exactamente el PDF que tu cliente recibió, no una reconstrucción con la plantilla de hoy.

Lo que garantiza el almacenamiento

Cada artefacto se registra primero en PostgreSQL como PENDING, se escribe en R2 con una escritura condicional, y solo entonces pasa a READY con su ETag, su hash y su tamaño.

Ese orden importa y no es un detalle de implementación:

  • PostgreSQL tiene el estado; R2 tiene los bytes. Que exista un objeto en R2 nunca es, por sí solo, estado de negocio. Un archivo a medio escribir no puede parecer un artefacto válido.
  • El hash está guardado. Lo que descargas es verificable contra lo que se registró cuando se produjo, no contra lo que hay ahora en el bucket.
  • El bucket es privado. No hay URL pública de un artefacto. Se sirve por una ruta autenticada, que comprueba tu credencial y tu empresa antes de leer un solo byte.

Qué existe en cada momento

CuándoQué hay
Recién creadoNada todavía: el documento aún no se ha firmado
Firmado y enviadosigned-xml, submission-zip
Con respuesta de SUNATcdr-zip, cdr-xml
Tras pedir una representaciónpdf-a4 o pdf-ticket, y qr-png

Un comprobante REJECTED también deja artefactos: se firmó, se envió y volvió un CDR que dice que no. Ese CDR es exactamente la evidencia que querrás para entender por qué.

No construyas la URL de un artefacto a mano a partir del nombre del archivo. La ruta autenticada es el contrato; la organización interna del bucket no lo es y puede cambiar.

On this page