Archivos descargables
Listar el PDF, el XML firmado y la respuesta de la DIAN, descargarlos, comprobarlos y reintentar el que falle.
Cada documento genera archivos: el PDF para que lo lea una persona y el XML firmado, que es la factura de verdad. En habilitación se guarda además la respuesta de la DIAN.
Los archivos se generan cuando la revisión termina, así que pueden aparecer unos segundos después de que dian.status ya diga validated. Un archivo que todavía no está no es un error: es un pending.
Qué archivos hay
kind | Qué es |
|---|---|
pdf | La representación gráfica, con el QR y el CUFE. Es lo que le muestras a tu cliente. |
signed_xml | El documento fiscal firmado. Es el que tiene valor; guárdalo tú también. |
dian_response | La respuesta de la DIAN (ApplicationResponse), tal como llegó. |
attached_document | El contenedor firmado que une el XML y la respuesta de la DIAN. No se envía a la DIAN. |
unsigned_xml_preview | Una vista previa sin firmar. Solo en simulación. |
attached_document no funciona en el sandbox
En las cuentas del sandbox, el AttachedDocument queda en failed con ATTACHED_SIGNING_AUTHORIZATION_BLOCKED, porque el emisor de pruebas es compartido. El PDF y el XML firmado sí se generan con normalidad. No lo reintentes: no es algo que puedas arreglar desde tu lado.
Listar y descargar
# 1. Qué archivos tiene la factura
curl -s "https://api-sandbox.cufy.co/v1/documents/DOCUMENT_ID/artifacts" \
-H "X-API-Key: TU_API_KEY"
# 2. Descargar uno (toma el id del que quieras)
curl -s "https://api-sandbox.cufy.co/v1/artifacts/ARTIFACT_ID/content" \
-H "X-API-Key: TU_API_KEY" -o factura.pdfGET /v1/documents/{id}/artifacts devuelve uno por archivo:
| Campo | Qué es |
|---|---|
id | Lo que pones en la descarga. |
kind | Cuál de los archivos de la tabla de arriba es. |
status | pending (aún no), available (listo) o failed (no se pudo). |
revision | A qué revisión del documento pertenece. |
sha256 | La huella del contenido. Compárala después de descargar. |
size_bytes y content_type | Tamaño y tipo. Solo vienen si está available. |
reason_code | Por qué falló, cuando status es failed. |
Busca por kind, nunca por posición en la lista. Para los archivos de una revisión anterior, añade ?revision=1.
GET /v1/artifacts/{id}/content devuelve los bytes. Necesita documents:read.
Comprueba lo que descargaste: el tamaño y el SHA-256 tienen que coincidir con los del listado antes de que guardes el archivo o se lo muestres a nadie. El ETag de la descarga es ese mismo SHA-256.
shasum -a 256 factura.pdfLos archivos de revisiones anteriores conservan su id y sus bytes para siempre: una corrección no reescribe el pasado.
Reintentar un archivo fallido
Un failed trae su reason_code. Si la causa depende de ti, arréglala y llama POST /v1/artifacts/{id}/retries con documents:write, una Idempotency-Key nueva y un motivo:
{ "reason": "Reintentar la generación tras corregir la causa" }reason_code | Qué pasó |
|---|---|
DIAN_APPLICATION_RESPONSE_MISSING / DIAN_RESPONSE_SOURCE_MISSING | Falta la evidencia original de la DIAN. No se inventa una aprobación: hay que recuperarla. |
ATTACHED_RESPONSE_UNAVAILABLE | Le falta una pieza al AttachedDocument. |
ATTACHED_SIGNING_AUTHORIZATION_BLOCKED | En el sandbox, lo esperado (ver arriba). |
Reintentar un archivo que está available o pending responde conflicto. Un reintento no cambia el número, la revisión, el estado fiscal ni el saldo de la factura: solo vuelve a generar el archivo.
Los fallos pasajeros ya se reintentan solos, hasta ocho veces. Que un archivo falle no bloquea la factura, y el PDF puede quedar disponible aunque los demás fallen.
Qué trae el PDF
- El número, el CUFE y el QR de la factura, cuando ya existen.
- Los importes tal como están en el XML firmado, sin recalcular ni redondear nada.
- Una marca visible de que es un documento de pruebas, y de rechazo cuando corresponde.
- Un máximo de 8 MiB.
Generar el PDF no le envía nada a nadie ni cambia delivery_status. Para que le llegue al comprador, ver Entrega.