Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [7.1.0] - 2026-10-07

### Added

- Add `NominaCatalog.SearchDeductions` and `NominaCatalog.SearchPerceptions` to search the SAT payroll deduction and perception catalogs.

## [7.0.0] - 2026-09-09
### Breaking
- `SearchResult.Page`, `TotalPages`, and `TotalResults` are now nullable (`int?`): cursor responses after the first page omit them and absence must not deserialize as `0`.
Expand Down
2 changes: 2 additions & 0 deletions FacturapiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public sealed class FacturapiClient : IFacturapiClient
public IRetentionWrapper Retention { get; private set; }
public ICatalogWrapper Catalog { get; private set; }
public ICartaporteCatalogWrapper CartaporteCatalog { get; private set; }
public INominaCatalogWrapper NominaCatalog { get; private set; }
public IToolWrapper Tool { get; private set; }
public IWebhookWrapper Webhook { get; private set; }
private readonly HttpClient httpClient;
Expand All @@ -41,6 +42,7 @@ private FacturapiClient(string apiKey, string apiVersion, HttpClient httpClient,
this.Retention = new RetentionWrapper(apiKey, apiVersion, this.httpClient);
this.Catalog = new CatalogWrapper(apiKey, apiVersion, this.httpClient);
this.CartaporteCatalog = new CartaporteCatalogWrapper(apiKey, apiVersion, this.httpClient);
this.NominaCatalog = new NominaCatalogWrapper(apiKey, apiVersion, this.httpClient);
this.Tool = new ToolWrapper(apiKey, apiVersion, this.httpClient);
this.Webhook = new WebhookWrapper(apiKey, apiVersion, this.httpClient);
}
Expand Down
1 change: 1 addition & 0 deletions IFacturapiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public interface IFacturapiClient : IDisposable
IRetentionWrapper Retention { get; }
ICatalogWrapper Catalog { get; }
ICartaporteCatalogWrapper CartaporteCatalog { get; }
INominaCatalogWrapper NominaCatalog { get; }
IToolWrapper Tool { get; }
IWebhookWrapper Webhook { get; }
}
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ var facturapi = new FacturapiClient("TU_API_KEY");
var invoice = await facturapi.Invoice.CreateAsync(...);
```

### Catálogos de nómina

```csharp
var deductions = await facturapi.NominaCatalog.SearchDeductions(new Dictionary<string, object> { ["q"] = "001" });
var perceptions = await facturapi.NominaCatalog.SearchPerceptions(new Dictionary<string, object> { ["q"] = "001" });
```

### Escenario avanzado: usar tu propio `HttpClient`

Para la mayoría de usuarios, usa el constructor normal de `FacturapiClient`.
Expand Down
17 changes: 17 additions & 0 deletions Router/NominaCatalogRouter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;

namespace Facturapi
{
internal static partial class Router
{
public static string SearchNominaDeductions(Dictionary<string, object> query = null)
{
return UriWithQuery("catalogs/deductions", query);
}

public static string SearchNominaPerceptions(Dictionary<string, object> query = null)
{
return UriWithQuery("catalogs/perceptions", query);
}
}
}
12 changes: 12 additions & 0 deletions Wrappers/INominaCatalogWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Facturapi.Wrappers
{
public interface INominaCatalogWrapper
{
Task<SearchResult<CatalogItem>> SearchDeductions(Dictionary<string, object> query = null, CancellationToken cancellationToken = default);
Task<SearchResult<CatalogItem>> SearchPerceptions(Dictionary<string, object> query = null, CancellationToken cancellationToken = default);
}
}
35 changes: 35 additions & 0 deletions Wrappers/NominaCatalogWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Facturapi.Wrappers
{
public class NominaCatalogWrapper : BaseWrapper, INominaCatalogWrapper
{
internal NominaCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient)
{
}

public Task<SearchResult<CatalogItem>> SearchDeductions(Dictionary<string, object> query = null, CancellationToken cancellationToken = default)
{
return SearchCatalogAsync(Router.SearchNominaDeductions(query), cancellationToken);
}

public Task<SearchResult<CatalogItem>> SearchPerceptions(Dictionary<string, object> query = null, CancellationToken cancellationToken = default)
{
return SearchCatalogAsync(Router.SearchNominaPerceptions(query), cancellationToken);
}

private async Task<SearchResult<CatalogItem>> SearchCatalogAsync(string url, CancellationToken cancellationToken)
{
using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false))
{
await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false);
var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<SearchResult<CatalogItem>>(resultString, jsonSettings);
}
}
}
}
2 changes: 1 addition & 1 deletion facturapi-net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Summary>SDK oficial de Facturapi para .NET para facturación electrónica en México (CFDI), envío de documentos, búsqueda y trazabilidad.</Summary>
<PackageTags>factura factura-electronica facturacion cfdi cfdi40 sat invoice invoicing facturapi mexico</PackageTags>
<Title>Facturapi</Title>
<Version>7.0.0</Version>
<Version>7.1.0</Version>
<PackageVersion>$(Version)</PackageVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
Expand Down
Loading