# QR code and the invoice PDF

When the VeriFactu QR code data is available, how the PDF relates to it, and what applies to any document that carries the QR.

An invoice issued with a billing system carries a QR code that lets its recipient check it with AEAT (article 6.5 of the RD 1619/2012, and articles 20 and 21 of the Orden HAC/1177/2024). BeeL. prints that QR on the PDF it generates — once, centred at the top of the first page, at the size [QRC-003 · The QR measures between 30 mm and 40 mm](/rules/qr#qrc-003) sets, with «QR tributario:» above it and the legend below, both centred too — and also returns the QR data on the invoice.

## The QR exists from `PENDING`

The QR is produced when the record is submitted, not when AEAT accepts it. As soon as an invoice reads `submission_status: PENDING`, its `verifactu` block already carries:

- `qr_url` — the AEAT validation link the QR encodes;
- `qr_base64` — the QR as a base64-encoded PNG, ready to embed;
- `invoice_hash` — the fingerprint of the record.

They stay on the invoice whatever AEAT answers — including after a rejection. Their presence says the record was built, not that AEAT accepted it: read `submission_status` for that.

Before you render a document of the invoice, make sure the QR data is there: read the invoice until `verifactu.qr_url` is present, or wait for the `invoice.pdf.generated` webhook — see [QRC-002 · Wait for the QR before you distribute the PDF](/rules/qr#qrc-002).

In sandbox the QR points to AEAT's **test** validation service; see [Testing in sandbox](/verifactu/testing-in-sandbox#where-the-submission-goes).

## The PDF and the QR

For an invoice under VeriFactu, BeeL. renders the PDF with the QR once the QR data exists. The `invoice.pdf.generated` webhook tells you when it is ready, and [downloading the PDF](/invoices/getCompanyInvoicePdf) waits for it rather than making you poll. An invoice outside VeriFactu (`verifactu.enabled: false`) never waits: its PDF has no QR.

The PDF is generated **once**, with the QR, and is never modified afterwards. Voiding the invoice or issuing a corrective for it does not change it and does not send `invoice.pdf.generated` again: the new status is in `status` and `verifactu.submission_status`, not in the document. Emailing the invoice before its PDF exists answers `202`, and the email goes out when the PDF is stored — see [Sending email](/guides/sending-email#sending-before-the-pdf-exists).

> **Rules that apply here:** [QRC-002 · Wait for the QR before you distribute the PDF](/rules/qr#qrc-002)

## If the submission never reaches AEAT

When the registration never produces a record — the submission was refused before reaching AEAT, or the invoice stays `NOT_SUBMITTED` — there is no QR data to print. An invoice whose registration was refused before reaching AEAT, or that was voided without being registered, has no PDF: downloading it, previewing it or emailing it with the PDF answers `400` [`INVOICE_NOT_REGISTERED_NO_PDF`](/errors/INVOICE_NOT_REGISTERED_NO_PDF). The fix is to get the invoice registered, not to render around it: see [Handling AEAT rejections](/verifactu/handling-rejections#when-to-contact-support).

## Rendering your own PDF

<Callout type="warn" title="Check this architecture with your tax advisor first">
  Under the criteria AEAT has published, software that **prints the invoice or generates its QR** can be a component of the billing system that needs its own *declaración responsable* (the producer's signed statement of compliance), even when BeeL. generates the record and the QR data. The rules and AEAT's wording are in [Software built on the API](/verifactu/compliance-and-responsibilities#software-built-on-the-api).
</Callout>

The API returns the QR data so that it is available to your software:

```json
{
  "verifactu": {
    "enabled": true,
    "submission_status": "PENDING",
    "qr_url": "https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?nif=B27534239&numserie=S-2026-0001&fecha=19-09-2026&importe=121.00",
    "qr_base64": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADI..."
  }
}
```

- **`qr_base64`** is the QR as a PNG image.
- **`qr_url`** is the link the QR encodes.

The URL comes from the registered record: its `importe` is the total AEAT registers, which can differ from your invoice's total — see [What AEAT receives](/verifactu/what-aeat-receives#the-total). The number registered with AEAT is the `invoice_number` BeeL. assigned.

Any document that carries the QR is subject to these rules:

- [QRC-003 · The QR measures between 30 mm and 40 mm](/rules/qr#qrc-003)
- [QRC-004 · The QR follows ISO/IEC 18004 with error correction M](/rules/qr#qrc-004)
- [QRC-005 · Use qr_url exactly as returned](/rules/qr#qrc-005)
- [QRC-007 · «QR tributario:» goes just above the QR](/rules/qr#qrc-007)
- [QRC-008 · The QR goes once, at the start of the first page](/rules/qr#qrc-008)
- [QRC-009 · Keep a blank margin around the QR](/rules/qr#qrc-009)
- the legend goes next to it — see [The legend next to the QR](#the-legend-next-to-the-qr).

The QR data is available from `PENDING`, without waiting for `ACCEPTED`. The `verifactu.status.updated` webhook for the registration carries `qr_url` and `qr_base64` too.

> **Rules that apply here:** [QRC-001 · Every invoice carries the tax QR code](/rules/qr#qrc-001) · [QRC-010 · A structured e-invoice carries the QR URL as a field](/rules/qr#qrc-010)

## The legend next to the QR

**QRC-006 · The VeriFactu legend goes just below the QR**

`Required` · Law · Impact: medium · Responsibility: your integration.

Just below the QR, print «Factura verificable en la sede electrónica de la AEAT» or «VERI*FACTU», preferably centred on it. The Orden asks for a type and size clearly visible and similar to the rest of the invoice data; AEAT's specification, for one equal to or larger than it. Print it only on invoices whose record goes to AEAT.

Full rule: [QRC-006](/rules/qr#qrc-006)

> **Rules that apply here:** [QRC-006 · The VeriFactu legend goes just below the QR](/rules/qr#qrc-006) · [QRC-001 · Every invoice carries the tax QR code](/rules/qr#qrc-001)

## Related

<Related>

- [Submission states](/verifactu/submission-states) — what `PENDING`, `ACCEPTED` and `REJECTED` mean
- [What AEAT receives](/verifactu/what-aeat-receives) — why the QR's amount can differ from `invoice_total`
- [Download the invoice PDF](/invoices/getCompanyInvoicePdf)

</Related>

---

Full OpenAPI spec: https://docs.beel.es/api/openapi