Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/josemmo/Verifactu-PHP/llms.txt

Use this file to discover all available pages before exploring further.

Verifactu-PHP supports full round-trip XML serialization for both RegistrationRecord and CancellationRecord. This is useful for storing records in a database or filesystem, producing AEAT-format XML for auditing purposes, or integrating with external systems that consume the VERI*FACTU XSD format.
XML serialization depends on the josemmo/uxml library for XML manipulation. It is installed automatically as a Composer dependency — no additional setup is required.

Exporting records to XML

Use UXML::newInstance() to create a container element with the correct sum1 namespace binding, then call $record->export() passing the container and your ComputerSystem instance. Retrieve the resulting element with ->get() and call ->asXML() to obtain the XML string.
<?php
use josemmo\Verifactu\Models\ComputerSystem;
use josemmo\Verifactu\Models\Records\Record;
use josemmo\Verifactu\Models\Records\RegistrationRecord;
use UXML\UXML;

// Assume $record is a fully built and validated RegistrationRecord
// and $system is a configured ComputerSystem instance

/** @var RegistrationRecord $record */
/** @var ComputerSystem $system */

// Create a container with the VERI*FACTU namespace
$container = UXML::newInstance('container', null, [
    'xmlns:sum1' => Record::NS,
]);

// Export the record into the container
$record->export($container, $system);

// Retrieve the <sum1:RegistroAlta> element and serialise it
$xmlString = $container->get('sum1:RegistroAlta')->asXML();
echo $xmlString . "\n";
For a CancellationRecord, the element name changes to sum1:RegistroAnulacion:
$xmlString = $container->get('sum1:RegistroAnulacion')->asXML();
echo $xmlString . "\n";

Importing records from XML

Use UXML::fromString() to parse an XML document, then call the static Record::fromXml() method. It automatically detects the record type based on the root element name (sum1:RegistroAltaRegistrationRecord, sum1:RegistroAnulacionCancellationRecord) and returns the appropriate object.
<?php
use josemmo\Verifactu\Exceptions\ImportException;
use josemmo\Verifactu\Exceptions\InvalidModelException;
use josemmo\Verifactu\Models\Records\Record;
use josemmo\Verifactu\Models\Records\RegistrationRecord;
use josemmo\Verifactu\Models\Records\CancellationRecord;
use UXML\UXML;

$data = file_get_contents(__DIR__ . '/path/to/registro.xml');
if ($data === false) {
    throw new RuntimeException('Failed to read XML file');
}

try {
    $xml    = UXML::fromString($data);
    $record = Record::fromXml($xml);

    // Optionally validate the imported record
    $record->validate();

    if ($record instanceof RegistrationRecord) {
        echo "Registration record for invoice: {$record->invoiceId->invoiceNumber}\n";
    } elseif ($record instanceof CancellationRecord) {
        echo "Cancellation record for invoice: {$record->invoiceId->invoiceNumber}\n";
    }
} catch (ImportException $e) {
    echo "Failed to import record: $e\n";
} catch (InvalidModelException $e) {
    echo "Imported record is invalid: $e\n";
}

XML namespaces

All VERI*FACTU record elements live in the SuministroInformacion XML namespace. The namespace URI is available as a public constant on the Record base class:
use josemmo\Verifactu\Models\Records\Record;

echo Record::NS . "\n";
// https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd
When constructing the export container, bind this namespace to the sum1 prefix:
$container = UXML::newInstance('container', null, [
    'xmlns:sum1' => Record::NS,
]);
Using any prefix other than sum1, or omitting the namespace binding, will produce XML that Record::fromXml() cannot parse — the import method enforces the sum1 prefix on the root element.

Error handling

Record::fromXml() throws an ImportException if the XML is structurally invalid, missing required elements, or contains values that cannot be mapped to the expected enum types. Always wrap imports in a try / catch block:
use josemmo\Verifactu\Exceptions\ImportException;
use josemmo\Verifactu\Models\Records\Record;
use UXML\UXML;

try {
    $record = Record::fromXml(UXML::fromString($xmlString));
} catch (ImportException $e) {
    // Log or surface the error — $e->getMessage() contains a human-readable description
    error_log("XML import failed: " . $e->getMessage());
}
Common causes of ImportException:
CauseExample
Missing required element<sum1:IDFactura /> absent from the document
Unknown enum value<sum1:TipoFactura>XX</sum1:TipoFactura> (not a valid InvoiceType)
Malformed date<sum1:FechaExpedicionFactura>2026/03/15</sum1:FechaExpedicionFactura> (wrong format)
Wrong namespace prefixRoot element is RegistroAlta instead of sum1:RegistroAlta

Build docs developers (and LLMs) love