using API.WebHost.NotasFiscais; using Microsoft.Extensions.Options; using NuvemFiscal.Sdk.Api; using NuvemFiscal.Sdk.Client; using NuvemFiscal.Sdk.Model; public interface INfcomSdkService { Task EmitirAsync(NfcomPedidoEmissao payload, CancellationToken ct = default); Task ConsultarAsync(string id, CancellationToken ct = default); Task CancelarAsync(string id, NfcomPedidoCancelamento payloadCancelamento, CancellationToken ct = default); Task BaixarXmlAsync(string id, CancellationToken ct = default); Task ConsultarStatusSefazAsync(string uf, CancellationToken ct = default); } public sealed class NfcomSdkService( IHttpClientFactory httpFactory, INuvemFiscalTokenProvider tokenProvider, IOptions opt) : INfcomSdkService { private NfcomApi CreateApi(string accessToken) { var http = httpFactory.CreateClient("NuvemFiscal.SDK"); // Habilitar gzip para receber XML/PDF quando aplicável (conforme README do SDK) var handler = new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.All }; var cfg = new Configuration { AccessToken = accessToken, BasePath = opt.Value.BaseApiUrl.TrimEnd('/') // sandbox ou produção }; // Construtor que aceita HttpClient + Configuration (+ opcional handler) return new NfcomApi(http, cfg, handler); } public async Task EmitirAsync(NfcomPedidoEmissao payload, CancellationToken ct = default) { var token = await tokenProvider.GetTokenAsync(ct); var api = CreateApi(token); var requisito = CriarRequisitoEmissaoNfCom(payload); // Nome do método segue o padrão do SDK (ex.: EmitirNfcom) var result = await api.EmitirNfcomAsync(requisito, ct); return result!; } private NfcomPedidoEmissao CriarRequisitoEmissaoNfCom(NfcomPedidoEmissao payload) { // 1) Montar a NFCom (sandbox PR/Curitiba) var builder = new NfcomBuilder() .SandboxPRCuritibaTemplate() .WithId("NFCom000001ABCDEF12345600000000000000000000000000") .WithReferencia("PEDIDO-TESTE-0001") .WithEmitente( cnpj: "58728789000181", ie: "123456789012", crt: 3, xNome: "EMPRESA TESTE NFCom LTDA", xFant: "EMPRESA TESTE", xLgr: "Av. Teste", nro: "1000", xBairro: "Centro", cMun: "4106902", xMun: "Curitiba", cep: "80000000", uf: "PR", fone: "41999999999", email: "fiscal@exemplo.com.br") .WithDestinatarioPF( nome: "Cliente de Teste", cpf: "11144477735", indIEDest: 9, xLgr: "Rua Exemplo", nro: "123", xBairro: "Bairro", cMun: "4106902", xMun: "Curitiba", cep: "80000000", uf: "PR", cPais: "1058", xPais: "Brasil", fone: "41988887777", email: "cliente@exemplo.com") .WithAssinante( iCodAssinante: "CT-0001", tpAssinante: 1, tpServUtil: 1, nContrato: "CONTR-2025-0001", dIni: new DateOnly(2025, 9, 1), dFim: new DateOnly(2026, 8, 31), nroTermPrinc: "41999990001", cUFPrinc: 41) .AddItemServico( nItem: 1, cProd: "INT100M", xProd: "Serviço de Internet 100 Mbps - Mensalidade", cClass7digits: "0101010", cfop: "5301", uMed: 1, qFaturada: 1m, vItem: 100m, vDesc: 0m, vOutro: 0m) .AutoTotals(); // 2A) Se quiser ver o JSON final var json = builder.BuildJson(); Console.WriteLine(json); var requisito = builder.BuildAs(); return requisito; } public async Task ConsultarAsync(string id, CancellationToken ct = default) { var token = await tokenProvider.GetTokenAsync(ct); var api = CreateApi(token); return await api.ConsultarNfcomAsync(id, ct); } public async Task CancelarAsync(string id, NfcomPedidoCancelamento payloadCancelamento, CancellationToken ct = default) { var token = await tokenProvider.GetTokenAsync(ct); var api = CreateApi(token); return await api.CancelarNfcomAsync(id, payloadCancelamento, ct); } public async Task BaixarXmlAsync(string id, CancellationToken ct = default) { var token = await tokenProvider.GetTokenAsync(ct); var api = CreateApi(token); // Normalmente há método do tipo BaixarXmlNfcomAsync var file = await api.BaixarXmlNfcomAsync(id, ct); return file; } public async Task ConsultarStatusSefazAsync(string uf, CancellationToken ct = default) { var token = await tokenProvider.GetTokenAsync(ct); var api = CreateApi(token); return await api.ConsultarStatusSefazNfcomAsync(uf, cancellationToken: ct); } }