C# / .NET SDK
Disponible — paquete
FactuLinken NuGet. Tipos nativos, async/await,IAsyncEnumerablepara auto-paginación. Compatible con .NET Standard 2.0 y .NET 8+.
El SDK oficial de FactuLink para .NET. Funciona en .NET Framework 4.6.1+, Mono, Xamarin, Unity y .NET 8+.
Instalación
dotnet add package FactuLinkMulti-target: netstandard2.0 y net8.0.
Quickstart
using FactuLink;
using FactuLink.Models;
using var fc = new FactuLinkClient(new FactuLinkOptions
{
ApiKey = Environment.GetEnvironmentVariable("FC_API_KEY"), // sk_test_... o sk_live_...
});
var cfdi = await fc.Cfdis.CreateAsync(new CreateCfdiParams
{
Tipo = "I",
Receptor = new CfdiReceptor
{
Rfc = "XAXX010101000",
Nombre = "Cliente de Prueba",
RegimenFiscal = "601",
DomicilioFiscal = "06600",
UsoCfdi = "G03",
},
Conceptos =
{
new CfdiConcepto
{
ClaveProdServ = "43211503",
Descripcion = "Laptop",
Cantidad = 1,
ClaveUnidad = "H87",
ValorUnitario = 15000m,
},
},
});
Console.WriteLine(cfdi.Uuid);Configuración
var fc = new FactuLinkClient(new FactuLinkOptions
{
ApiKey = "sk_live_...", // Requerido
BaseUrl = "https://api.factulink.com.mx", // Default
Timeout = TimeSpan.FromSeconds(30), // Default 30s
Retries = 2, // Default 2 reintentos en 429/5xx
});Inyectar tu propio HttpClient
Útil para añadir handlers (logging, telemetría) o reutilizar la conexión:
var http = new HttpClient();
var fc = new FactuLinkClient(new FactuLinkOptions { ApiKey = "sk_live_..." }, http);Recursos disponibles
| Recurso | Métodos |
|---|---|
fc.Cfdis | CreateAsync, ListAsync, GetAsync, CancelAsync, DownloadXmlAsync, DownloadPdfAsync, SatStatusAsync, ValidateAsync, ListAutoPaginateAsync |
fc.Clients | CreateAsync, ListAsync, GetAsync, UpdateAsync, DeleteAsync |
fc.Certificates | UploadAsync, ListAsync, GetAsync, UpdateAsync, DeleteAsync |
fc.Catalogs | ProductsAsync, UnitsAsync, TaxRegimesAsync, CfdiUsagesAsync, PaymentFormsAsync, PaymentMethodsAsync, CurrenciesAsync, CountriesAsync |
fc.Webhooks | CreateAsync, ListAsync, UpdateAsync, DeleteAsync, DeliveriesAsync, TestAsync |
fc.Ai | CreateFromTextAsync, ConfirmInvoiceAsync, CopilotAsync |
fc.ApiKeys | CreateAsync, ListAsync, RevokeAsync |
Operaciones comunes
Descargar PDF / XML
var pdfBytes = await fc.Cfdis.DownloadPdfAsync(cfdi.Uuid);
await File.WriteAllBytesAsync($"{cfdi.Uuid}.pdf", pdfBytes);
var xmlBytes = await fc.Cfdis.DownloadXmlAsync(cfdi.Uuid);
await File.WriteAllBytesAsync($"{cfdi.Uuid}.xml", xmlBytes);Cancelar CFDI
var resultado = await fc.Cfdis.CancelAsync(cfdi.Uuid, new CancelCfdiParams
{
Motivo = "02",
});Auto-paginación con IAsyncEnumerable
await foreach (var cfdi in fc.Cfdis.ListAutoPaginateAsync(new CfdiListParams { Estado = "timbrado" }))
{
Console.WriteLine(cfdi.Uuid);
}Webhooks
var webhook = await fc.Webhooks.CreateAsync(new CreateWebhookParams
{
Url = "https://tu-servidor.com/fc-webhook",
Events = new[] { "cfdi.timbrado", "cfdi.cancelado" },
});
Console.WriteLine($"Guarda este secret: {webhook.Secret}");
await fc.Webhooks.TestAsync(webhook.Id);Manejo de errores
using FactuLink.Exceptions;
try
{
await fc.Cfdis.CreateAsync(parameters);
}
catch (RateLimitException ex)
{
Console.WriteLine($"Rate limited — reintenta en {ex.RetryAfter}s");
}
catch (AuthException)
{
Console.WriteLine("API key inválida o expirada");
}
catch (ApiException ex)
{
Console.WriteLine($"{ex.Code}: {ex.Message}");
foreach (var detail in ex.Details) Console.WriteLine(detail);
}Jerarquía: RateLimitException y AuthException heredan de ApiException,
que hereda de FactuLinkException. El cliente reintenta automáticamente en
429 y 5xx con backoff exponencial.
Ambientes
- Sandbox: API Keys con prefijo
sk_test_.... Timbrado simulado, no se envía al SAT y no consume folios reales. - Producción: API Keys con prefijo
sk_live_.... Timbrado con el PAC autorizado y registro ante el SAT.
El mismo BaseUrl (https://api.factulink.com.mx) atiende ambos ambientes —
el prefijo de la API Key determina cuál usar.
Código fuente
- GitHub: github.com/IYair/fc-sdk-dotnet
- NuGet: FactuLink
Reportes de bugs y feature requests bienvenidos en el repo.
Last updated on