IQeSign.TicketBai 1.0.0

dotnet add package IQeSign.TicketBai --version 1.0.0
                    
NuGet\Install-Package IQeSign.TicketBai -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IQeSign.TicketBai" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IQeSign.TicketBai" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="IQeSign.TicketBai" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add IQeSign.TicketBai --version 1.0.0
                    
#r "nuget: IQeSign.TicketBai, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package IQeSign.TicketBai@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=IQeSign.TicketBai&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=IQeSign.TicketBai&version=1.0.0
                    
Install as a Cake Tool

IQeSign.TicketBai

NuGet License: MIT .NET

Cliente .NET para la API IQ eSign TicketBAI de InnoQubit Software. Permite integrar desde cualquier aplicación .NET la presentación de facturas electrónicas a las haciendas forales del País Vasco (Álava, Gipuzkoa y Bizkaia), gestionando certificados digitales, firma de peticiones y encadenamiento automático.


Sobre InnoQubit

InnoQubit Business Software es una empresa tecnológica con sede en Castellón (España), especializada en la digitalización y automatización de procesos empresariales para sistemas ERP.

Su producto insignia IQ eSign agrupa soluciones de facturación electrónica y firma digital que se integran con cualquier ERP (Microsoft Dynamics 365 Business Central, Navision y software a medida):

Solución Descripción
IQ eSign VeriFactu Presentación de facturas al sistema VeriFactu de la AEAT
IQ eSign TicketBAI Facturación electrónica para el País Vasco
IQ eSign Facturae Generación y envío de facturas en formato Facturae
IQ eSign ePDF Generación de PDFs firmados digitalmente

¿Qué es TicketBAI?

TicketBAI es el sistema de facturación electrónica obligatorio en el País Vasco, regulado por las haciendas forales de Álava, Gipuzkoa y Bizkaia. Garantiza la integridad de cada factura mediante encadenamiento de firmas digitales y su presentación en tiempo real a la hacienda foral correspondiente.

Este paquete encapsula toda la complejidad de la integración:

  • Autenticación JWT automática con refresco de token
  • Firma de peticiones con certificado digital (.pfx) almacenado en IQ Portal
  • Encadenamiento automático de facturas (gestión de HuellaTbai)
  • Soporte para facturas emitidas y recibidas
  • Soporte para correcciones (Zuzendu) en Álava y Gipuzkoa
  • Gestión de facturas simplificadas y rectificativas
  • Reintentos de envío para documentos con fallos transitorios

Instalación

dotnet add package IQeSign.TicketBai

Para obtener una cuenta y el CredentialGuid necesarios para usar este paquete, contacta con el equipo comercial de InnoQubit en comercial@innoqubit.com.


Inicio rápido

1. Registro en el contenedor DI

// Program.cs
builder.Services.AddIQeSignTicketBai(options =>
{
    options.CredentialGuid = builder.Configuration["IQeSignTicketBai:CredentialGuid"]!;
    options.Environment = IQeSignEnvironment.Production; // o Staging para pruebas
    options.TimeoutSeconds = 30;
});

O bien usando una sección de appsettings.json:

{
  "IQeSignTicketBai": {
    "CredentialGuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Environment": "Production"
  }
}
builder.Services.AddIQeSignTicketBai(
    builder.Configuration.GetSection(IQeSignOptions.SectionName));

2. Enviar una factura emitida

public class FacturacionService(ITicketBaiService ticketBai)
{
    public async Task<string> EnviarFacturaAsync(CancellationToken ct = default)
    {
        var response = await ticketBai.AddDocumentAsync(new AddDocumentRequest
        {
            CertificateId = "id-del-certificado-en-iqportal",
            CertificatePass = "contraseña-del-pfx",
            File = new TicketBaiDocumentFile
            {
                Issuer = new TicketBaiIssuerInfo
                {
                    Name = "Mi Empresa S.L.",
                    CifNif = "B12345678",
                    TaxCategory = "662"
                },
                Serial = "FAC",
                Number = "2024-001",
                Date = "2024-01-15",
                Name = "Cliente S.A.",
                Nif = "A98765432",
                Address = "Calle Mayor 1",
                ZipCode = "28001",
                Country = "ES",
                Simplified = false,
                OperationType = OperationTypeEmitted.SinInversion,
                Rectified = false,
                TotalInvoice = 1210.00m,
                Administration = Administration.Gipuzkoa,
                Lines =
                [
                    new InvoiceLine
                    {
                        Description = "Servicios de consultoría",
                        Quantity = 1,
                        UnitAmount = 1000.00m,
                        DiscountAmount = 0m,
                        Vat = 21m,
                        VatEc = 0m,
                        VatSubject = true,
                        VatCause = VatCause.E1,
                        TaxKey = TaxKey.RegimenGeneral
                    }
                ]
            },
            Metadata = new DocumentMetadata
            {
                Platform = "MiApp",
                Version = "1.0.0",
                User = "usuario@empresa.com",
                Email = "facturacion@empresa.com",
                Company = "Mi Empresa S.L.",
                Tenant = "tenant-001",
                Description = "Factura generada desde MiApp"
            }
        }, ct);

        if (!response.IsSuccess)
            throw new Exception($"Error TicketBAI [{response.ErrorCode}]: {response.ErrorMessage}");

        return response.Result!.Id!;
    }
}

3. Registrar una factura recibida

public class FacturasRecibidasService(ITicketBaiReceivedService received)
{
    public async Task<string> RegistrarAsync(CancellationToken ct = default)
    {
        var response = await received.AddReceivedAsync(new AddReceivedRequest
        {
            CertificateId = "id-del-certificado",
            CertificatePass = "contraseña",
            File = new ReceivedDocumentFile
            {
                Issuer = new ReceivedIssuerInfo
                {
                    Name = "Proveedor S.L.",
                    CifNif = "B87654321",
                    Country = "ES",
                    IdentifierType = IdentifierType.NifIva
                },
                OperationType = ReceivedOperationType.AdquisicionBienesServicios,
                InvoiceType = ReceivedInvoiceType.FacturaConDestinatario,
                Serial = "PRV",
                Number = "2024-100",
                Exercise = 2024,
                ReceivedDate = "2024-01-20",
                InvoiceDate = "2024-01-18",
                SalesVatQuote = 0m,
                Name = "Mi Empresa S.L.",
                Nif = "B12345678",
                Description = "Servicios de consultoría recibidos",
                Rectified = false,
                TaxBase = 500.00m,
                TotalInvoice = 605.00m
            }
        }, ct);

        if (!response.IsSuccess)
            throw new Exception($"[{response.ErrorCode}] {response.ErrorMessage}");

        return response.Result!.Id!;
    }
}

4. Gestión de certificados

public class CertificadoService(ICertificateService certs)
{
    public async Task<string> SubirCertificadoAsync(byte[] pfxBytes, string nombre)
    {
        var resp = await certs.AddAsync(new AddCertificateRequest
        {
            Name = nombre,
            File = Convert.ToBase64String(pfxBytes)
        });
        return resp.Result!.Id;
    }
}

Servicios disponibles

ITicketBaiService — Facturas emitidas

Método Endpoint Descripción
GetUsageAsync() GET /api/v2/Ticketbai/Usage Consulta el consumo del plan contratado
AddDocumentAsync(request) POST /api/v2/TicketBai/Document Envía una factura emitida a la hacienda foral
GetDocumentByIdAsync(id) GET /api/v2/TicketBai/Document/{id} Consulta el estado y datos de un documento
DownloadDocumentAsync(id) GET /api/v2/TicketBai/Document/{id}/Download Descarga el ZIP con el XML firmado (Base64)
CancelDocumentAsync(id) PUT /api/v2/TicketBai/Document/{id}/Cancel Cancela un documento en la hacienda foral
RetryDocumentAsync(id) PUT /api/v2/TicketBai/Document/{id}/Retry Reintenta un envío fallido (Processed=false)
ListDocumentsAsync(filtros?) GET /api/v2/TicketBai/Document/List Lista documentos con filtro de fechas opcional
AddZuzenduAsync(id, request) POST /api/v2/TicketBai/Document/{id}/Zuzendu Envía una corrección Zuzendu (Álava/Gipuzkoa)
CancelZuzenduAsync(id) PUT /api/v2/TicketBai/Document/{id}/Zuzendu/Cancel Cancela un Zuzendu

ITicketBaiReceivedService — Facturas recibidas

Método Endpoint Descripción
AddReceivedAsync(request) POST /api/v2/TicketBai/Received Registra una factura recibida
CancelReceivedAsync(id, request) PUT /api/v2/TicketBai/Received/{id}/Cancel Cancela una factura recibida
CheckReceivedAsync(id, request) PUT /api/v2/TicketBai/Received/{id}/Check Consulta el estado en la hacienda foral
UpdateReceivedAsync(id, request) PUT /api/v2/TicketBai/Received/{id} Actualiza una factura recibida
ListReceivedAsync(filtros?) GET /api/v2/TicketBai/Received/List Lista facturas recibidas con filtro de fechas

ICertificateService — Certificados digitales

Método Endpoint Descripción
AddAsync(request) POST /api/v2/Certificate Sube un certificado .pfx en Base64
GetByIdAsync(id) GET /api/v2/Certificate/{id} Consulta un certificado por ID
DownloadAsync(id) GET /api/v2/Certificate/{id}/Download Descarga el .pfx en Base64
ListAsync() GET /api/v2/Certificate/List Lista todos los certificados
DeleteAsync(id) DELETE /api/v2/Certificate/{id} Elimina un certificado

Listas de referencia TicketBAI

// Administración hacienda foral
Administration.Alava       // "Álava"
Administration.Gipuzkoa    // "Gipuzkoa"
Administration.Bizkaia     // "Bizkaia" (solo facturas emitidas, no Zuzendu)

// Clave fiscal / régimen (L9)
TaxKey.RegimenGeneral      // "01"
TaxKey.Exportacion         // "02"

// Causa de exención (L10)
VatCause.Articulo20        // "E1"
VatCause.NoSujetoArticulo7 // "OT"

// Tipo de operación emitida (L11)
OperationTypeEmitted.SinInversion  // "S1"
OperationTypeEmitted.ConInversion  // "S2"

// Tipo de factura recibida (L18)
ReceivedInvoiceType.FacturaConDestinatario     // "F1"
ReceivedInvoiceType.FacturaSinDestinatario     // "F2"

// Código de rectificación (L7)
RectificationCode.R1  // "R1" — Error fundado en derecho
RectificationCode.R5  // "R5" — Facturas simplificadas

// Tipo de compra (L19)
PurchaseType.ComprasBienes   // "C"
PurchaseType.Gastos          // "G"
PurchaseType.BienesInversion // "I"

// Inversión del sujeto pasivo (L20)
ReverseCharge.Si  // "S"
ReverseCharge.No  // "N"

Documentos con envío fallido (Processed = false)

Si el envío a la hacienda foral falla por un error transitorio, la API devuelve el Id del documento pero con Processed = false. Usa RetryDocumentAsync para reintentarlo:

var doc = await ticketBai.GetDocumentByIdAsync(id, ct);
if (!doc.Result!.Processed)
{
    var retry = await ticketBai.RetryDocumentAsync(id, ct);
    if (!retry.IsSuccess)
        Console.WriteLine($"Reintento fallido: {retry.ErrorMessage}");
}

Si existe un documento pendiente con Processed = false, la API devuelve el aviso "00001" al intentar enviar uno nuevo. Resuelve primero el documento pendiente con RetryDocumentAsync.


Control de errores

var response = await ticketBai.AddDocumentAsync(request, ct);

if (!response.IsSuccess)
{
    // ErrorCode "0"  → éxito
    // ErrorCode "8"  → validación incorrecta (datos, ID no encontrado, plataforma rechaza)
    // ErrorCode "9"  → error no controlado (ver ErrorMessage)
    // Otros valores  → error de negocio controlado (ver ErrorMessage)
    Console.WriteLine($"[{response.ErrorCode}] {response.ErrorMessage}");
}

// Avisos de la plataforma (no impiden el registro)
foreach (var w in response.Result?.Warning ?? [])
    Console.WriteLine($"Aviso [{w.Code}]: {w.Message} / {w.Azalpena}");

Las excepciones se lanzan únicamente ante fallos de comunicación:

Excepción Cuándo se lanza
IQeSignAuthException El CredentialGuid es inválido o la cuenta está inactiva
IQeSignApiException La API devuelve un código HTTP 4xx/5xx inesperado

Entornos

Entorno URL Uso
IQeSignEnvironment.Production https://iqesignapi.azurewebsites.net Producción real
IQeSignEnvironment.Staging https://iqesignapistaging.azurewebsites.net Pruebas e integración

Requisitos

  • .NET 8.0 o .NET Standard 2.1 (compatible con .NET 6+, .NET 7+)
  • Cuenta activa en IQ Portal con la solución IQ eSign TicketBAI contratada
  • Certificado digital .pfx válido para firma de facturas (FNMT, ACA, etc.)

Documentación adicional


Licencia

MIT © InnoQubit Software

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 94 5/13/2026