Skip to main content

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.

This page documents every supporting model used when building InvoiceSubmission, InvoiceCancellation, and InvoiceQuery objects, plus the response models returned by the facade methods. All models extend the abstract Model base class and expose a validate(): array method that returns an associative array of validation errors (empty means valid).
InvoiceId identifies a specific invoice within AEAT (IDFacturaType). It is used as the $invoiceId property on every InvoiceRecord subclass.
use eseperio\verifactu\models\InvoiceId;

$id = new InvoiceId();
$id->issuerNif    = 'B12345678';
$id->seriesNumber = 'A-2025/001';
$id->issueDate    = '2025-01-15';

Properties

issuerNif
string
required
Spanish tax identification number (NIF) of the invoice issuer (IDEmisorFactura). Example: 'B12345678'
seriesNumber
string
required
Combined series and invoice number (NumSerieFactura). Example: 'A-2025/001'. Max 60 characters.
issueDate
string
required
Issue date in YYYY-MM-DD format (FechaExpedicionFactura). The library serialiser automatically converts this to DD-MM-YYYY as required by the AEAT XML schema. Example: '2025-01-15'

Validation rules

  • issuerNif, seriesNumber, issueDate are all required strings.
  • issueDate must match the regex /^\d{4}-\d{2}-\d{2}$/.

Breakdown is the container for one or more tax breakdown lines (DesgloseType). It maps to the <sfLR:Desglose> XML element and holds an array of BreakdownDetail objects.
use eseperio\verifactu\models\Breakdown;
use eseperio\verifactu\models\BreakdownDetail;

$breakdown = new Breakdown();
$breakdown->addDetail($detail1);
$breakdown->addDetail($detail2);

$invoice->setBreakdown($breakdown);
// or use the convenience shortcut:
$invoice->addBreakdownDetail($detail1);

Methods

addDetail(BreakdownDetail|array $detail): static
Appends a single breakdown line. Accepts a BreakdownDetail object or an associative array whose keys correspond to BreakdownDetail properties (taxType, regimeKey, operationQualification, exemptOperation, taxRate, taxableBase, costBasedTaxableBase, taxAmount, equivalenceSurchargeRate, equivalenceSurchargeAmount).
setDetails(array $details): static
Replaces all existing details with the provided array. Each element may be a BreakdownDetail object or an associative array.
getDetails(): BreakdownDetail[]
Returns the current array of BreakdownDetail instances.

Validation rules

  • At least one BreakdownDetail is required.
  • Each detail must be a valid BreakdownDetail instance (passes its own validate() check).

BreakdownDetail represents a single tax line within a Breakdown (DetalleType). It maps to the <sfLR:DetalleDesglose> XML element.
use eseperio\verifactu\models\BreakdownDetail;
use eseperio\verifactu\models\enums\TaxType;
use eseperio\verifactu\models\enums\RegimeType;
use eseperio\verifactu\models\enums\OperationQualificationType;

$detail = new BreakdownDetail();
$detail->taxableBase            = 1000.0;
$detail->taxRate                = 21.0;
$detail->taxAmount              = 210.0;
$detail->taxType                = TaxType::IVA;
$detail->regimeKey              = RegimeType::GENERAL;
$detail->operationQualification = OperationQualificationType::SUBJECT_NO_EXEMPT_NO_REVERSE;

Properties

taxableBase
float
required
Taxable base or non-subject amount (BaseImponibleOimporteNoSujeto). Always required.
taxType
TaxType
The type of tax applied to this line (Impuesto, optional).
Enum caseValueDescription
TaxType::IVA'01'Value Added Tax (IVA)
TaxType::IPSI'02'IPSI — Ceuta & Melilla production tax
TaxType::IGIC'03'IGIC — Canary Islands indirect tax
TaxType::OTHER'05'Other taxes
regimeKey
RegimeType
Special regime key or additional transcendence code (ClaveRegimen, optional). Common values:
Enum caseValueDescription
RegimeType::GENERAL'01'General regime
RegimeType::EXPORT'02'Export
RegimeType::CASH_BASIS'07'Cash basis accounting
RegimeType::EQUIVALENCE_SURCHARGE'18'Equivalence surcharge
RegimeType::SIMPLIFIED'20'Simplified regime
See the RegimeType enum for all 17 codes.
operationQualification
OperationQualificationType
Operation qualification (CalificacionOperacion). Either this or exemptOperation must be set (not both, and at least one is required).
Enum caseValueDescription
SUBJECT_NO_EXEMPT_NO_REVERSE'S1'Subject, not exempt, no reverse charge
SUBJECT_NO_EXEMPT_REVERSE'S2'Subject, not exempt, with reverse charge
NOT_SUBJECT_ARTICLE'N1'Not subject (Art. 7, 14, etc.)
NOT_SUBJECT_LOCATION'N2'Not subject due to location rules
exemptOperation
ExemptOperationType
Exempt operation code (OperacionExenta). Either this or operationQualification must be set. Values: E1 through E8.
taxRate
float
Applicable tax rate as a percentage (TipoImpositivo, optional). Example: 21.0 for 21% IVA.
costBasedTaxableBase
float
Cost-based taxable base (BaseImponibleACoste, optional). Used in specific regime scenarios.
taxAmount
float
Tax amount charged (CuotaRepercutida, optional). The total tax for this breakdown line.
equivalenceSurchargeRate
float
Equivalence surcharge rate (TipoRecargoEquivalencia, optional).
equivalenceSurchargeAmount
float
Equivalence surcharge amount (CuotaRecargoEquivalencia, optional).

Validation rules

  • taxableBase is always required.
  • At least one of operationQualification or exemptOperation must be set.
  • Numeric fields (taxRate, taxableBase, taxAmount, etc.) must be float, int, or null.
  • Enum fields must be the correct enum type when set.

Chaining encapsulates the hash-chaining data (EncadenamientoType) that links each record to the previous one in the submission chain, providing tamper-evident integrity. Every InvoiceRecord must have a Chaining set — either as the first record or with a link to the previous record.
use eseperio\verifactu\models\Chaining;

// Option 1 — first record in the chain
$chaining = new Chaining();
$chaining->setAsFirstRecord();

// Option 2 — link to previous record
$chaining = new Chaining();
$chaining->setPreviousInvoice($previousInvoiceChaining);

// Convenience: set directly on the record
$invoice->setAsFirstRecord();

Properties

firstRecord
string|null
First record indicator (PrimerRegistro). The string 'S' when this is the first record in the chain, null otherwise. Set automatically by setAsFirstRecord() — do not set manually to any other value.

Methods

setAsFirstRecord(): static
Marks this as the first record in the chain. Sets firstRecord = 'S' and clears any previousInvoice. Mutually exclusive with setPreviousInvoice().
setPreviousInvoice(PreviousInvoiceChaining|array $previousInvoice): static
Sets the link to the previous record. Accepts a PreviousInvoiceChaining object or an array with issuerNif, seriesNumber, issueDate, and hash keys. Clears firstRecord automatically.
getPreviousInvoice(): PreviousInvoiceChaining|null
Returns the stored PreviousInvoiceChaining object, or null if this is the first record.

Validation rules

  • Exactly one of firstRecord or previousInvoice must be set (not both, and not neither).
  • If firstRecord is set, its value must be the string 'S'.

PreviousInvoiceChaining holds the reference to the previous invoice in the submission chain (EncadenamientoFacturaAnteriorType). Used inside Chaining when this is not the first record.
use eseperio\verifactu\models\PreviousInvoiceChaining;

$prev = new PreviousInvoiceChaining();
$prev->issuerNif    = 'B12345678';
$prev->seriesNumber = 'A-2025/001';
$prev->issueDate    = '15-01-2025';   // DD-MM-YYYY format
$prev->hash         = 'abc123...';    // SHA-256 hash of the previous record

Properties

issuerNif
string
required
NIF of the issuer of the previous invoice (IDEmisorFactura).
seriesNumber
string
required
Series and number of the previous invoice (NumSerieFactura).
issueDate
string
required
Issue date of the previous invoice (FechaExpedicionFactura). Format: DD-MM-YYYY (note: day-first, unlike InvoiceId which uses YYYY-MM-DD).
hash
string
required
SHA-256 hash (Huella) of the previous record. This is the value stored in InvoiceRecord::$hash after the previous submission.

Validation rules

  • All four fields are required strings.
  • issueDate must match /^\d{2}-\d{2}-\d{4}$/.

ComputerSystem describes the billing software generating the invoice (SistemaInformaticoType). AEAT uses this information to audit which systems are submitting records.
use eseperio\verifactu\models\ComputerSystem;
use eseperio\verifactu\models\LegalPerson;
use eseperio\verifactu\models\enums\YesNoType;

$provider = new LegalPerson();
$provider->name = 'Verifactu PHP SDK';
$provider->nif  = 'B99999999';

$system = new ComputerSystem();
$system->providerName          = 'Verifactu PHP SDK';
$system->systemName            = 'MyERP';
$system->systemId              = '01';
$system->version               = '2.0.0';
$system->installationNumber    = '1';
$system->onlyVerifactu         = YesNoType::YES;
$system->multipleObligations       = YesNoType::NO;
$system->hasMultipleObligations    = YesNoType::NO;
$system->setProviderId($provider);

Properties

providerName
string
required
Name of the software provider company (NombreRazon).
systemName
string
required
Name of the billing software system (NombreSistemaInformatico).
systemId
string
required
System identifier code (IdSistemaInformatico). Typically '01' unless multiple systems are used.
version
string
required
Software version string (Version). Example: '2.0.0'
installationNumber
string
required
Installation instance number (NumeroInstalacion). Typically '1' for a single installation.
onlyVerifactu
YesNoType
required
Whether this system exclusively uses VERI*FACTU (TipoUsoPosibleSoloVerifactu). YesNoType::YES or YesNoType::NO.
multipleObligations
YesNoType
required
Whether the system supports multiple taxpayer obligations (TipoUsoPosibleMultiOT). YesNoType::YES or YesNoType::NO.
hasMultipleObligations
YesNoType
required
Whether this installation is currently serving multiple tax obligations (IndicadorMultiplesOT). YesNoType::YES or YesNoType::NO.

Methods

Sets the provider identity. Accepts a LegalPerson object or an array with name and either nif or otherId keys. See LegalPerson.
Returns the stored LegalPerson provider identity.

Validation rules

  • All nine public properties plus providerId are required.
  • onlyVerifactu, multipleObligations, hasMultipleObligations must be YesNoType instances.
  • providerId must be a LegalPerson instance.

LegalPerson represents a natural person or legal entity (PersonaFisicaJuridicaType). Used for invoice recipients, third-party issuers, generator data, and computer system provider IDs. Either a Spanish NIF or a foreign OtherID must be provided.
use eseperio\verifactu\models\LegalPerson;

// Spanish entity (NIF)
$person = new LegalPerson();
$person->name = 'Client Corp S.A.';
$person->nif  = 'A87654321';

// Foreign entity (OtherID)
$person = new LegalPerson();
$person->name = 'Foreign GmbH';
$person->setOtherId([
    'countryCode' => 'DE',
    'idType'      => '02',   // NIF-IVA
    'id'          => 'DE123456789',
]);

Properties

name
string
required
Legal name or company name (NombreRazon).
nif
string
Spanish NIF (NIF). Required when otherId is not set. Use this for Spanish residents and companies.

Methods

setOtherId(OtherID|array $otherId): static
Sets a foreign entity identifier. Required when nif is not set. Accepts an OtherID object or an array with countryCode, idType, and id keys. Throws \Exception if the OtherID fails its own validation.
getOtherId(): OtherID|null
Returns the stored OtherID object, or null if using a NIF.

Validation rules

  • name is required.
  • At least one of nif or otherId must be set.

OtherID holds a non-Spanish tax identifier for a foreign entity (IDOtroType). Used inside LegalPerson when the entity has no Spanish NIF.
use eseperio\verifactu\models\OtherID;
use eseperio\verifactu\models\enums\LegalPersonIdType;

$otherId = new OtherID();
$otherId->countryCode = 'FR';
$otherId->idType      = LegalPersonIdType::VAT_ID->value; // '02'
$otherId->id          = 'FR12345678901';

Properties

idType
string
required
Identifier type code (IDType). Must be one of the LegalPersonIdType enum values:
Enum caseValueDescription
LegalPersonIdType::VAT_ID'02'NIF-IVA (EU VAT number)
LegalPersonIdType::PASSPORT'03'Passport number
LegalPersonIdType::ID_IN_COUNTRY_OF_RESIDENCE'04'ID document in country of residence
LegalPersonIdType::RESIDENCE_CERTIFICATE'05'Residence certificate
LegalPersonIdType::OTHER_PROOF_DOCUMENT'06'Other identifying document
LegalPersonIdType::NOT_REGISTERED'07'Not registered
id
string
required
The identifier value (ID). For example, a VAT number or passport number.
countryCode
string
ISO 3166-1 alpha-2 country code (CodigoPais, optional for idType = '02', required for all other types). Examples: 'FR', 'DE', 'GB', 'NL'.
As of the AEAT 2026 denomination update (v1.2.1, 23/02/2026), the Netherlands uses code 'NL'. The internal AEAT label was updated from “Holanda” to “Países Bajos” but the ISO code 'NL' remains correct and unchanged.

Validation rules

  • idType and id are required strings.
  • idType must be one of: '02', '03', '04', '05', '06', '07'.
  • countryCode is required when idType is not '02' (VAT_ID).

RectificationBreakdown holds the original invoice amounts being corrected in a rectification invoice (DesgloseRectificacionType). Required for rectification invoices (R1–R5) that use the substitutive (S) rectification type.
use eseperio\verifactu\models\RectificationBreakdown;

$rectBreakdown = new RectificationBreakdown();
$rectBreakdown->rectifiedBase = -1000.0;
$rectBreakdown->rectifiedTax  = -210.0;

$invoice->setRectificationBreakdown($rectBreakdown);

// Array shorthand via setRectificationBreakdown()
$invoice->setRectificationBreakdown([
    'rectifiedBase' => -1000.0,
    'rectifiedTax'  => -210.0,
    'rectifiedEquivalenceSurcharge' => 0.0,
]);

Properties

rectifiedBase
float
required
The rectified taxable base amount (BaseRectificada). Typically a negative value representing the base that is being reversed.
rectifiedTax
float
required
The rectified tax amount (CuotaRectificada). Typically negative.
rectifiedEquivalenceSurcharge
float
The rectified equivalence surcharge amount (CuotaRecargoRectificado, optional). Set when the original invoice included an equivalence surcharge.

Validation rules

  • rectifiedBase and rectifiedTax are required.
  • All three fields must be numeric (float, int, or null).

EventRecord represents a system event record submitted to AEAT (RegistroEventoEventosSIF.xsd). Used for reporting billing system lifecycle events such as activations and deactivations.
use eseperio\verifactu\models\EventRecord;

$event = new EventRecord();
$event->versionId = '1.0';
$event->eventData = [
    // AEAT event data fields
];

Properties

versionId
string
required
Schema version identifier (IDVersion). Example: '1.0'
eventData
array
required
The event payload (Evento). An associative array of event fields as defined by the EventosSIF.xsd schema.

Validation rules

  • versionId (string) and eventData (array) are both required.

InvoiceResponse is the return type of both Verifactu::registerInvoice() and Verifactu::cancelInvoice(). It maps to the RespuestaRegFactuSistemaFacturacionType schema.
$response = Verifactu::registerInvoice($invoice);

// Check status
if ($response->submissionStatus === \eseperio\verifactu\models\InvoiceResponse::STATUS_OK) {
    echo 'Success! CSV: ' . $response->csv;
} else {
    // Inspect line-level errors
    foreach ($response->getErrors() as $code => $description) {
        echo "Error $code: $description\n";
    }
}

Constants

ConstantValueDescription
InvoiceResponse::STATUS_OK'Correcto'All records accepted successfully
Partial acceptance ('ParcialmenteCorrecto') and full rejection ('Incorrecto') are reflected in submissionStatus with details available via getErrors() and lineResponses.

Properties

submissionStatus
string
Overall submission status (EstadoEnvio). Compare against InvoiceResponse::STATUS_OK ('Correcto'). Other values include 'ParcialmenteCorrecto' (partial) and 'Incorrecto' (rejected).
csv
string
Secure Verification Code (CSV) generated by AEAT. Only present when the submission is fully accepted (STATUS_OK). Store this alongside your invoice for future reference and QR code generation.
lineResponses
array
Array of per-line response details (RespuestaLinea). Each element is an associative array. Contains CodigoErrorRegistro and DescripcionErrorRegistro keys when a line was rejected.
header
array
Response header (Cabecera) from AEAT.
waitTime
string
Recommended wait time before the next submission (TiempoEsperaEnvio).
submissionData
array
Presentation metadata (DatosPresentacion, optional).

Methods

getErrors(): array
Returns an associative array of error_code => error_description pairs extracted from all lineResponses entries that contain a non-empty CodigoErrorRegistro. Returns an empty array when there are no errors.
$errors = $response->getErrors();
// e.g. ['1105' => 'Factura duplicada']

QueryResponse is the return type of Verifactu::queryInvoices(). It maps to RespuestaConsultaFactuSistemaFacturacionType.
$result = Verifactu::queryInvoices($query);

if ($result->queryResult === 'ConDatos') {
    foreach ($result->foundRecords as $record) {
        // process each record
    }
}

Properties

queryResult
string
Textual result of the query (ResultadoConsulta).
ValueMeaning
'ConDatos'At least one record was found
'SinDatos'No records matched
foundRecords
array
Array of matched invoice records (RegistroRespuestaConsultaFactuSistemaFacturacion). Each element is a raw associative array from the AEAT SOAP response. May be null when there are no results.
paginationIndicator
string
Pagination flag (IndicadorPaginacion). Value 'S' means more pages are available; 'N' means this is the last page.
paginationKey
array
Raw pagination cursor data (ClavePaginacion) from AEAT. Only present when paginationIndicator === 'S'. To fetch the next page, call $query->setPaginationKey($nextPage, $pageSize) with your desired page number and size.
header
array
Response header (Cabecera) from AEAT.
period
array
Period attribution data (PeriodoImputacion) for the returned records.

Validation rules

  • header, period, paginationIndicator, and queryResult are required.
  • header, period, foundRecords, and paginationKey must be arrays when set.
  • paginationIndicator and queryResult must be strings.

Build docs developers (and LLMs) love