Facturar
Descargar y enviar la factura
Después de que la DGII acepta la factura, Timbro prepara dos archivos: el XML, que es el e-CF firmado, y el PDF, que es su representación impresa. Cada archivo tiene su propio estado, así que una factura aceptada puede tener su PDF todavía en preparación.
Descarga los archivos
Sección titulada «Descarga los archivos»Consulta la factura y descarga cada archivo cuando su estado sea ready:
import { createTimbroInvoices } from "@timbro/invoices";
const timbro = createTimbroInvoices({ apiKey: process.env.TIMBRO_INVOICES_API_KEY! });const invoiceId = "11111111-1111-4111-8111-111111111111";const invoice = await timbro.invoices.retrieve(invoiceId);if (!invoice) throw new Error("Invoice not found");
if (invoice.files.xml.status === "ready") { const xml = await timbro.invoices.downloadXml(invoice.id);}if (invoice.files.pdf.status === "ready") { const pdf = await timbro.invoices.downloadPdf(invoice.id);}invoices.retrieve lanza NotFoundError cuando la factura no existe. Cada descarga devuelve el archivo en content:
import os
from timbro_invoices import TimbroInvoices
timbro = TimbroInvoices(api_key=os.environ["TIMBRO_INVOICES_API_KEY"])invoice_id = "11111111-1111-4111-8111-111111111111"invoice = timbro.invoices.retrieve(invoice_id)
if invoice["files"]["xml"]["status"] == "ready": xml = timbro.invoices.download_xml(invoice["id"])if invoice["files"]["pdf"]["status"] == "ready": pdf = timbro.invoices.download_pdf(invoice["id"])El SDK solo devuelve un archivo después de comprobar que sus bytes coinciden con la factura que Timbro indica en los encabezados de la respuesta. Guarda los bytes tal como los recibes. Si un archivo sigue pendiente, consulta la factura más tarde o espera el webhook invoice.ready; no vuelvas a emitirla.
Envía la factura por correo
Sección titulada «Envía la factura por correo»Timbro o tu sistema le envía la factura al cliente, nunca los dos. Si tu sistema ya la envía, no le pidas a Timbro que la envíe también.
Para que Timbro la envíe, solicita la entrega con el correo del cliente. Usa una clave de idempotencia derivada de un registro de tu sistema y repítela si necesitas repetir la solicitud:
const delivery = await timbro.invoices.deliver({ invoiceId, recipientEmail: "comprador@example.com", idempotencyKey: "venta-842-entrega-1",});const deliveryStatus = await timbro.invoices.retrieveDelivery({ invoiceId, deliveryId: delivery.id,});delivery = timbro.invoices.deliver( invoice_id, {"recipientEmail": "comprador@example.com"}, idempotency_key="venta-842-entrega-1",)delivery_status = timbro.invoices.retrieve_delivery(invoice_id, delivery["id"])Con HTTP, usa POST /v1/invoices/{invoiceId}/deliveries con el encabezado Idempotency-Key y el cuerpo { "recipientEmail": "comprador@example.com" }, y consulta el resultado con GET /v1/invoices/{invoiceId}/deliveries/{deliveryId}. Para elegir qué archivos van adjuntos, envía attachments: { "pdf": true, "xml": true }.
Timbro envía el correo después de que la DGII acepta la factura. Los webhooks invoice.deliverySent e invoice.deliveryFailed traen el deliveryId que debes consultar. Que la solicitud se haya guardado no confirma que el correo llegó. Si el envío falla, la factura sigue siendo válida; revisa el resultado de la entrega antes de pedir otra.
Si el cliente va a pagar con Timbro, también puedes indicar el correo al crear el pago, con invoicing.recipientEmail.
Compartir la factura con otro servidor de Timbro
Si emites tus facturas en un servidor de Timbro dedicado y quieres cobrarlas con https://api.timbro.do, crea en tu servidor una factura compartida: un acceso limitado que permite leer los datos de la factura y descargar su PDF, pero no su XML firmado ni sus diagnósticos.
const access = await timbro.invoices.shareReceipt(invoiceId);const receipt = await timbro.invoices.retrieveReceipt(access);const receiptPdf = await timbro.invoices.downloadReceiptPdf(access);access = timbro.invoices.share_receipt(invoice_id)receipt = timbro.invoices.retrieve_receipt(access)receipt_pdf = timbro.invoices.download_receipt_pdf(access)Envía access al otro sistema por un canal protegido y guarda su accessToken como un secreto. Cobrar una factura que ya emitiste muestra cómo usa el pago ese acceso.