Skip to content

Commit 5ae41a2

Browse files
authored
Merge pull request #5 from FiscalAPI/feat/descarga-retenciones-info-pagos
feat/descarga retenciones info pagos added
2 parents 5dc9ec2 + feeed9b commit 5ae41a2

18 files changed

+395
-101
lines changed

Auth/AuthService.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ public AuthService(ILogger<AuthService> logger)
5151
/// Authenticates with SAT using the provided credential and returns the authentication token
5252
/// </summary>
5353
public async Task<AuthResponse> AuthenticateAsync(ICredential credential,
54-
ILogger logger, CancellationToken cancellationToken = default)
54+
ServiceEndpoints endpoints, ILogger logger, CancellationToken cancellationToken = default)
5555
{
56-
logger.LogInformation("Starting SAT authentication process for RFC: {Rfc}", credential.Certificate.Rfc);
56+
logger.LogInformation("Starting SAT authentication process for RFC: {Rfc}, ServiceType: {ServiceType}",
57+
credential.Certificate.Rfc, endpoints.ServiceType);
5758

5859
try
5960
{
@@ -70,10 +71,10 @@ public async Task<AuthResponse> AuthenticateAsync(ICredential credential,
7071
signature);
7172

7273
// Send request
73-
logger.LogInformation("Sending authentication request to SAT. URL: {Url}", SatUrl.AuthUrl);
74+
logger.LogInformation("Sending authentication request to SAT. URL: {Url}", endpoints.AuthUrl);
7475
var satResponse = await SendRequestAsync(
75-
url: SatUrl.AuthUrl,
76-
action: SatUrl.AuthAction,
76+
url: endpoints.AuthUrl,
77+
action: ServiceEndpoints.AuthAction,
7778
payload: authXml,
7879
cancellationToken: cancellationToken);
7980

Auth/IAuthService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using Fiscalapi.Credentials.Core;
1818
using Fiscalapi.XmlDownloader.Auth.Models;
19+
using Fiscalapi.XmlDownloader.Common.Http;
1920
using Microsoft.Extensions.Logging;
2021

2122
namespace Fiscalapi.XmlDownloader.Auth;
@@ -29,8 +30,9 @@ public interface IAuthService
2930
/// Authenticates with SAT using the provided credential and returns the authentication token.
3031
/// </summary>
3132
/// <param name="credential"></param>
33+
/// <param name="endpoints">Service endpoints to use for authentication</param>
3234
/// <param name="cancellationToken">CancellationToken</param>
3335
/// <param name="logger">Logger</param>
3436
/// <returns></returns>
35-
Task<AuthResponse> AuthenticateAsync(ICredential credential, ILogger logger, CancellationToken cancellationToken = default);
37+
Task<AuthResponse> AuthenticateAsync(ICredential credential, ServiceEndpoints endpoints, ILogger logger, CancellationToken cancellationToken = default);
3638
}

Common/Enums/ServiceType.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* ============================================================================
3+
* Mozilla Public License 2.0 (MPL-2.0)
4+
* Autor: FISCAL API S. DE R.L. DE C.V. - https://fiscalapi.com
5+
* ============================================================================
6+
*
7+
* Este código está sujeto a los términos de la Mozilla Public License v2.0.
8+
* Licencia completa: https://mozilla.org/MPL/2.0
9+
*
10+
* AVISO: Este software se proporciona "tal como está" sin garantías de ningún
11+
* tipo. Al usar, modificar o distribuir este código debe mantener esta
12+
* atribución y las referencias al autor.
13+
*
14+
* ============================================================================
15+
*/
16+
17+
namespace Fiscalapi.XmlDownloader.Common.Enums;
18+
19+
/// <summary>
20+
/// Tipo de servicio de descarga masiva del SAT.
21+
/// </summary>
22+
public enum ServiceType
23+
{
24+
/// <summary>
25+
/// Servicio para descarga de CFDI regulares y metadatos
26+
/// </summary>
27+
Cfdi,
28+
29+
/// <summary>
30+
/// Servicio para descarga de CFDI de retenciones e información de pagos
31+
/// </summary>
32+
Retenciones
33+
}
34+

Common/Http/SatUrl.cs

Lines changed: 0 additions & 68 deletions
This file was deleted.

Common/Http/ServiceEndpoints.cs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* ============================================================================
3+
* Mozilla Public License 2.0 (MPL-2.0)
4+
* Autor: FISCAL API S. DE R.L. DE C.V. - https://fiscalapi.com
5+
* ============================================================================
6+
*
7+
* Este código está sujeto a los términos de la Mozilla Public License v2.0.
8+
* Licencia completa: https://mozilla.org/MPL/2.0
9+
*
10+
* AVISO: Este software se proporciona "tal como está" sin garantías de ningún
11+
* tipo. Al usar, modificar o distribuir este código debe mantener esta
12+
* atribución y las referencias al autor.
13+
*
14+
* ============================================================================
15+
*/
16+
17+
using Fiscalapi.XmlDownloader.Common.Enums;
18+
19+
namespace Fiscalapi.XmlDownloader.Common.Http;
20+
21+
/// <summary>
22+
/// Clase inmutable que encapsula todos los endpoints del servicio de descarga masiva del SAT.
23+
/// Use ServiceEndpoints.Cfdi() para "CFDI regulares"
24+
/// Use ServiceEndpoints.Retenciones() para "CFDI de retenciones e información de pagos"
25+
/// </summary>
26+
public sealed class ServiceEndpoints
27+
{
28+
/// <summary>
29+
/// URL del servicio de autenticación
30+
/// </summary>
31+
public string AuthUrl { get; }
32+
33+
/// <summary>
34+
/// URL del servicio de solicitud de descarga
35+
/// </summary>
36+
public string QueryUrl { get; }
37+
38+
/// <summary>
39+
/// URL del servicio de verificación de solicitud
40+
/// </summary>
41+
public string VerifyUrl { get; }
42+
43+
/// <summary>
44+
/// URL del servicio de descarga de paquetes
45+
/// </summary>
46+
public string DownloadUrl { get; }
47+
48+
/// <summary>
49+
/// Tipo de servicio (CFDI o Retenciones)
50+
/// </summary>
51+
public ServiceType ServiceType { get; }
52+
53+
// SOAP Actions (constantes que no cambian entre CFDI y Retenciones)
54+
public const string AuthAction = "http://DescargaMasivaTerceros.gob.mx/IAutenticacion/Autentica";
55+
public const string RequestIssuedAction = "http://DescargaMasivaTerceros.sat.gob.mx/ISolicitaDescargaService/SolicitaDescargaEmitidos";
56+
public const string RequestReceivedAction = "http://DescargaMasivaTerceros.sat.gob.mx/ISolicitaDescargaService/SolicitaDescargaRecibidos";
57+
public const string RequestUuidAction = "http://DescargaMasivaTerceros.sat.gob.mx/ISolicitaDescargaService/SolicitaDescargaFolio";
58+
public const string VerifyAction = "http://DescargaMasivaTerceros.sat.gob.mx/IVerificaSolicitudDescargaService/VerificaSolicitudDescarga";
59+
public const string DownloadAction = "http://DescargaMasivaTerceros.sat.gob.mx/IDescargaMasivaTercerosService/Descargar";
60+
61+
/// <summary>
62+
/// Constructor privado para crear instancias inmutables
63+
/// </summary>
64+
private ServiceEndpoints(string authUrl, string queryUrl, string verifyUrl, string downloadUrl, ServiceType serviceType)
65+
{
66+
AuthUrl = authUrl ?? throw new ArgumentNullException(nameof(authUrl));
67+
QueryUrl = queryUrl ?? throw new ArgumentNullException(nameof(queryUrl));
68+
VerifyUrl = verifyUrl ?? throw new ArgumentNullException(nameof(verifyUrl));
69+
DownloadUrl = downloadUrl ?? throw new ArgumentNullException(nameof(downloadUrl));
70+
ServiceType = serviceType;
71+
}
72+
73+
/// <summary>
74+
/// Crea una instancia con los endpoints para "CFDI regulares"
75+
/// </summary>
76+
public static ServiceEndpoints Cfdi()
77+
{
78+
return new ServiceEndpoints(
79+
authUrl: "https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc",
80+
queryUrl: "https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/SolicitaDescargaService.svc",
81+
verifyUrl: "https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/VerificaSolicitudDescargaService.svc",
82+
downloadUrl: "https://cfdidescargamasiva.clouda.sat.gob.mx/DescargaMasivaService.svc",
83+
serviceType: ServiceType.Cfdi
84+
);
85+
}
86+
87+
/// <summary>
88+
/// Crea una instancia con los endpoints para "CFDI de retenciones e información de pagos"
89+
/// </summary>
90+
public static ServiceEndpoints Retenciones()
91+
{
92+
return new ServiceEndpoints(
93+
authUrl: "https://retendescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc",
94+
queryUrl: "https://retendescargamasivasolicitud.clouda.sat.gob.mx/SolicitaDescargaService.svc",
95+
verifyUrl: "https://retendescargamasivasolicitud.clouda.sat.gob.mx/VerificaSolicitudDescargaService.svc",
96+
downloadUrl: "https://retendescargamasiva.clouda.sat.gob.mx/DescargaMasivaService.svc",
97+
serviceType: ServiceType.Retenciones
98+
);
99+
}
100+
}
101+

Download/DownloadService.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,20 @@ public DownloadService(ILogger<DownloadService> logger)
5454
/// <param name="credential">Fiel</param>
5555
/// <param name="authToken">Authentication token</param>
5656
/// <param name="packageId">PackageID</param>
57+
/// <param name="endpoints">Service endpoints to use for download</param>
5758
/// <param name="cancellationToken">CancellationToken</param>
5859
/// <param name="logger">Logger</param>
5960
/// <returns>DownloadResponse</returns>
6061
public async Task<DownloadResponse> DownloadAsync(ICredential credential, Token authToken, string packageId,
61-
ILogger logger, CancellationToken cancellationToken = default)
62+
ServiceEndpoints endpoints, ILogger logger, CancellationToken cancellationToken = default)
6263
{
6364
var toDigest = CreateDigest(packageId, credential.Certificate.Rfc);
6465
var signature = CreateSignature(credential, toDigest);
6566
var requestXml = BuildEnvelope(packageId, credential.Certificate.Rfc, signature);
6667

6768
var satResponse = await SendRequestAsync(
68-
url: SatUrl.DownloadUrl,
69-
action: SatUrl.DownloadAction,
69+
url: endpoints.DownloadUrl,
70+
action: ServiceEndpoints.DownloadAction,
7071
payload: requestXml,
7172
token: authToken.Value,
7273
cancellationToken: cancellationToken);

Download/IDownloadService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using Fiscalapi.Credentials.Core;
1818
using Fiscalapi.XmlDownloader.Auth.Models;
19+
using Fiscalapi.XmlDownloader.Common.Http;
1920
using Fiscalapi.XmlDownloader.Download.Models;
2021
using Microsoft.Extensions.Logging;
2122

@@ -32,9 +33,10 @@ public interface IDownloadService
3233
/// <param name="credential">Fiel</param>
3334
/// <param name="authToken">Authentication token</param>
3435
/// <param name="packageId">PackageID</param>
36+
/// <param name="endpoints">Service endpoints to use for download</param>
3537
/// <param name="cancellationToken">CancellationToken</param>
3638
/// <param name="logger">Logger</param>
3739
/// <returns>DownloadResponse</returns>
3840
Task<DownloadResponse> DownloadAsync(ICredential credential, Token authToken, string packageId,
39-
ILogger logger, CancellationToken cancellationToken = default);
41+
ServiceEndpoints endpoints, ILogger logger, CancellationToken cancellationToken = default);
4042
}

DownloaderExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ namespace Fiscalapi.XmlDownloader;
3131

3232
public static class DownloaderExtensions
3333
{
34-
//private const string SatFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
3534
private const string SatFormat = "yyyy-MM-ddTHH:mm:ss.000Z";
3635

3736
/// <summary>

IXmlDownloaderService.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
using Fiscalapi.Credentials.Core;
1818
using Fiscalapi.XmlDownloader.Auth.Models;
19+
using Fiscalapi.XmlDownloader.Common.Enums;
20+
using Fiscalapi.XmlDownloader.Common.Http;
1921
using Fiscalapi.XmlDownloader.Common.Models;
2022
using Fiscalapi.XmlDownloader.Download.Models;
2123
using Fiscalapi.XmlDownloader.Query.Models;
@@ -40,27 +42,53 @@ public interface IXmlDownloaderService
4042
/// </summary>
4143
public Token? Token { get; set; }
4244

45+
/// <summary>
46+
/// Service endpoints currently configured for the service (CFDI or Retenciones).
47+
/// </summary>
48+
public ServiceEndpoints ServiceEndpoints { get; }
49+
50+
/// <summary>
51+
/// Sets the service type (CFDI or Retenciones) and switches endpoints accordingly.
52+
/// If the current token is from a different service type, it will be invalidated to force re-authentication.
53+
/// If Credential is set, re-authentication will be performed automatically.
54+
/// </summary>
55+
/// <param name="serviceType">The service type to switch to</param>
56+
/// <param name="forceReauthenticate">If true, invalidates the current token even if it matches the service type</param>
57+
/// <param name="cancellationToken">Cancellation token</param>
58+
/// <returns>Task representing the asynchronous operation</returns>
59+
Task SetServiceType(ServiceType serviceType, bool forceReauthenticate = false, CancellationToken cancellationToken = default);
60+
4361

4462
/// <summary>
4563
/// Authenticates the user with SAT and retrieves an authentication token using the provided certificate and key in Base64 format.
64+
/// </summary>
4665
/// <param name="base64Cer">Base64 Fiel Certificate</param>
4766
/// <param name="base64Key">Base64 Fiel PrivateKey</param>
4867
/// <param name="password">Plain Fiel PrivateKey's Password Phrase</param>
49-
/// <param name="cancellationToken"></param>
68+
/// <param name="endpoints">Service endpoints to use for authentication. Defaults to CFDI endpoints if null.</param>
69+
/// <param name="cancellationToken">Cancellation token</param>
5070
/// <returns>AuthResponse</returns>
51-
/// </summary>
5271
Task<AuthResponse> AuthenticateAsync(string base64Cer, string base64Key, string password,
53-
CancellationToken cancellationToken = default);
72+
ServiceEndpoints? endpoints = null, CancellationToken cancellationToken = default);
73+
/// <summary>
74+
/// Authenticates the user with SAT and retrieves an authentication token given the Fiel credential.
75+
/// </summary>
76+
/// <param name="credential"></param>
77+
/// <param name="endpoints">Service endpoints to use for authentication. Defaults to CFDI endpoints if null.</param>
78+
/// <param name="cancellationToken"></param>
79+
/// <returns>AuthResponse</returns>
80+
Task<AuthResponse> AuthenticateAsync(ICredential credential, ServiceEndpoints? endpoints = null, CancellationToken cancellationToken = default);
5481

5582

5683
/// <summary>
57-
/// Authenticates the user with SAT and retrieves an authentication token given the Fiel credential.
84+
/// Authenticates the user to CFDI endpoints with SAT and retrieves an authentication token given the Fiel credential.
5885
/// </summary>
5986
/// <param name="credential"></param>
6087
/// <param name="cancellationToken"></param>
6188
/// <returns>AuthResponse</returns>
6289
Task<AuthResponse> AuthenticateAsync(ICredential credential, CancellationToken cancellationToken = default);
6390

91+
6492
/// <summary>
6593
/// Creates a 'download request' to the SAT with the specified query parameters.
6694
/// </summary>

Query/IQueryService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using Fiscalapi.Credentials.Core;
1818
using Fiscalapi.XmlDownloader.Auth.Models;
19+
using Fiscalapi.XmlDownloader.Common.Http;
1920
using Fiscalapi.XmlDownloader.Query.Models;
2021
using Microsoft.Extensions.Logging;
2122

@@ -32,9 +33,10 @@ public interface IQueryService
3233
/// <param name="credential">Fiel</param>
3334
/// <param name="authToken">Authentication token</param>
3435
/// <param name="parameters">Request parameters</param>
36+
/// <param name="endpoints">Service endpoints to use for the query</param>
3537
/// <param name="cancellationToken">CancellationToken</param>
3638
/// <param name="logger">Logger</param>
3739
/// <returns>QueryResponse</returns>
3840
Task<QueryResponse> CreateAsync(ICredential credential, Token authToken,
39-
QueryParameters parameters, ILogger logger, CancellationToken cancellationToken = default);
41+
QueryParameters parameters, ServiceEndpoints endpoints, ILogger logger, CancellationToken cancellationToken = default);
4042
}

0 commit comments

Comments
 (0)