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.

InvoiceSubmission (XML schema: RegistroAltaType) represents a new invoice registration request sent to AEAT. It extends InvoiceRecord, which in turn extends the abstract Model base class.
use eseperio\verifactu\models\InvoiceSubmission;

$invoice = new InvoiceSubmission();
Pass a populated instance to Verifactu::registerInvoice() to submit it to AEAT.

Properties inherited from InvoiceRecord

These fields are common to both InvoiceSubmission and InvoiceCancellation. They must be set on every record.

Required inherited fields

versionId
string
default:"'1.0'"
Schema version identifier (IDVersion). Defaults to '1.0' and should not need to be changed unless AEAT releases a new schema version.
invoiceId
InvoiceId
required
Invoice identification block (IDFactura). Contains the issuer’s NIF, the series + invoice number, and the issue date. Set via setInvoiceId(). See InvoiceId.
chaining
Chaining
required
Hash-chaining data (Encadenamiento). Links this record to the previous one in the submission chain, or marks it as the first record. Set via setChaining() or setAsFirstRecord(). See Chaining.
systemInfo
ComputerSystem
required
Billing software information (SistemaInformatico). Identifies the software system generating the invoice. Set via setSystemInfo(). See ComputerSystem.
recordTimestamp
string
required
ISO 8601 timestamp with timezone offset for when the record was generated (FechaHoraHusoGenRegistro). Example: '2025-01-15T10:30:00+01:00'. Use date('Y-m-d\TH:i:sP') to generate dynamically.
hashType
HashType
default:"HashType::SHA_256"
Hash algorithm used (TipoHuella). Always HashType::SHA_256 ('01') as mandated by AEAT. You do not need to set this manually.
hash
string
SHA-256 chain hash (Huella) of this record. Automatically computed by the library before submission — do not set manually.

Optional inherited fields

externalRef
string
Free-form external reference (RefExterna, optional). Use this to store your own internal identifier (e.g. your ERP’s invoice ID) alongside the AEAT record. Max 60 characters per the XSD.
fechaFinVeriFactu
string
End date for voluntary VERI*FACTU submission (FechaFinVeriFactu, optional). Must be '31-12-YYYY' format (December 31st of the current or previous year). Used when voluntarily ceasing VERI*FACTU submissions. Corresponds to AEAT validation rule 31.1.3.

InvoiceSubmission-specific properties

Required fields

issuerName
string
required
Issuer’s full legal name or company name (NombreRazonEmisor). Example: 'Mi Empresa S.L.'
invoiceType
InvoiceType
required
Invoice type code (TipoFactura). Determines recipient requirements and validation rules.
Enum caseValueDescription
InvoiceType::STANDARDF1Standard invoice (Art. 6, 7.2, 7.3 RD 1619/2012). Recipient required.
InvoiceType::SIMPLIFIEDF2Simplified invoice / no-recipient-ID invoice (Art. 6.1.d). Recipient not required (or not allowed unless identified).
InvoiceType::REPLACEMENTF3Replacement for previously declared simplified invoices. Recipient required.
InvoiceType::RECTIFICATION_1R1Rectification invoice (Art. 80.1, 80.2, law-based errors). Recipient required.
InvoiceType::RECTIFICATION_2R2Rectification invoice (Art. 80.3). Recipient required.
InvoiceType::RECTIFICATION_3R3Rectification invoice (Art. 80.4). Recipient required.
InvoiceType::RECTIFICATION_4R4Rectification invoice (other cases). Recipient required.
InvoiceType::RECTIFICATION_SIMPLIFIEDR5Rectification for simplified invoices. Recipient not allowed.
operationDescription
string
required
Free-text description of the operation (DescripcionOperacion). Example: 'Consulting services — January 2025'
taxAmount
float
required
Total tax amount applied across all breakdown lines (CuotaTotal). Must match the sum of taxAmount values in the breakdown details.
totalAmount
float
required
Total invoice amount including tax (ImporteTotal). The final amount the recipient pays.

Optional fields

rectificationType
RectificationType
Rectification method (TipoRectificativa). Required when invoiceType is any R1–R5 code.
Enum caseValueDescription
RectificationType::SUBSTITUTIVESFull substitution of the original invoice
RectificationType::INCREMENTALIOnly the difference from the original is recorded
operationDate
string
Date the operation actually occurred if different from the issue date (FechaOperacion, optional). Format: YYYY-MM-DD.
simplifiedInvoice
YesNoType
Flags this as a simplified invoice under Art. 72–73 LIVA (FacturaSimplificadaArt7273, optional). Use YesNoType::YES / YesNoType::NO.
invoiceWithoutRecipient
YesNoType
Flags the invoice as issued without recipient identification under Art. 6.1.d RD 1619/2012 (FacturaSinIdentifDestinatarioArt61d, optional).
macrodata
YesNoType
Macrodata indicator (Macrodato, optional). Use YesNoType::YES for invoices above the macrodata threshold defined by AEAT.
issuedBy
ThirdPartyOrRecipientType
Indicates who issued the invoice when it is not the obliged party (EmitidaPorTerceroODestinatario, optional).
Enum caseValueDescription
ThirdPartyOrRecipientType::RECIPIENTDIssued by the recipient
ThirdPartyOrRecipientType::THIRD_PARTYTIssued by a third party
coupon
YesNoType
Coupon indicator (Cupon, optional). Set to YesNoType::YES when the invoice relates to a coupon operation.
invoiceAgreementNumber
string
Invoice agreement registration number (NumRegistroAcuerdoFacturacion, optional).
systemAgreementId
string
Computer system agreement identifier (IdAcuerdoSistemaInformatico, optional).

Methods

setInvoiceId(InvoiceId|array $invoiceId): static

Sets the invoice identifier. Accepts either an InvoiceId object or a plain array with issuerNif, seriesNumber, and issueDate keys.
// Array shorthand
$invoice->setInvoiceId([
    'issuerNif'    => 'B12345678',
    'seriesNumber' => 'A-2025/001',
    'issueDate'    => '2025-01-15',   // YYYY-MM-DD
]);

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

setBreakdown(Breakdown|array $breakdown): static

Replaces the entire tax breakdown. Accepts a Breakdown object or an array of breakdown item arrays. Prefer addBreakdownDetail() for individual lines.

addBreakdownDetail(BreakdownDetail|array $detail): static

Adds a single tax line to the breakdown. Lazily creates a Breakdown instance if none exists. See BreakdownDetail for the full property list.
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;

$invoice->addBreakdownDetail($detail);

setChaining(Chaining|array $chaining): static

Sets the chaining data linking this record to the previous submission. Accepts a Chaining object or an array. For the very first invoice in a chain, use setAsFirstRecord() instead.
// Link to a previous invoice
$invoice->setChaining([
    'previousInvoice' => [
        'issuerNif'    => 'B12345678',
        'seriesNumber' => 'A-2024/099',
        'issueDate'    => '2024-12-31',
    ],
    'previousHash' => 'abc123...',
]);

setAsFirstRecord(): static

Convenience method. Creates a Chaining object with firstRecord = 'S' and sets it on the submission. Use this for the first invoice you ever submit for an issuer/system combination.
$invoice->setAsFirstRecord();

setSystemInfo(ComputerSystem|array $systemInfo): static

Sets the billing software information. Accepts a ComputerSystem object or a legacy array with system, version, providerName, etc. keys.

addRecipient(LegalPerson|array $recipient): static

Adds a recipient to the Destinatarios list. Recipient requirement depends on invoiceType:
Invoice typeRecipient rule
F1 (STANDARD)Required — at least one recipient must be added
F2 (SIMPLIFIED)Not required; not allowed unless invoiceWithoutRecipient is explicitly set to NO
F3 (REPLACEMENT)Required
R1–R4 (RECTIFICATION)Required
R5 (RECTIFICATION_SIMPLIFIED)Not allowed
$recipient = new LegalPerson();
$recipient->name = 'Client Corp S.A.';
$recipient->nif  = 'A87654321';
$invoice->addRecipient($recipient);

// Array shorthand
$invoice->addRecipient(['name' => 'Client Corp S.A.', 'nif' => 'A87654321']);

setThirdParty(LegalPerson|array $thirdParty): static

Sets the third-party issuer (Tercero). Used when issuedBy is ThirdPartyOrRecipientType::THIRD_PARTY.

setRectificationData(array $data): static

Replaces all rectification reference data at once. The array may contain:
  • 'rectified' — array of rectified invoice references (FacturasRectificadas)
  • 'substituted' — array of substituted invoice references (FacturasSustituidas)
Each reference is an associative array with issuerNif, seriesNumber, and issueDate.

addRectifiedInvoice(string $issuerNif, string $seriesNumber, string $issueDate): static

Appends a single rectified invoice reference to the FacturasRectificadas list.
$invoice->addRectifiedInvoice('B12345678', 'A-2024/055', '2024-11-01');

addSubstitutedInvoice(string $issuerNif, string $seriesNumber, string $issueDate): static

Appends a single substituted invoice reference to the FacturasSustituidas list.

addBreakdownItem(float $rate, float $base, float $amount): static

Deprecated. Use addBreakdownDetail() instead. addBreakdownItem() is kept for backward compatibility only and sets a fixed operationQualification of SUBJECT_NO_EXEMPT_NO_REVERSE. It will be removed in a future release.
Adds a simplified tax breakdown line using raw rate, base, and amount values. Internally creates a BreakdownDetail with operationQualification forced to OperationQualificationType::SUBJECT_NO_EXEMPT_NO_REVERSE.

setRectificationBreakdown(RectificationBreakdown|array $data): static

Sets the rectification amounts breakdown (ImporteRectificacion). Required for rectification invoices that use substitutive (S) rectification type. See RectificationBreakdown.
$invoice->setRectificationBreakdown([
    'rectifiedBase' => -1000.0,
    'rectifiedTax'  => -210.0,
]);

validate(): array

Validates all properties against the model’s rule set. Returns an empty array on success, or an associative array of 'ClassName::$property' => ['error message', ...] on failure. Validation is also run automatically before submission.
$errors = $invoice->validate();
if (!empty($errors)) {
    foreach ($errors as $field => $messages) {
        echo "$field: " . implode(', ', $messages) . "\n";
    }
}

Complete example

<?php

use eseperio\verifactu\Verifactu;
use eseperio\verifactu\models\InvoiceSubmission;
use eseperio\verifactu\models\ComputerSystem;
use eseperio\verifactu\models\LegalPerson;
use eseperio\verifactu\models\BreakdownDetail;
use eseperio\verifactu\models\enums\InvoiceType;
use eseperio\verifactu\models\enums\YesNoType;
use eseperio\verifactu\models\enums\TaxType;
use eseperio\verifactu\models\enums\RegimeType;
use eseperio\verifactu\models\enums\OperationQualificationType;

$invoice = new InvoiceSubmission();

// Required base fields
$invoice->issuerName          = 'Mi Empresa S.L.';
$invoice->invoiceType         = InvoiceType::STANDARD;
$invoice->operationDescription = 'Professional services Q1 2025';
$invoice->taxAmount           = 210.0;
$invoice->totalAmount         = 1210.0;
$invoice->recordTimestamp     = date('Y-m-d\TH:i:sP');

// Invoice ID
$invoice->setInvoiceId([
    'issuerNif'    => 'B12345678',
    'seriesNumber' => 'SRV-2025/001',
    'issueDate'    => '2025-01-20',
]);

// First record in the chain
$invoice->setAsFirstRecord();

// Billing software
$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);
$invoice->setSystemInfo($system);

// Tax breakdown
$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;
$invoice->addBreakdownDetail($detail);

// Recipient (required for F1)
$recipient = new LegalPerson();
$recipient->name = 'Client S.A.';
$recipient->nif  = 'A11111111';
$invoice->addRecipient($recipient);

// Validate before submission
$errors = $invoice->validate();
if (!empty($errors)) {
    throw new \RuntimeException('Invoice validation failed: ' . json_encode($errors));
}

$response = Verifactu::registerInvoice($invoice);

Build docs developers (and LLMs) love