|
1 | | -# Fiscalapi XML Downloader (sat-ws-descarga-masiva) |
| 1 | +# 🧾 Fiscalapi XML Downloader (sat-ws-descarga-masiva) |
2 | 2 |
|
3 | 3 | [](https://www.nuget.org/packages/Fiscalapi.XmlDownloader) |
4 | | -[](https://github.com/FiscalAPI/xml-downloader/blob/main/LICENSE.txt) |
| 4 | +[](https://dotnet.microsoft.com/download/dotnet/8.0) |
| 5 | +[](LICENSE) |
5 | 6 |
|
6 | | -## ⚠️ **Librería en version beta** |
| 7 | +## 📋 Descripción |
7 | 8 |
|
8 | | -- Se liberó la version 5.X.X-beta, su predecesora es la 4.X.X, significa que la version rompe la compatibilidad hacia atrás. |
9 | | -- Los servicios del SAT están degradados, por lo cual hace falta testing adicional y esto será completado apenas se reestablezcan los ws del SAT. |
10 | | -- Se actualizará la documentación ASAP. |
| 9 | +Librería .NET para consultar y descargar facturas (CFDI) emitidas y recibidas a través del servicio web del SAT, incluyendo la obtención de metadata. Este servicio es parte del sistema "Consulta y recuperación de comprobantes" del SAT. |
11 | 10 |
|
| 11 | +## 🎯 Casos de Uso |
12 | 12 |
|
13 | | -## Descripción |
14 | | -Librería .NET para consultar y descargar facturas (CFDI) emitidas y recibidas a través del servicio web del SAT, incluyendo la obtención de metadata. Este servicio es parte del sistema "Consulta y recuperación de comprobantes" del SAT ([documentación oficial](https://www.sat.gob.mx/consultas/42968/consulta-y-recuperacion-de-comprobantes-(nuevo))). |
| 13 | +- **Automatización de cadena de suministros** - Descarga automática de facturas de proveedores |
| 14 | +- **Automatización de cuentas por pagar** - Gestión de facturas recibidas |
| 15 | +- **Automatización de cuentas por cobrar** - Control de facturas emitidas |
| 16 | +- **Contabilidad electrónica** - Integración con sistemas contables |
| 17 | +- **Generación de pólizas contables** - Procesamiento automático de comprobantes |
15 | 18 |
|
16 | | -### Casos de Uso |
| 19 | +## 📦 Instalación |
17 | 20 |
|
18 | | -- Automatización de cadena de suministros |
19 | | -- Automatización de cuentas por pagar |
20 | | -- Automatización de cuentas por cobrar |
21 | | -- Contabilidad electrónica |
22 | | -- Contabilidad general |
23 | | -- Generación de pólizas contables |
| 21 | +```bash |
| 22 | +# Package Manager |
| 23 | +Install-Package Fiscalapi.XmlDownloader |
24 | 24 |
|
25 | | -## Instalación |
26 | | - |
27 | | -```shell |
28 | | -NuGet\Install-Package Fiscalapi.XmlDownloader |
| 25 | +# .NET CLI |
| 26 | +dotnet add package Fiscalapi.XmlDownloader |
29 | 27 | ``` |
30 | 28 |
|
31 | | -:warning: Esta librería depende de [Fiscalapi.Credentials](https://github.com/FiscalAPI/fiscalapi-credentials-net). Se recomienda leer su documentación antes de continuar. |
32 | | - |
33 | | -## Arquitectura del Proyecto |
34 | | - |
35 | | -### Estructura de Código |
36 | | - |
| 29 | +> **📌 Dependencia requerida:** Esta librería depende de `Fiscalapi.Credentials`. Se recomienda leer su documentación antes de continuar. |
| 30 | +
|
| 31 | +## 🔄 Flujo de Operación |
| 32 | + |
| 33 | +```mermaid |
| 34 | +flowchart TD |
| 35 | + START([Inicio]) --> AUTH[🔑 Autenticarse<br/>AuthService] |
| 36 | + |
| 37 | + AUTH --> AUTH_OK{¿Éxito?} |
| 38 | + AUTH_OK -->|No| ERROR([❌ Error]) |
| 39 | + |
| 40 | + AUTH_OK -->|Sí| QUERY[📝 Crear Solicitud<br/>QueryService] |
| 41 | + |
| 42 | + QUERY --> QUERY_OK{¿Éxito?} |
| 43 | + QUERY_OK -->|No| ERROR |
| 44 | + |
| 45 | + QUERY_OK -->|Sí| VERIFY[🔍 Verificar Estado<br/>VerifyService] |
| 46 | + |
| 47 | + VERIFY --> VERIFY_STATUS{¿Solicitud<br/>Resuelta?} |
| 48 | + VERIFY_STATUS -->|En proceso| WAIT[⏳ Esperar] |
| 49 | + WAIT --> VERIFY |
| 50 | + VERIFY_STATUS -->|Error| ERROR |
| 51 | + |
| 52 | + VERIFY_STATUS -->|Sí| DOWNLOAD[⬇️ Descargar Paquetes<br/>DownloadService] |
| 53 | + |
| 54 | + DOWNLOAD --> DOWNLOAD_OK{¿Éxito?} |
| 55 | + DOWNLOAD_OK -->|No| RETRY{¿Reintentar?} |
| 56 | + RETRY -->|Sí| DOWNLOAD |
| 57 | + RETRY -->|No| ERROR |
| 58 | + |
| 59 | + DOWNLOAD_OK -->|Sí| SUCCESS([✅ Completado]) |
| 60 | + |
| 61 | + %% Estilos Fiscalapi |
| 62 | + classDef service fill:#ffffff,stroke:#9c27b0,stroke-width:2px,color:#9c27b0 |
| 63 | + classDef decision fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px,color:#9c27b0 |
| 64 | + classDef endpoint fill:#ffffff,stroke:#9c27b0,stroke-width:3px,color:#9c27b0 |
| 65 | + classDef error fill:#ffebee,stroke:#d32f2f,stroke-width:2px,color:#d32f2f |
| 66 | + |
| 67 | + class AUTH,QUERY,VERIFY,DOWNLOAD,WAIT service |
| 68 | + class AUTH_OK,QUERY_OK,VERIFY_STATUS,DOWNLOAD_OK,RETRY decision |
| 69 | + class START,SUCCESS endpoint |
| 70 | + class ERROR error |
37 | 71 | ``` |
38 | | -src/ |
39 | | -├── XmlService/ # Clase principal que consume los servicios |
40 | | -├── Services/ # Implementación de servicios |
41 | | -│ ├── Authenticate/ |
42 | | -│ ├── Query/ |
43 | | -│ ├── Verify/ |
44 | | -│ └── Download/ |
45 | | -├── Common/ # Objetos compartidos |
46 | | -├── Models/ # Objetos DTO |
47 | | -├── Packaging/ # Manejo de paquetes del SAT |
48 | | -├── Builder/ # Generación de mensajes SOAP |
49 | | -└── SoapClient/ # Cliente HTTP para el Webservice |
| 72 | + |
| 73 | +## 📊 Reglas de Negocio y Validaciones |
| 74 | + |
| 75 | +### Estados Permitidos por Tipo de Consulta |
| 76 | + |
| 77 | +| Tipo Descarga | Tipo Consulta | Estados Permitidos | |
| 78 | +|---------------|---------------|-------------------| |
| 79 | +| **Emitidos** | CFDI | Vigente, Cancelado, Todos | |
| 80 | +| **Emitidos** | Metadata | Vigente, Cancelado, Todos | |
| 81 | +| **Recibidos** | CFDI | Solo Vigente | |
| 82 | +| **Recibidos** | Metadata | Vigente, Cancelado, Todos | |
| 83 | + |
| 84 | +### Validaciones Principales |
| 85 | + |
| 86 | +- **Fechas**: La fecha inicial debe ser menor a la fecha final |
| 87 | +- **UUID**: Debe tener exactamente 36 caracteres (cuando se especifica) |
| 88 | +- **Límites de registros**: Hasta 200,000 por petición (1,000,000 en metadata) |
| 89 | +- **Tipos de consulta**: Solo valores válidos definidos en `SatQueryTypes` |
| 90 | +- **Estados de factura**: Solo valores válidos según el tipo de descarga |
| 91 | + |
| 92 | +## 🚀 Ejemplo de Uso |
| 93 | + |
| 94 | +```csharp |
| 95 | +using Fiscalapi.XmlDownloader; |
| 96 | +using Fiscalapi.XmlDownloader.Models; |
| 97 | + |
| 98 | +internal class Program |
| 99 | +{ |
| 100 | + private static async Task Main(string[] args) |
| 101 | + { |
| 102 | + // Configuración de credenciales FIEL |
| 103 | + var certBase64 = "certBase64..."; |
| 104 | + var keyBase64 = "keyBase64..."; |
| 105 | + var password = "keyPassPhrase..."; |
| 106 | + |
| 107 | + var service = new XmlDownloaderService(); |
| 108 | + |
| 109 | + try |
| 110 | + { |
| 111 | + // 1. Autenticación con FIEL |
| 112 | + Console.WriteLine("Autenticando..."); |
| 113 | + await service.AuthenticateAsync(certBase64, keyBase64, password); |
| 114 | + |
| 115 | + // 2. Crear solicitud de descarga |
| 116 | + Console.WriteLine("Creando solicitud..."); |
| 117 | + var queryParams = new QueryParameters |
| 118 | + { |
| 119 | + StartDate = new DateTime(2024, 1, 1).ToStartOfDay(), |
| 120 | + EndDate = new DateTime(2024, 1, 30).ToEndOfDay(), |
| 121 | + RecipientTin = "RFC123456789", // RFC del receptor |
| 122 | + RequestType = QueryType.CFDI, |
| 123 | + InvoiceStatus = InvoiceStatus.Vigente |
| 124 | + }; |
| 125 | + |
| 126 | + var queryResponse = await service.CreateRequestAsync(queryParams); |
| 127 | + |
| 128 | + if (!queryResponse.Succeeded) |
| 129 | + { |
| 130 | + Console.WriteLine($"Error creando solicitud: {queryResponse.SatMessage}"); |
| 131 | + return; |
| 132 | + } |
| 133 | + |
| 134 | + Console.WriteLine($"Solicitud creada exitosamente: {queryResponse.RequestId}"); |
| 135 | + |
| 136 | + // 3. Verificar estado de la solicitud |
| 137 | + Console.WriteLine("Verificando estado de la solicitud..."); |
| 138 | + var verifyResponse = await service.VerifyAsync(queryResponse.RequestId); |
| 139 | + |
| 140 | + if (!verifyResponse.Succeeded) |
| 141 | + { |
| 142 | + Console.WriteLine($"Error verificando solicitud: {verifyResponse.SatMessage}"); |
| 143 | + return; |
| 144 | + } |
| 145 | + |
| 146 | + Console.WriteLine($"Estado SAT: {verifyResponse.SatStatus}"); |
| 147 | + Console.WriteLine($"Estado Solicitud: {verifyResponse.RequestStatus}"); |
| 148 | + Console.WriteLine($"Facturas encontradas: {verifyResponse.InvoiceCount}"); |
| 149 | + |
| 150 | + // 4. Descargar paquetes si están listos |
| 151 | + if (verifyResponse.IsReadyToDownload) |
| 152 | + { |
| 153 | + Console.WriteLine($"Descargando {verifyResponse.PackageIds.Count} paquete(s)..."); |
| 154 | + |
| 155 | + foreach (var packageId in verifyResponse.PackageIds) |
| 156 | + { |
| 157 | + Console.WriteLine($"Descargando paquete: {packageId}"); |
| 158 | + var downloadResponse = await service.DownloadAsync(packageId); |
| 159 | + |
| 160 | + if (downloadResponse.Succeeded) |
| 161 | + { |
| 162 | + // Guardar paquete en disco |
| 163 | + var packagePath = Path.Combine("C:\\FiscalAPI\\packages", $"{packageId}.zip"); |
| 164 | + await service.WritePackageAsync(packagePath, downloadResponse.PackageBytes); |
| 165 | + Console.WriteLine($"Paquete guardado en: {packagePath}"); |
| 166 | + |
| 167 | + // Procesar comprobantes del paquete |
| 168 | + Console.WriteLine("Procesando comprobantes..."); |
| 169 | + await foreach (var comprobante in service.GetComprobantesAsync(downloadResponse.PackageBytes)) |
| 170 | + { |
| 171 | + Console.WriteLine($"CFDI procesado - Serie: {comprobante.Serie}, Folio: {comprobante.Folio}"); |
| 172 | + } |
| 173 | + } |
| 174 | + else |
| 175 | + { |
| 176 | + Console.WriteLine($"Error descargando paquete {packageId}: {downloadResponse.SatMessage}"); |
| 177 | + } |
| 178 | + } |
| 179 | + } |
| 180 | + else |
| 181 | + { |
| 182 | + Console.WriteLine($"La solicitud no está lista para descarga. Estado: {verifyResponse.RequestStatus}"); |
| 183 | + } |
| 184 | + |
| 185 | + Console.WriteLine("Proceso completado exitosamente"); |
| 186 | + } |
| 187 | + catch (Exception ex) |
| 188 | + { |
| 189 | + Console.WriteLine($"Error general: {ex.Message}"); |
| 190 | + } |
| 191 | + } |
| 192 | +} |
50 | 193 | ``` |
51 | 194 |
|
52 | | -### Servicios Principales |
| 195 | +## 🔧 Servicios Principales |
53 | 196 |
|
54 | | -Cada servicio (`Authenticate`, `Query`, `Verify`, `Download`) contiene: |
55 | | -- `Result`: Resultado de la operación |
56 | | -- `Parameters`: Parámetros de operación |
| 197 | +💡 La librería utiliza **`IXmlDownloaderService`**, el servicio principal que coordina y orquesta todo el flujo de descarga masiva. Actúa como el único punto de entrada para el desarrollador, centralizando y gestionando todo el proceso desde una sola interfaz. |
57 | 198 |
|
58 | | -## Funcionamiento del Servicio Web |
59 | 199 |
|
60 | | -### Flujo de Operación |
| 200 | +### Servicios Internos |
61 | 201 |
|
62 | | -1. **Autenticación**: Utilizando FIEL (manejo automático del token) |
63 | | -2. **Solicitud**: Especificación de parámetros (fechas, tipo de solicitud) |
64 | | -3. **Verificación**: Consulta de disponibilidad |
65 | | -4. **Descarga**: Obtención de paquetes |
| 202 | +**`AuthService`** |
| 203 | +Maneja la autenticación utilizando certificados FIEL (Firma Electrónica Avanzada) y gestión automática de tokens. |
66 | 204 |
|
67 | | - |
| 205 | +**`QueryService`** |
| 206 | +Crea solicitudes de descarga especificando parámetros como fechas, tipo de consulta, filtros y validaciones de reglas de negocio. |
68 | 207 |
|
69 | | -### Límites y Consideraciones |
| 208 | +**`VerifyService`** |
| 209 | +Verifica el estado de las solicitudes creadas y obtiene los identificadores de paquetes disponibles para descarga. |
70 | 210 |
|
71 | | -- Hasta 200,000 registros por petición (1,000,000 en metadata) |
72 | | -- Sin límite en número de solicitudes |
73 | | -- Tiempo de respuesta variable (minutos a horas) |
| 211 | +**`DownloadService`** |
| 212 | +Descarga los paquetes ZIP que contienen los comprobantes fiscales y metadata desde los servidores del SAT. |
74 | 213 |
|
75 | | -## Documentación Oficial |
| 214 | +**`FileStorageService`** |
| 215 | +Maneja el almacenamiento y lectura de paquetes descargados en el sistema de archivos local. |
76 | 216 |
|
77 | | -- [Portal SAT - Consulta y Recuperación](https://www.sat.gob.mx/consultas/42968/consulta-y-recuperacion-de-comprobantes-(nuevo)) |
78 | | -- [Solicitud de Descargas](https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1579314716402&ssbinary=true) |
79 | | -- [Verificación de Solicitudes](https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1579314716409&ssbinary=true) |
80 | | -- [Descarga de Solicitudes](https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1579314716395&ssbinary=true) |
| 217 | +## ⚙️ Límites y Consideraciones |
81 | 218 |
|
82 | | -## Ejemplos de Uso |
| 219 | +- **Límite de registros**: Hasta 200,000 registros por petición (1,000,000 en metadata) |
| 220 | +- **Número de solicitudes**: Sin límite |
| 221 | +- **Tiempo de respuesta**: Variable, desde minutos hasta horas |
| 222 | +- **Formato de descarga**: Paquetes ZIP con archivos XML |
| 223 | +- **Tipos soportados**: CFDI emitidos, recibidos y metadata |
83 | 224 |
|
84 | | -Consulte [la rama master](https://github.com/FiscalAPI/xml-downloader/tree/master) para ejemplos detallados de uso. |
| 225 | +## 📚 Documentación Oficial del SAT |
85 | 226 |
|
86 | | -## Compatibilidad |
| 227 | +- Consulta el folder `satdocs` |
87 | 228 |
|
88 | | -- Compatible con .NET 8 |
89 | | -- Soporta aplicaciones Windows Forms, Console y Web |
90 | | -- Seguimos Versionado Semántico 2.0.0 |
| 229 | +## 🔧 Compatibilidad |
91 | 230 |
|
| 231 | +- **.NET 8** - Framework principal |
| 232 | +- **Windows Forms** - Aplicaciones de escritorio |
| 233 | +- **Console Applications** - Aplicaciones de línea de comandos |
| 234 | +- **Web Applications** - Aplicaciones web y APIs |
| 235 | +- **Versionado Semántico 2.0.0** - Control de versiones |
92 | 236 |
|
93 | 237 | ## 🤝 Contribuir |
94 | 238 |
|
95 | | -1. Haz un fork del repositorio. |
96 | | -2. Crea una rama para tu feature: `git checkout -b feature/AmazingFeature`. |
97 | | -3. Realiza commits de tus cambios: `git commit -m 'Add some AmazingFeature'`. |
98 | | -4. Sube tu rama: `git push origin feature/AmazingFeature`. |
99 | | -5. Abre un Pull Request en GitHub. |
100 | | - |
| 239 | +1. Haz un fork del repositorio |
| 240 | +2. Crea una rama para tu feature: `git checkout -b feature/AmazingFeature` |
| 241 | +3. Realiza commits de tus cambios: `git commit -m 'Add some AmazingFeature'` |
| 242 | +4. Sube tu rama: `git push origin feature/AmazingFeature` |
| 243 | +5. Abre un Pull Request en GitHub |
101 | 244 |
|
102 | 245 | ## 🐛 Reportar Problemas |
103 | 246 |
|
104 | | -1. Asegúrate de usar la última versión del SDK. |
105 | | -2. Verifica si el problema ya fue reportado. |
106 | | -3. Proporciona un ejemplo mínimo reproducible. |
107 | | -4. Incluye los mensajes de error completos. |
| 247 | +Antes de reportar un problema: |
108 | 248 |
|
| 249 | +1. **Verifica la versión**: Asegúrate de usar la última versión del SDK |
| 250 | +2. **Busca duplicados**: Verifica si el problema ya fue reportado |
| 251 | +3. **Ejemplo reproducible**: Proporciona un ejemplo mínimo que reproduzca el error |
| 252 | +4. **Logs completos**: Incluye los mensajes de error completos y stack traces |
109 | 253 |
|
110 | | -## 📄 Licencia |
| 254 | +## 🛣️ Roadmap |
111 | 255 |
|
112 | | -Este proyecto está licenciado bajo la Licencia **MPL**. Consulta el archivo [LICENSE](LICENSE.txt) para más detalles. |
| 256 | +### ✅ Funcionalidades Completadas |
| 257 | +- [x] Descarga de CFDI emitidos y recibidos |
| 258 | +- [x] Descarga de metadata de CFDI |
| 259 | +- [x] Validaciones de reglas de negocio del SAT |
| 260 | +- [x] Soporte para múltiples RFC |
| 261 | +- [x] Orquestador principal (`IXmlDownloaderService`) |
| 262 | +- [x] Almacenamiento y lectura de paquetes descargados |
| 263 | +- [x] Deserializado XML a objetos Comprobante CFDI. |
| 264 | +- [x] Soporte para inyección de dependencias (.NET) |
113 | 265 |
|
114 | | -## Roadmap |
| 266 | +### 🚧 Próximas Funcionalidades |
| 267 | +- [ ] Descarga de metadata de CFDI |
115 | 268 |
|
116 | | -- [x] Descarga de CFDI emitidos y recibidos |
117 | | -- [x] Descarga de metadata de CFDI |
118 | | -- [ ] Documentación exhaustiva |
| 269 | +## 🔗 Enlaces Útiles |
| 270 | + |
| 271 | +- [SDK.NET](https://github.com/FiscalAPI/fiscalapi-net) |
| 272 | +- [Documentación Oficial](https://docs.fiscalapi.com) |
| 273 | +- [Portal de FiscalAPI](https://fiscalapi.com) |
| 274 | +- [Ejemplos Facturacion WinForms](https://github.com/FiscalAPI/fiscalapi-samples-net-winforms) |
| 275 | +- [Ejemplos Facturacion ASP.NET](https://github.com/FiscalAPI/fiscalapi-samples-net-aspnet) |
| 276 | + |
| 277 | +## 📄 Licencia |
119 | 278 |
|
120 | | -## Licencia |
| 279 | +Copyright © **FISCAL API S DE R.L DE C.V.** |
121 | 280 |
|
122 | | -Copyright © FISCAL API S DE R.L DE C.V. Este proyecto está licenciado bajo la [Licencia MIT](LICENSE). |
| 281 | +Este proyecto está licenciado bajo la **Licencia MPL** (Mozilla Public License). Consulta el archivo [LICENSE](LICENSE) para más detalles. |
0 commit comments