Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Eseperio/verifactu-php/llms.txt
Use this file to discover all available pages before exploring further.
Spain’s AEAT Verifactu regulation requires every submitted invoice to carry a machine-readable QR code on the printed or PDF document. When a recipient scans the code their device opens an AEAT verification URL that displays the official record, confirming the invoice was registered by the issuer.
The QR code encodes a URL with the following query parameters:
| Parameter | Source | Description |
|---|
nif | InvoiceId::$issuerNif | NIF of the invoice issuer |
num | InvoiceId::$seriesNumber | Series and invoice number |
fecha | InvoiceId::$issueDate | Invoice issue date |
huella | InvoiceRecord::$hash | SHA-256 hash (Huella) of the record |
An example URL looks like:
https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR
?nif=B12345678
&num=FA2024%2F001
&fecha=2024-07-01
&huella=1234567890abcdef...
The huella query parameter is omitted when the invoice record’s hash property is
null or empty. For VERI*FACTU invoices the hash is calculated automatically during
registerInvoice() / cancelInvoice(). Always generate the QR after submitting the
invoice so that the hash is available.
Dependency
QR generation requires the bacon/bacon-qr-code package. Install it via Composer:
composer require bacon/bacon-qr-code ^3
The Verifactu PHP library does not pull this dependency automatically; add it explicitly when you need QR generation.
Choosing the Right Method
The library exposes QR generation at two levels:
| Method | Arguments | Use when |
|---|
Verifactu::generateInvoiceQr(InvoiceRecord $record) | Record only | You want the default PNG output (GD renderer, 300 px, string destination) and have already called Verifactu::config() |
VerifactuService::generateInvoiceQr($record, $destination, $size, $engine) | Record + options | You need a specific renderer, size, or file destination |
QrGeneratorService::generateQr($record, $baseUrl, $destination, $size, $engine) | Record + base URL + options | You manage the base URL yourself, or use the service in isolation |
The Facade Method
Verifactu::generateInvoiceQr() is the simplest entry point. It accepts a single InvoiceRecord argument, reads the correct AEAT base URL from the configuration set by Verifactu::config(), and returns raw PNG binary data using the GD renderer at 300 px.
use eseperio\verifactu\Verifactu;
// Returns raw PNG binary data (GD renderer, 300 px, string destination)
$pngData = Verifactu::generateInvoiceQr($invoice);
The method signature is:
Verifactu::generateInvoiceQr(InvoiceRecord $record): string
To control the renderer, output size, or destination, call VerifactuService::generateInvoiceQr() directly (see below).
Custom Options via VerifactuService
VerifactuService::generateInvoiceQr() exposes the full set of options. It also reads the base URL from the library’s configuration, so you still only need to call Verifactu::config() once.
use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
$qrData = VerifactuService::generateInvoiceQr(
$invoice, // InvoiceRecord (submission or cancellation)
QrGeneratorService::DESTINATION_STRING, // destination: 'string' (default) or 'file'
300, // size in pixels (default 300)
QrGeneratorService::RENDERER_GD // renderer: 'gd' (default), 'imagick', or 'svg'
);
The full signature is:
VerifactuService::generateInvoiceQr(
InvoiceRecord $record,
string $destination = QrGeneratorService::DESTINATION_STRING,
int $size = 300,
string $engine = QrGeneratorService::RENDERER_GD
): string
Available Renderers
| Constant | Value | Output | Requirement |
|---|
QrGeneratorService::RENDERER_GD | 'gd' | PNG binary | PHP ext-gd (widely available) |
QrGeneratorService::RENDERER_IMAGICK | 'imagick' | PNG binary | PHP ext-imagick + ImageMagick |
QrGeneratorService::RENDERER_SVG | 'svg' | SVG markup | None (pure PHP) |
Destination Options
| Constant | Value | Returns |
|---|
QrGeneratorService::DESTINATION_STRING | 'string' | Raw image data (PNG bytes or SVG markup) |
QrGeneratorService::DESTINATION_FILE | 'file' | Absolute path to a temporary file |
Code Examples
GD (PNG)
SVG (vector)
Imagick (PNG)
Uses PHP’s built-in GD library. This is the default renderer and the most portable option.use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// Returns raw PNG binary data
$pngData = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_STRING,
300,
QrGeneratorService::RENDERER_GD
);
// Save manually
file_put_contents('/var/invoices/qr_FA2024_001.png', $pngData);
// Or embed in an HTTP response
header('Content-Type: image/png');
echo $pngData;
Produces scalable SVG markup — ideal for PDF rendering engines and screens that need
crisp display at any size.use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// Returns SVG markup as a string
$svgData = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_STRING,
300,
QrGeneratorService::RENDERER_SVG
);
// Inline in HTML
echo '<div class="qr-code">' . $svgData . '</div>';
// Or save as a file
file_put_contents('/var/invoices/qr_FA2024_001.svg', $svgData);
Uses the ImageMagick extension for higher-quality PNG output. Requires ext-imagick
to be installed and enabled on your server.use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// Returns high-quality PNG binary data
$pngData = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_STRING,
300,
QrGeneratorService::RENDERER_IMAGICK
);
// Embed in an HTTP response
header('Content-Type: image/png');
echo $pngData;
Destination Options
use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// Returns the raw image bytes / SVG markup directly
$imageData = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_STRING, // <-- default
300,
QrGeneratorService::RENDERER_GD
);
Embedding in HTML (base64)
use eseperio\verifactu\Verifactu;
// Facade returns raw PNG binary — encode it for embedding
$pngData = Verifactu::generateInvoiceQr($invoice);
$base64 = base64_encode($pngData);
echo '<img src="data:image/png;base64,' . $base64 . '" alt="Invoice QR Code" />';
Full Workflow: Submit Then Generate QR
The recommended pattern is to submit the invoice first, store the CSV, then generate the QR once the hash has been set by the library.
<?php
use eseperio\verifactu\Verifactu;
use eseperio\verifactu\models\InvoiceResponse;
use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// ... build $invoice as shown in the Register Invoice guide ...
// 1. Register the invoice
$response = Verifactu::registerInvoice($invoice);
if ($response->submissionStatus === InvoiceResponse::STATUS_OK) {
// 2. The library has now set $invoice->hash automatically
echo "Registered. CSV: " . $response->csv . "\n";
// 3. Simple facade call — PNG string, GD renderer, 300 px
$pngData = Verifactu::generateInvoiceQr($invoice);
// 4. Save to a temp file using VerifactuService for full control
$qrPath = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_FILE,
300,
QrGeneratorService::RENDERER_GD
);
echo "QR saved to: $qrPath\n";
// 5. Or generate as base64 for embedding in your invoice PDF
$base64Qr = base64_encode($pngData);
// Pass $base64Qr to your PDF rendering template
} else {
foreach ($response->getErrors() as $code => $description) {
echo "[$code] $description\n";
}
}
Resolution / Size
The $size parameter controls the output dimensions in pixels. The default is 300. Use a higher value for print-quality output:
use eseperio\verifactu\services\VerifactuService;
use eseperio\verifactu\services\QrGeneratorService;
// High-resolution QR for print (600 px)
$hiResQr = VerifactuService::generateInvoiceQr(
$invoice,
QrGeneratorService::DESTINATION_STRING,
600,
QrGeneratorService::RENDERER_GD
);
For SVG output the $size value sets the width/height attributes of the generated SVG
element, but the image remains fully scalable via CSS regardless of the value used.
Production vs. Sandbox QR URLs
Verifactu::config() automatically selects the correct base URL for the QR:
| Environment | Base URL |
|---|
ENVIRONMENT_PRODUCTION | https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR |
ENVIRONMENT_SANDBOX | https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR |
QR codes generated in sandbox mode point to the AEAT homologation verifier. Re-generate stored QR codes when you move from sandbox to production.