Skip to content

Veri*Factu ​

When you issue a sales invoice, Bilteo generates its Veri*Factu billing record, chains it to the previous record using a hash and submits it to the AEAT. This is automatic: you do not need to build or sign anything.

What Bilteo generates ​

  • A registration record (RegistroAlta) when a sales invoice is issued.
  • A cancellation record (RegistroAnulacion) when an issued invoice is cancelled.
  • Each record includes a SHA-256 hash calculated from its key fields and the hash of the tenant's previous record, forming a tamper-evident chain.
Invoice A (registration) ──hash──▶ Invoice B (registration) ──hash──▶ Invoice A (cancellation) ─▶ …
        └── chained per tenant: each record references the previous record's hash

Submission and record statuses ​

Generation and submission are decoupled: the record starts as pending and a later process submits it to the AEAT. Its status reflects the response:

StatusMeaning
pendingGenerated and waiting to be sent.
in-processSent and awaiting a response.
acceptedAccepted by the AEAT.
accepted_errorAccepted with errors (registered).
rejectedRejected (not registered with the AEAT).
unknown_responseNo final response: transport error or unparseable reply. response_code carries the cause (SOAP_CLIENT, HTTP_<status>, INVALID_JSON, INVALID_TYPE). Not a fiscal rejection; needs review.

Transient network or AEAT errors do not change the status: the record goes back to pending and is retried automatically.

A record with a final response (rejected, accepted or accepted_error) can be corrected.

Do not poll: use webhooks

Instead of repeatedly checking the status, subscribe to verifactu.accepted / verifactu.rejected and Bilteo will notify you when the AEAT responds.

QR code ​

Every issued invoice includes its AEAT verification QR code (tax ID, series number, date and total amount), which the recipient can use to verify it. Bilteo embeds it when rendering the PDF.

Reading records

With the verifactu:read scope you can retrieve records and their status through the API. See the Reference.

In testing ​

In a test tenant, records are submitted to the AEAT certification environment, never production. You can also disable record generation when you only need to test your integration. See the Test environment.

Bilteo · Documentation