The VERI*FACTU regulation offers two valid compliance paths, and the mode your SIF adopts determines how billing records are handled after they are generated. In VERI*FACTU mode, records are submitted to the AEAT in real time as each invoice is issued. In Non-VERI*FACTU mode, records are kept locally with an electronic signature but are not sent unless the AEAT requests them. Both modes require a QR code on every invoice and the same chained-hash integrity mechanism.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.
- VERI*FACTU Mode
- Non-VERI*FACTU Mode
Every registration record must be submitted to AEAT immediately after it is generated. Electronic signatures on individual records are not required because the act of transmission itself fulfils the integrity guarantee. The SIF must be able to reach the AEAT web service endpoint at the time of invoice issuance.
VERI*FACTU mode
In VERI*FACTU mode the SIF acts as a real-time relay: every newRegistrationRecord or CancellationRecord must be dispatched to the AEAT immediately after the invoice is issued, using AeatClient::send(). The AEAT responds with a Código Seguro de Verificación (CSV) that should be stored alongside the invoice.
When your SIF operates exclusively in this mode, set $system->onlySupportsVerifactu = true on the ComputerSystem instance. This flag is included in every SOAP request and tells the AEAT that the system is incapable of operating offline.
ComputerSystem::$supportsMultipleTaxpayers must be true if the SIF is capable of managing billing for more than one taxpayer, regardless of the compliance mode. ComputerSystem::$hasMultipleTaxpayers must additionally be true at the moment a given record is generated if the SIF is actively handling more than one taxpayer at that time.Non-VERI*FACTU mode
In Non-VERI*FACTU mode, the SIF retains all billing records locally. Each record must carry a valid electronic signature before it is stored. The SIF is also required to maintain an event log (libro de registro de eventos) that the AEAT can inspect. Set$system->onlySupportsVerifactu = false to declare that the SIF supports offline operation. Records are created and chained in exactly the same way as in VERI*FACTU mode — the difference is that AeatClient::send() is only called when responding to an AEAT requirement.
Switching modes
A SIF that has been operating in VERI*FACTU mode and needs to switch to Non-VERI*FACTU mode must notify the AEAT of the end date of voluntary remission. UseAeatClient::setVoluntaryRemissionEndDate() and then call send() with an empty array to dispatch the notification without attaching any billing records.
true as the second argument:
Responding to AEAT requirements
In Non-VERI*FACTU mode the AEAT may issue a formal requirement (remisión por requerimiento) asking the SIF to submit a set of billing records. UseAeatClient::setRequirementReference() with the reference string provided by the AEAT. Because a requirement may involve many records, submissions are paginated — use the $isLastRequirementSubmission flag to signal the final batch.
Set the requirement reference
Call
setRequirementReference() with the reference code included in the AEAT requirement document before each send() call.Send intermediate batches
Continue calling
send() with successive batches. As long as more records remain, leave $isLastRequirementSubmission as false (the default).Signal the last submission
On the final batch, pass
true as the second argument to setRequirementReference(). This tells the AEAT there are no more records to submit for this requirement.