Invoice
Download and send the invoice
After the DGII accepts the invoice, Timbro prepares two files: the XML, which is the signed e-CF, and the PDF, which is its printed representation. Each file has its own status, so an accepted invoice can still have its PDF in preparation.
Download the files
Section titled “Download the files”Retrieve the invoice and download each file when its status is 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 raises NotFoundError when the invoice does not exist. Each download returns the file in 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"])The SDK only returns a file after checking that its bytes match the invoice Timbro names in the response headers. Store the bytes exactly as you receive them. If a file is still pending, retrieve the invoice later or wait for the invoice.ready webhook; do not issue it again.
Email the invoice
Section titled “Email the invoice”Timbro or your system emails the invoice to the customer, never both. If your system already sends it, do not ask Timbro to send it too.
For Timbro to send it, request delivery with the customer’s email. Use an idempotency key derived from a record in your system, and reuse it if you need to repeat the request:
const delivery = await timbro.invoices.deliver({ invoiceId, recipientEmail: "buyer@example.com", idempotencyKey: "sale-842-email-1",});const deliveryStatus = await timbro.invoices.retrieveDelivery({ invoiceId, deliveryId: delivery.id,});delivery = timbro.invoices.deliver( invoice_id, {"recipientEmail": "buyer@example.com"}, idempotency_key="sale-842-email-1",)delivery_status = timbro.invoices.retrieve_delivery(invoice_id, delivery["id"])With HTTP, use POST /v1/invoices/{invoiceId}/deliveries with the Idempotency-Key header and the body { "recipientEmail": "buyer@example.com" }, and retrieve the result with GET /v1/invoices/{invoiceId}/deliveries/{deliveryId}. To choose which files are attached, send attachments: { "pdf": true, "xml": true }.
Timbro sends the email after the DGII accepts the invoice. The invoice.deliverySent and invoice.deliveryFailed webhooks carry the deliveryId you must retrieve. A saved request does not confirm that the email arrived. If sending fails, the invoice is still valid; check the delivery result before asking for another one.
If the customer will pay with Timbro, you can also state the email when you create the payment, with invoicing.recipientEmail.
Share the invoice with another Timbro server
If you issue your invoices on a dedicated Timbro server and want to collect them with https://api.timbro.do, create a shared invoice on your server: limited access that allows reading the invoice’s data and downloading its PDF, but not its signed XML or its diagnostics.
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)Send access to the other system over a protected channel and store its accessToken as a secret. Collect an invoice you already issued shows how the payment uses that access.