Ir al contenido

PDF y layouts

Todo comprobante tiene tres archivos: el PDF (su representación impresa), el XML firmado que se envió a SUNAT y el CDR, la constancia con que SUNAT respondió.

El comprobante los trae en links. Son direcciones que funcionan sin llave de API, para enviarlas a tu cliente o enlazarlas desde tu sistema:

{
"links": {
"pdf": "https://files.emitay.com/files/…/F001-1.pdf",
"xml": "https://files.emitay.com/files/…/F001-1.xml",
"cdr": "https://files.emitay.com/files/…/R-F001-1.zip"
}
}
  • El enlace lleva un token imposible de adivinar: es todo el permiso. Quien tenga el enlace puede ver el archivo.
  • cdr es null hasta que SUNAT responde.
  • El del PDF admite ?format=a4, ticket80 o ticket58.
format Papel
a4 Hoja A4, las que haga falta. Es el formato por defecto
ticket80 Rollo de 80 mm, una sola hoja del alto de su contenido
ticket58 Rollo de 58 mm
Ventana de terminal
curl "https://api.emitay.com/v1/documents/doc_…/pdf?format=ticket80" \
-H "Authorization: Bearer $EMITAY_API_KEY" \
-o F001-1.pdf

Con el SDK, cada archivo llega como bytes:

import { writeFile } from "node:fs/promises";
const pdf = await emitay.documents.pdf("doc_…", { format: "ticket80" }); // Uint8Array
const xml = await emitay.documents.xml("doc_…"); // el XML firmado
const cdr = await emitay.documents.cdr("doc_…"); // el zip del CDR de SUNAT
await writeFile("F001-1.pdf", pdf);

El PDF se genera al pedirlo y se guarda: la segunda petición no vuelve a dibujarlo. El QR de una factura, una boleta o una nota se calcula al emitir, así que el PDF existe aunque SUNAT todavía no haya respondido.

Sin hacer nada, cada formato usa la plantilla de Emitay, con el logo de tu empresa si lo subiste. Un layout es tu propia plantilla: dónde va cada dato, con qué tamaño y qué textos fijos lleva.

  • Es de posición libre: textos, tablas, imágenes, QR, líneas y figuras, cada uno donde lo pongas. No lleva código ni expresiones: cada elemento se enlaza a un dato del comprobante elegido de una lista (issuer.ruc, document_id, qr, la tabla de ítems, los totales…).
  • La misma plantilla sirve para todos los tipos de comprobante: una columna que ninguna línea llena no se dibuja, y una guía muestra sus bienes sin precios.
  • El motor que dibuja la vista previa es el mismo que genera el PDF: lo que ves es lo que sale.

En el panel, en Layouts de PDF, Nuevo layout copia la plantilla de Emitay del formato que elijas —A4, ticket de 80 mm o ticket de 58 mm— y la abre en el editor visual:

  • En el editor del panel cada elemento se arrastra a su sitio. Agregar dato pone un dato del comprobante, elegido de una lista; Agregar elemento, lo que tú escribes o dibujas: un texto, una imagen, una línea, un recuadro o una elipse.
  • En el mismo editor del panel, Vista previa muestra el PDF con un comprobante de muestra y Guardar deja una versión nueva. Si al diseño le falta algo de lo que una plantilla no puede quitar, el editor dice qué y no guarda.
  • Un layout nuevo no cambia lo que imprimes. En la lista del panel, en el menú de acciones del layout, Usar como predeterminado hace que todos los PDF de ese formato salgan con él, también los de comprobantes ya emitidos.

Un layout es { name, format, template, is_default }. La plantilla es un documento JSON de pdfme; lo habitual es partir de una que ya existe.

Operación Qué hace
POST /v1/layouts Crea un layout. La plantilla queda como versión 1
PATCH /v1/layouts/{id} Cambia solo lo que envías. Un template nuevo no reemplaza al anterior: queda como la versión siguiente
POST /v1/layouts/{id}/preview Devuelve el PDF de la versión vigente con un comprobante de muestra (sample) o con uno tuyo (document_id). No guarda nada
GET /v1/layouts Lista tus layouts
const layouts = await emitay.layouts.list();
const [primero] = layouts.data;
if (primero) {
const pdf = await emitay.layouts.preview(primero.id, { sample: "invoice" });
console.log(`${primero.name} (${primero.format}), versión ${primero.version}: ${pdf.byteLength} bytes`);
}
  • is_default: true hace que todos los PDF de ese formato usen el layout. Hay uno predeterminado por formato; marcar otro se lo quita al anterior.
  • Las muestras de preview son invoice, receipt, credit_note, despatch_advice y retention.
  • Los layouts son de la empresa: sirven al modo de prueba y a producción.

SUNAT exige ciertos datos en la representación impresa. Una plantilla que no los tenga no se guarda: la API responde 422 con una entrada en errors por cada uno que falta.

  • El RUC y la razón social del emisor.
  • El tipo de comprobante, su serie y su número.
  • El código QR o el valor resumen (hash): basta uno.
  • La leyenda «Representación impresa de…».

Un dato no cuenta si no se leería: casi transparente, diminuto o fuera de la hoja.

La referencia de cada operación está en Layouts.