SatCatch 1.0.4

dotnet add package SatCatch --version 1.0.4
                    
NuGet\Install-Package SatCatch -Version 1.0.4
                    
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="SatCatch" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SatCatch" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="SatCatch" />
                    
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 SatCatch --version 1.0.4
                    
#r "nuget: SatCatch, 1.0.4"
                    
#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 SatCatch@1.0.4
                    
#: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=SatCatch&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=SatCatch&version=1.0.4
                    
Install as a Cake Tool

<div align="center"> <img class="notranslate" translate="no" src="https://raw.githubusercontent.com/RaulZamoraPerez/sat-descarga-masiva/main/icon.png" alt="SatCatch Logo" width="128" height="128" />

SatCatch

Librería .NET para el Servicio de Descarga Masiva del SAT México

Compatibilidad nativa con .NET 8.0 y .NET 9.0 sin dependencias externas.

NuGet Downloads .NET License

</div>


Características de la Librería

  • Cero dependencias externas: Desarrollada exclusivamente con las librerías oficiales de Microsoft.
  • Caché automático de tokens: Reutiliza el token de acceso activo y evita peticiones redundantes al SAT utilizando la interfaz ISatTokenCache.
  • Extracción flexible de XMLs: Permite realizar la descompresión directamente a disco con auto-limpieza del archivo ZIP o extraer en memoria para entornos serverless.
  • Traducción de errores: Mapea códigos SOAP y HTTP del SAT a mensajes comprensibles en español.
  • Orquestador asíncrono: Incluye lógica de consulta continua (polling) resiliente a fallos de red temporales y retrasos en la infraestructura del SAT.
  • Multi-compatibilidad: Soporte para CFDI Normal, CFDI de Retenciones, búsquedas por fechas y consultas por Folio Fiscal (UUID).

Instalación

Para instalar el paquete en su proyecto, ejecute el siguiente comando en la consola de NuGet:

dotnet add package SatCatch

API Reference y Guía de Uso

1. Inicialización de Credenciales (SatCredentials)

La clase SatCredentials encapsula la e.firma. Implementa IDisposable para asegurar la liberación inmediata de los recursos criptográficos del sistema operativo.

using SatDescargaMasiva;

// Cargar archivos en memoria
byte[] cerBytes = File.ReadAllBytes("ruta_certificado.cer");
byte[] keyBytes = File.ReadAllBytes("ruta_llave.key");
string password = "mi_contraseña";

using var credentials = SatCredentials.FromBytes(
    rfc: "PEGA730105IZ2",
    cerBytes: cerBytes,
    keyBytes: keyBytes,
    password: password
);

2. Inyección de Dependencias (ServiceCollection)

Para utilizar el cliente en aplicaciones ASP.NET Core o Worker Services, regístrelo mediante el método de extensión:

using Microsoft.Extensions.DependencyInjection;

// Registra ISatDescargaMasivaClient y el caché en memoria por defecto
builder.Services.AddSatDescargaMasivaClient();

3. Cliente de Descarga Masiva (SatDescargaMasivaClient)

La clase SatDescargaMasivaClient es la interfaz principal para comunicarse con los servicios del SAT.

Solicitar Descarga (SolicitarDescargaAsync)

Inicia una solicitud de descarga masiva ante el SAT. Admite criterios por fechas o por Folio Fiscal (UUID).

using SatDescargaMasiva.Models;

var client = new SatDescargaMasivaClient();

// Ejemplo A: Búsqueda por Rango de Fechas
var reqFechas = new SolicitudDescargaRequest
{
    FechaInicio = DateTime.Today.AddDays(-5),
    FechaFin = DateTime.Today,
    TipoDescarga = TipoDescarga.Recibidos,
    TipoCfdi = TipoCfdi.Normal,
    TipoSolicitud = TipoSolicitud.Cfdi,
    EstadoComprobante = EstadoComprobante.Vigente
};

var result = await client.SolicitarDescargaAsync(credentials, reqFechas);

if (result.IsSuccess)
{
    Console.WriteLine($"Solicitud Aceptada. IdSolicitud: {result.IdSolicitud}");
}
// Ejemplo B: Búsqueda por Folio Fiscal (UUID)
var reqUuid = new SolicitudDescargaRequest
{
    Folio = "851C907A-ACD4-406D-A0A3-CC795EF7D651",
    FechaInicio = new DateTime(2022, 12, 1),
    FechaFin = new DateTime(2022, 12, 31),
    TipoDescarga = TipoDescarga.Emitidos,
    TipoCfdi = TipoCfdi.Normal,
    TipoSolicitud = TipoSolicitud.Cfdi
};

var result = await client.SolicitarDescargaAsync(credentials, reqUuid);
Verificar Solicitud (VerificarSolicitudDescargaAsync)

Consulta el estatus de procesamiento del SAT para un IdSolicitud específico.

var verifRequest = new VerificacionRequest
{
    IdSolicitud = "id_solicitud_anterior",
    TipoCfdi = TipoCfdi.Normal
};

var verifResult = await client.VerificarSolicitudDescargaAsync(credentials, verifRequest);

if (verifResult.IsSuccess)
{
    Console.WriteLine($"Estado de solicitud: {verifResult.EstadoSolicitud}"); // Terminada, EnProceso, Aceptada
    Console.WriteLine($"Cantidad de XMLs: {verifResult.NumeroCfdis}");
    Console.WriteLine($"Paquetes a descargar: {verifResult.IdPaquetes.Count}");
}
Descargar Paquete (DescargarPaqueteAsync)

Descarga el archivo ZIP correspondiente a un IdPaquete una vez que la solicitud está en estado Terminada.

var downloadReq = new DescargaPaqueteRequest
{
    IdPaquete = "paquete_id_obtenido",
    TipoCfdi = TipoCfdi.Normal
};

var downloadResult = await client.DescargarPaqueteAsync(credentials, downloadReq);

if (downloadResult.IsSuccess && downloadResult.ArchivoZip != null)
{
    // El archivo ZIP está listo como byte[]
    File.WriteAllBytes("paquete.zip", downloadResult.ArchivoZip);
}

4. Orquestación Asíncrona (SatDownloadOrchestrator)

Clase utilitaria para realizar consultas continuas (polling) al SAT en segundo plano hasta completar el procesamiento. Soporta la tolerancia y reintentos ante fallos temporales de comunicación o base de datos del SAT.

using SatDescargaMasiva;

// Realiza consultas cada 60 segundos con un tiempo máximo de espera de 15 minutos
var orchestratorResult = await SatDownloadOrchestrator.PollUntilCompleteAsync(
    client,
    credentials,
    idSolicitud: "id_solicitud",
    TipoCfdi.Normal,
    pollInterval: TimeSpan.FromSeconds(60),
    timeout: TimeSpan.FromMinutes(15)
);

if (orchestratorResult.EstadoSolicitud == EstadoSolicitud.Terminada)
{
    Console.WriteLine("La solicitud ha sido procesada por el SAT.");
}

5. Descompresión de Paquetes (SatZipUtility)

Ofrece utilidades optimizadas para extraer comprobantes de los archivos ZIP del SAT.

Extracción física con limpieza automática

Extrae todos los archivos XML en una ruta específica y elimina el archivo ZIP de inmediato para optimizar espacio en disco.

using SatDescargaMasiva;

List<string> rutasXmlExtraidos = SatZipUtility.ExtractZipFileToDirectory(
    zipFilePath: "ruta/archivo.zip",
    targetDirectory: "ruta/destino",
    deleteZipAfterExtraction: true // Elimina el archivo ZIP origen tras descomprimir
);
Extracción en memoria (Serverless)

Extrae los archivos XML directamente a memoria como strings. No requiere permisos de escritura en disco.

using SatDescargaMasiva;

List<(string FileName, string XmlContent)> xmlsInMemory = SatZipUtility.ExtractXmlsInMemory(zipBytes);

foreach (var xml in xmlsInMemory)
{
    Console.WriteLine($"Archivo: {xml.FileName}");
    Console.WriteLine($"XML: {xml.XmlContent}");
}

6. Traducción de Errores (SatErrorTranslator)

Clase utilitaria para convertir códigos de error devueltos por los servicios del SAT en mensajes descriptivos en español.

using SatDescargaMasiva;

string mensajeEnEspanol = SatErrorTranslator.Translate("5002");
// Retorna: "Se ha agotado el límite de solicitudes para este periodo."

Caching Personalizado

Por defecto, la librería utiliza memoria (InMemorySatTokenCache). Para utilizar un caché compartido (por ejemplo, Redis o una Base de Datos), implemente la interfaz ISatTokenCache y regístrela en el contenedor de servicios:

using System;
using System.Threading.Tasks;
using SatDescargaMasiva.Caching;

public class RedisTokenCache : ISatTokenCache
{
    public async Task<string?> GetAsync(string key)
    {
        // Obtener del servidor de Redis
    }

    public async Task SetAsync(string key, string token, TimeSpan expiration)
    {
        // Guardar en Redis con expiración
    }
}

// En el archivo de configuración de servicios (Program.cs)
builder.Services.AddSingleton<ISatTokenCache, RedisTokenCache>();

Licencia y Exclusión de Responsabilidad

Este proyecto está licenciado bajo la Licencia MIT.

Exclusión de Responsabilidad (Disclaimer)

Esta librería es una herramienta independiente y no tiene relación oficial, patrocinio ni respaldo del Servicio de Administración Tributaria (SAT) de México. El uso de esta librería es responsabilidad exclusiva del usuario. Los autores y colaboradores no se hacen responsables bajo ninguna circunstancia por errores en la declaración de impuestos, fallos del sistema, bloqueos de IP, sanciones del SAT, pérdidas de datos o cualquier otro perjuicio derivado de su utilización.

Product Compatible and additional computed target framework versions.
.NET 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 is compatible.  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. 
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.4 106 7/23/2026
1.0.2 94 7/23/2026
1.0.1 97 7/23/2026
1.0.0 97 7/23/2026