EcfService.Sdk
0.2.0
dotnet add package EcfService.Sdk --version 0.2.0
NuGet\Install-Package EcfService.Sdk -Version 0.2.0
<PackageReference Include="EcfService.Sdk" Version="0.2.0" />
<PackageVersion Include="EcfService.Sdk" Version="0.2.0" />
<PackageReference Include="EcfService.Sdk" />
paket add EcfService.Sdk --version 0.2.0
#r "nuget: EcfService.Sdk, 0.2.0"
#:package EcfService.Sdk@0.2.0
#addin nuget:?package=EcfService.Sdk&version=0.2.0
#tool nuget:?package=EcfService.Sdk&version=0.2.0
emite.do SDK — C# / .NET
SDK oficial para api.emite.do. El mismo POST /api/v1/ecf cubre E31–E47.
Guía: docs.emite.do/sdks/csharp · API: docs.emite.do
El paquete incluye XML de documentación (IntelliSense en Rider/VS).
Requisitos
- .NET 8.0 o superior
Instalación
dotnet add package EcfService.Sdk
Inicio rápido
using EcfService.Sdk;
using EcfService.Sdk.Models;
using var client = new EcfClient("tu_api_key");
var payload = new EcfPayloadBuilder(EcfType.E31)
.IdDoc(new Dictionary<string, object?>
{
["eNCF"] = "E310000000001",
["FechaVencimientoSecuencia"] = "31-12-2028",
})
.Emisor(new Dictionary<string, object?>
{
["RNCEmisor"] = "130478031",
["RazonSocialEmisor"] = "Mi Empresa SRL",
["FechaEmision"] = DateTime.Today.ToString("dd-MM-yyyy"),
})
.Comprador(new Dictionary<string, object?>
{
["RNCComprador"] = "131098193",
["RazonSocialComprador"] = "Cliente SRL",
})
.Totales(new Dictionary<string, object?>
{
["MontoTotal"] = 11800.0,
["TotalITBIS"] = 1800.0,
})
.AddItem(new Dictionary<string, object?>
{
["NumeroLinea"] = 1,
["NombreItem"] = "SERVICIO DEMO",
["MontoItem"] = 10000.0,
})
.Build();
EcfDocument doc = await client.Ecf.CreateAsync(
idempotencyKey: "INV-2026-0001",
ecfType: EcfType.E31,
payload: payload,
environment: EcfEnvironment.Test
);
Console.WriteLine($"{doc.PublicId} {doc.Status}"); // Received — el veredicto fiscal llega después
doc = await client.Ecf.GetAsync(doc.PublicId);
byte[] xml = await client.Ecf.DownloadXmlAsync(doc.PublicId);
EcfType acepta E31–E47. Cambia TipoeCF y el e-NCF (E32…, E47…) al tipo.
Misma idempotencyKey → 200 del original (el payload no se compara).
El builder pone TipoeCF (no TipoEcf). FechaEmision va en Emisor. Alias cortos RNC / RazonSocial se expanden a RNCEmisor / RNCComprador.
Empresa, rangos, inbox
var profile = await client.Client.CompanyAsync();
var seqs = await client.Client.SequencesAsync(activeOnly: true);
var inbox = await client.Client.InboxAsync(acked: false);
await client.Client.AckInboxAsync(inbox.Items[0].PublicId);
Los rangos se listan; no se crean por API.
ACECF y ANECF
await client.Ecf.SubmitAcecfAsync(
idempotencyKey: "ac-001",
encf: "E310000000001",
rncEmisor: "130478031",
rncComprador: "131098193",
fechaEmision: "15-08-2026",
montoTotal: "11800.00",
estado: "1"
);
await client.Ecf.CancelSequencesAsync("an-001", new[]
{
new CancellationLine
{
EcfType = EcfType.E31,
SequenceFrom = "E310000000010",
SequenceTo = "E310000000012",
Quantity = 3
}
});
Webhooks
Hoy el service notifica accepted, conditionally_accepted y rejected.
using EcfService.Sdk.Webhooks;
var wh = await client.Client.CreateWebhookAsync(
"https://mi-app.example/webhooks/ecf",
new List<string> { "accepted", "conditionally_accepted", "rejected" }
);
bool ok = WebhookVerifier.VerifySignature(requestBody, request.Headers["X-ECF-Signature"], wh.Secret);
Salud y padrón (sin API key)
using var client = new EcfClient(); // key opcional
Console.WriteLine((await client.HealthAsync()).Status);
Console.WriteLine((await client.Dgii.RncAsync("130478031")).RazonSocial);
Errores
El service responde { "detail": "..." } (FastAPI).
401→EcfAuthException404→EcfNotFoundException409e-NCF usado →EcfConflictException422payload / rango / P12 / header faltante →EcfValidationException
HttpClient e inyección
// IHttpClientFactory — no dispongas el HttpClient
builder.Services.AddHttpClient<EcfClient>((_, http) =>
{
http.BaseAddress = new Uri("https://api.emite.do/api/v1/");
http.DefaultRequestHeaders.Add("X-API-Key", config["Emite:ApiKey"]);
});
El constructor new EcfClient(httpClient) no dispone el cliente a menos que pases disposeHttpClient: true.
Qué no hace este SDK
- No valida el XSD DGII (lo hace el service).
- No crea rangos e-NCF; solo los lista.
- El
201deCreateAsyncesReceived, no el veredicto fiscal.
Licencia
MIT
| Product | Versions 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 was computed. 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. |
-
net8.0
- No dependencies.
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 |
|---|---|---|
| 0.2.0 | 0 | 8/16/2026 |