diff --git a/DFe.Testes/Gerais/ObterIdTestes.cs b/DFe.Testes/Gerais/ObterIdTestes.cs
new file mode 100644
index 000000000..2733d6e47
--- /dev/null
+++ b/DFe.Testes/Gerais/ObterIdTestes.cs
@@ -0,0 +1,61 @@
+using DFe.Classes.Entidades;
+using DFe.Classes.Flags;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NFe.Classes.Servicos.Tipos;
+using NFe.Utils.Evento;
+using NFe.Utils.Inutilizacao;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Vetores ouro do Id assinável de evento (infEvento/@Id) e de inutilização (infInut/@Id).
+ ///
+ /// Esses Ids também são calculados internamente pelos métodos que assinam (ServicosNFe). Se o formato
+ /// divergir, o digest da assinatura não bate e o SEFAZ rejeita — por isso os valores esperados aqui são
+ /// literais do layout, e não o resultado do próprio método.
+ ///
+ ///
+ [TestClass]
+ public class ObterIdTestes
+ {
+ /// Chave de NF-e (modelo 55) com CNPJ alfanumérico, conforme NT Conjunta 2025.001
+ private const string ChaveNFe = "522507PC3D315K000193550010000000011000000018";
+
+ /// Chave de NFC-e (modelo 65), 100% numérica
+ private const string ChaveNFCe = "23190811820016000167650010000000221100000227";
+
+ private const string CnpjNumerico = "11820016000167";
+ private const string CnpjAlfanumerico = "PC3D315K000193";
+
+ [TestMethod]
+ [DataRow(NFeTipoEvento.TeNfeCancelamento, ChaveNFe, 1, "ID110111" + ChaveNFe + "01",
+ DisplayName = "Cancelamento, chave com CNPJ alfanumérico")]
+ [DataRow(NFeTipoEvento.TeNfeCartaCorrecao, ChaveNFe, 2, "ID110110" + ChaveNFe + "02",
+ DisplayName = "Carta de Correção, 2ª sequência")]
+ [DataRow(NFeTipoEvento.TeMdCienciaDaOperacao, ChaveNFCe, 1, "ID210210" + ChaveNFCe + "01",
+ DisplayName = "Ciência da Operação, chave numérica")]
+ [DataRow(NFeTipoEvento.TeMdCienciaDaOperacao, ChaveNFCe, 11, "ID210210" + ChaveNFCe + "11",
+ DisplayName = "Sequência com 2 dígitos não recebe zero à esquerda")]
+ public void ObterIdEvento_SegueOLayout(NFeTipoEvento tpEvento, string chNFe, int nSeqEvento, string esperado)
+ {
+ Assert.AreEqual(esperado, Extevento.ObterId(tpEvento, chNFe, nSeqEvento));
+ }
+
+ [TestMethod]
+ [DataRow(ModeloDocumento.NFe, CnpjNumerico, 1, 1, 10,
+ "ID3525" + CnpjNumerico + "55" + "001" + "000000001" + "000000010",
+ DisplayName = "NF-e, modelo 55")]
+ [DataRow(ModeloDocumento.NFCe, CnpjNumerico, 1, 1, 10,
+ "ID3525" + CnpjNumerico + "65" + "001" + "000000001" + "000000010",
+ DisplayName = "NFC-e, modelo 65")]
+ [DataRow(ModeloDocumento.NFe, CnpjAlfanumerico, 12, 5, 5,
+ "ID3525" + CnpjAlfanumerico + "55" + "012" + "000000005" + "000000005",
+ DisplayName = "CNPJ alfanumérico, faixa de um número só")]
+ public void ObterIdInutilizacao_SegueOLayout(ModeloDocumento modelo, string cnpj, int serie,
+ int numeroInicial, int numeroFinal, string esperado)
+ {
+ Assert.AreEqual(esperado,
+ ExtinutNFe.ObterId(Estado.SP, 25, cnpj, modelo, serie, numeroInicial, numeroFinal));
+ }
+ }
+}
diff --git a/NFe.Servicos/ServicosNFe.cs b/NFe.Servicos/ServicosNFe.cs
index e6f4534ca..6474fdf7e 100644
--- a/NFe.Servicos/ServicosNFe.cs
+++ b/NFe.Servicos/ServicosNFe.cs
@@ -675,6 +675,23 @@ public RetornoRecepcaoEvento RecepcaoEventoManifestacaoDestinatario(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Manifestação do destinatário" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoManifestacaoDestinatario(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoManifestacaoDestinatario, _cFgServico.VersaoRecepcaoEventoManifestacaoDestinatario, assinar);
+ return retorno;
+ }
+
///
/// Envia um evento do tipo "EPEC"
///
@@ -816,6 +833,23 @@ public RetornoRecepcaoEvento RecepcaoEventoInsucessoEntrega(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Insucesso na Entrega da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoInsucessoEntrega(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, assinar);
+ return retorno;
+ }
+
///
/// Serviço para cancelamento insucesso na entrega
///
@@ -868,6 +902,23 @@ public RetornoRecepcaoEvento RecepcaoEventoCancInsucessoEntrega(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Cancelamento do Insucesso na Entrega da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoCancInsucessoEntrega(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancInsucessoEntregaNFe, _cFgServico.VersaoRecepcaoEventoInsucessoEntrega, assinar);
+ return retorno;
+ }
+
///
/// Recepção do Evento de Comprovante de Entrega
///
@@ -937,6 +988,23 @@ public RetornoRecepcaoEvento RecepcaoEventoComprovanteEntrega(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Comprovante de Entrega da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoComprovanteEntrega(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoComprovanteEntregaNFe, _cFgServico.VersaoRecepcaoEventoComprovanteEntrega, assinar);
+ return retorno;
+ }
+
///
/// Serviço para cancelamento comprovante de entrega
///
@@ -990,6 +1058,23 @@ public RetornoRecepcaoEvento RecepcaoEventoCancComprovanteEntrega(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Cancelamento do Comprovante de Entrega da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoCancComprovanteEntrega(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancComprovanteEntregaNFe, _cFgServico.VersaoRecepcaoEventoComprovanteEntrega, assinar);
+ return retorno;
+ }
+
///
/// Recepção do Evento de Conciliação Financeira
@@ -1041,6 +1126,23 @@ public RetornoRecepcaoEvento RecepcaoEventoConciliacaoFinanceira(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Conciliação Financeira da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoConciliacaoFinanceira(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoConciliacaoFinanceiraNFe, _cFgServico.VersaoRecepcaoEventoConciliacaoFinanceira, assinar);
+ return retorno;
+ }
+
///
/// Serviço para cancelamento Conciliação Financeira
///
@@ -1092,6 +1194,23 @@ public RetornoRecepcaoEvento RecepcaoEventoCancConciliacaoFinanceira(int idlote,
return retorno;
}
+ ///
+ /// Envia eventos do tipo "Cancelamento da Conciliação Financeira da NF-e" já assinado.
+ ///
+ ///
+ ///
+ ///
+ /// false (padrão) para transmitir os eventos exatamente como vieram, já assinados; true para a biblioteca
+ /// calcular o Id e assinar cada evento com o certificado desta instância de ServicosNFe, sobrescrevendo o Id
+ /// que já estiver preenchido.
+ ///
+ ///
+ public RetornoRecepcaoEvento RecepcaoEventoCancConciliacaoFinanceira(int idlote, List eventos, bool assinar = false)
+ {
+ var retorno = RecepcaoEvento(idlote, eventos, ServicoNFe.RecepcaoEventoCancConciliacaoFinanceiraNFe, _cFgServico.VersaoRecepcaoEventoConciliacaoFinanceira, assinar);
+ return retorno;
+ }
+
///
/// Recepção do Evento de Perecimento, perda, roubo ou furto durante o transporte contratado pelo fornecedor
///
diff --git a/NFe.Utils/Evento/Extevento.cs b/NFe.Utils/Evento/Extevento.cs
index c278d6745..70e3668e5 100644
--- a/NFe.Utils/Evento/Extevento.cs
+++ b/NFe.Utils/Evento/Extevento.cs
@@ -2,6 +2,7 @@
using System.Security.Cryptography.X509Certificates;
using DFe.Utils;
using NFe.Classes.Servicos.Evento;
+using NFe.Classes.Servicos.Tipos;
using NFe.Utils.Assinatura;
namespace NFe.Utils.Evento
@@ -18,6 +19,23 @@ public static string ObterXmlString(this evento pedEvento)
return FuncoesXml.ClasseParaXmlString(pedEvento);
}
+ ///
+ /// Obtém o Id de um evento (infEvento/@Id): literal "ID" + tpEvento + chNFe + nSeqEvento com 2 dígitos
+ ///
+ /// Uso opcional, para quando o evento for montado fora da biblioteca — por exemplo, para assinar com o
+ /// certificado numa máquina cliente e depois transmitir com a sobrecarga que recebe o evento já
+ /// assinado. Os métodos que assinam internamente continuam calculando o Id sozinhos.
+ ///
+ ///
+ /// Código do evento
+ /// Chave de acesso da NF-e vinculada ao evento
+ /// Sequencial do evento para o mesmo tipo de evento
+ /// Retorna o conteúdo do atributo infEvento/@Id
+ public static string ObterId(NFeTipoEvento tpEvento, string chNFe, int nSeqEvento)
+ {
+ return "ID" + ((int)tpEvento) + chNFe + nSeqEvento.ToString().PadLeft(2, '0');
+ }
+
///
/// Assina um objeto evento
///
diff --git a/NFe.Utils/Inutilizacao/ExtinutNFe.cs b/NFe.Utils/Inutilizacao/ExtinutNFe.cs
index 9f00c220d..79b8e544d 100644
--- a/NFe.Utils/Inutilizacao/ExtinutNFe.cs
+++ b/NFe.Utils/Inutilizacao/ExtinutNFe.cs
@@ -1,5 +1,7 @@
using System;
using System.Security.Cryptography.X509Certificates;
+using DFe.Classes.Entidades;
+using DFe.Classes.Flags;
using DFe.Utils;
using NFe.Classes.Servicos.Inutilizacao;
using NFe.Utils.Assinatura;
@@ -29,6 +31,36 @@ public static string ObterXmlString(this inutNFe pedInutilizacao)
return FuncoesXml.ClasseParaXmlString(pedInutilizacao);
}
+ ///
+ /// Obtém o Id de um pedido de inutilização (infInut/@Id): literal "ID" + cUF + ano com 2 dígitos + CNPJ +
+ /// modelo + série com 3 dígitos + número inicial e número final com 9 dígitos
+ ///
+ /// Uso opcional, para quando o pedido for montado fora da biblioteca — por exemplo, para assinar com o
+ /// certificado numa máquina cliente e depois transmitir com já feito, via a
+ /// sobrecarga que recebe o inutNFe pronto. O método que assina internamente continua calculando o Id
+ /// sozinho.
+ ///
+ ///
+ /// Código da UF do solicitante
+ /// Ano de inutilização da numeração
+ /// CNPJ do emitente
+ /// Modelo do documento
+ /// Série
+ /// Número inicial a ser inutilizado
+ /// Número final a ser inutilizado
+ /// Retorna o conteúdo do atributo infInut/@Id
+ public static string ObterId(Estado cUF, int ano, string cnpj, ModeloDocumento modelo, int serie,
+ int numeroInicial, int numeroFinal)
+ {
+ var numId = string.Concat((int)cUF, ano.ToString("D2"),
+ cnpj, (int)modelo,
+ serie.ToString().PadLeft(3, '0'),
+ numeroInicial.ToString().PadLeft(9, '0'),
+ numeroFinal.ToString().PadLeft(9, '0'));
+
+ return "ID" + numId;
+ }
+
///
/// Assina um objeto inutNFe
///