Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mdiago/VeriFactu/llms.txt

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

InvoiceEntry is the primary class for submitting new invoice records to the AEAT. It wraps an Invoice object, validates it against VERI*FACTU business rules at construction time, adds the record to the seller’s local blockchain, serializes it to a SOAP/XML envelope, and submits it to the AEAT endpoint — all in a single call to .Save().

Namespace

VeriFactu.Business

Herencia

InvoiceEntry → InvoiceAction → InvoiceActionPost → InvoiceActionMessage → InvoiceActionData

Constructor

InvoiceEntry(Invoice invoice)

Creates a new entry and immediately validates the Invoice against business rules.
invoice
Invoice
required
A fully populated Invoice instance. SellerName must be set. Validation runs synchronously in the constructor; if any rule is violated an InvalidOperationException is thrown before the object is usable.
Constructor-time validation checks (via GetBusErrors()):
  • An entry for the same seller + year + invoice number must not already exist on disk.
  • Invoice.SellerName must not be null or empty.
  • Invoice.RectificationItems.Count must be ≤ 1 000.
  • Invoice.TaxItems.Count must be ≤ 12.
  • Each TaxItem with a TaxException set must have zero values for rate/amount fields.
  • All AEAT specification validation rules via InvoiceValidation.
Throws InvalidOperationException listing all validation errors if any are found.

Método Save()

public void Save(X509Certificate2 certificate = null)
Performs the complete submission lifecycle in order:
  1. Validates that Save() has not already been called on this instance.
  2. Verifies the configured AEAT certificate is present and valid.
  3. Adds the RegistroAlta to the seller’s blockchain (assigns the chain link ID and timestamp).
  4. Regenerates the SOAP/XML payload with the now-populated blockchain hash fields.
  5. Writes the XML file to the outbox directory (OutboxPath).
  6. Sends the XML to the AEAT VERI*FACTU SOAP endpoint.
  7. Processes the AEAT response: populates Status, CSV, ErrorCode, ErrorDescription.
  8. On success, saves both the request and response XML files to disk.
  9. On failure, automatically rolls back the blockchain entry (ClearPost()), renames affected files to .ERR.* suffixes, and re-throws a SendException.
certificate
X509Certificate2
Optional. An X509Certificate2 to use for the HTTPS request. If omitted, the certificate configured in Settings.Current is used.
Throws InvalidOperationException if called more than once on the same instance.
Throws SendException (wrapping the original exception) on any communication or processing failure.

Propiedades de respuesta

These properties are populated after Save() completes.
Status
string
Overall submission status returned by the AEAT (EstadoEnvio). Common values:
  • "Correcto" — all records accepted.
  • "ParcialmenteCorrecto" — accepted with errors on individual lines.
  • "Incorrecto" — submission rejected.
null before Save() is called.
CSV
string
Secure Verification Code (Código Seguro de Verificación) assigned by the AEAT to the submission. Non-null only when the submission is accepted ("Correcto" or "ParcialmenteCorrecto" with "AceptadoConErrores" on the line).
ErrorCode
string
AEAT error code. Populated from the SOAP Fault faultcode or from CodigoErrorRegistro on the response line. null when there is no error.
ErrorDescription
string
Human-readable error message. Populated from the SOAP Fault faultstring or from DescripcionErrorRegistro. null when there is no error.
Response
string
Raw XML string of the AEAT SOAP response. Useful for debugging or archiving. null before Save() is called.
Posted
bool
true after the record has been successfully added to the local blockchain. Set to false again if ClearPost() is triggered during a rollback.
IsSent
bool
true after the SOAP request has been dispatched to the AEAT (regardless of the AEAT’s response status).
Xml
byte[]
Binary content of the SOAP/XML envelope sent to the AEAT. Regenerated after the blockchain step so it includes the correct hash chain fields.
InvoiceEntryID
string
Blockchain link ID zero-padded to 20 characters (e.g. "00000000000000000042"). null until the blockchain step completes.
BlockchainManager
Blockchain.Blockchain
The blockchain manager instance handling the seller’s chain. Resolved from Blockchain.Blockchain.Get(Invoice.SellerID) at construction time.

Método GetBusErrors()

// Defined on InvoiceAction (base class); override also present on InvoiceFix
public virtual List<string> GetBusErrors()
Returns the list of business-rule validation errors for the wrapped invoice without throwing. This method is defined on InvoiceAction (the base class) and called automatically during construction. Call it explicitly on an InvoiceAction instance before constructing InvoiceEntry if you want to inspect errors programmatically rather than catching an exception. Returns: List<string> — empty if the invoice is valid; one entry per violated rule otherwise.

Ejemplo

using VeriFactu.Business;
using VeriFactu.Xml.Factu;
using VeriFactu.Xml.Factu.Alta;

var invoice = new Invoice("FAC-2024-001", new DateTime(2024, 11, 15), "B72877814")
{
    InvoiceType = TipoFactura.F1,
    SellerName  = "MI EMPRESA SL",
    BuyerID     = "B44531218",
    BuyerName   = "CLIENTE SL",
    Text        = "SERVICIOS PROFESIONALES",
    TaxItems    = new List<TaxItem>
    {
        new TaxItem
        {
            TaxScheme = ClaveRegimen.RegimenGeneral,
            TaxType   = CalificacionOperacion.S1,
            TaxRate   = 21,
            TaxBase   = 1000,
            TaxAmount = 210
        }
    }
};

// Optional: pre-flight validation without throwing
var errors = new InvoiceAction(invoice).GetBusErrors();
if (errors.Count > 0)
{
    foreach (var err in errors)
        Console.WriteLine(err);
    return;
}

// Submit to AEAT
var entry = new InvoiceEntry(invoice);
entry.Save();

if (entry.Status == "Correcto")
    Console.WriteLine($"Accepted — CSV: {entry.CSV}");
else
    Console.WriteLine($"Rejected — {entry.ErrorCode}: {entry.ErrorDescription}");

Build docs developers (and LLMs) love