/// <summary> /// Gera um evento de manifesto do destinatário /// </summary> /// <param name="cnpj">CNPJ do destinatário</param> /// <param name="chave">Chave da NFe</param> /// <param name="evento">Tipo de evento</param> /// <param name="sequencia">Número sequencial usado para identificar a ordem que os eventos ocorreram</param> /// <param name="justificativa">Justificativa caso necessária</param> /// <exception cref="SefazException">Pode lançar uma exceção caso o cStat tenha algum valor inesperado</exception> /// <remarks>O schema (xsd) não está sendo validado antes do envio</remarks> public async Task ManifestarNFeAsync(string cnpj, string chave, Models.NFe.TEventoInfEventoDetEventoDescEvento evento, int sequencia = 1, string justificativa = null) { if (string.IsNullOrWhiteSpace(cnpj)) { throw new ArgumentNullException(nameof(cnpj)); } if (cnpj.Length != 14) { throw new ArgumentException("O CNPJ deve ter 14 algarismos.", nameof(cnpj)); } if (string.IsNullOrWhiteSpace(chave)) { throw new ArgumentNullException(nameof(chave)); } if (chave.Length != 44) { throw new ArgumentException("A chave deve ter 44 algarismos.", nameof(chave)); } if (DateTime.UtcNow > _Certificado.NotAfter) { throw new Exception($"O certificado venceu em {_Certificado.NotAfter}!"); } if (DateTime.UtcNow < _Certificado.NotBefore) { throw new Exception("O certificado ainda não é válido!"); } // Configuração do ws var endpoint = new System.ServiceModel.EndpointAddress(_EndPointNFeRecepcaoEvento); var binding = new System.ServiceModel.BasicHttpBinding(System.ServiceModel.BasicHttpSecurityMode.Transport) { MaxReceivedMessageSize = 999999999 }; binding.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Certificate; // Instância do cliente var ws = new NFeRecepcaoEvento4SoapClient(binding, endpoint); // Definição do certificado ws.ClientCredentials.ClientCertificate.Certificate = _Certificado; // Dados Models.NFe.TEventoInfEventoTpEvento tpEvento; string id; string nSeqEvento; switch (evento) { case Models.NFe.TEventoInfEventoDetEventoDescEvento.CienciaDaOperacao: tpEvento = Models.NFe.TEventoInfEventoTpEvento.CienciaDaEmissao; nSeqEvento = "1"; // FIXO "1" id = "ID" + "210210" + chave + nSeqEvento.PadLeft(2, '0'); // "ID" + tpEvento + chave da NF-e + nSeqEvento break; case Models.NFe.TEventoInfEventoDetEventoDescEvento.ConfirmacaoDaOperacao: tpEvento = Models.NFe.TEventoInfEventoTpEvento.ConfirmacaoDaOperacao; nSeqEvento = sequencia.ToString(); id = "ID" + "210200" + chave + nSeqEvento.PadLeft(2, '0'); break; case Models.NFe.TEventoInfEventoDetEventoDescEvento.DesconhecimentoDaOperacao: tpEvento = Models.NFe.TEventoInfEventoTpEvento.DesconhecimentoDaOperacao; nSeqEvento = sequencia.ToString(); id = "ID" + "210220" + chave + nSeqEvento.PadLeft(2, '0'); break; case Models.NFe.TEventoInfEventoDetEventoDescEvento.OperacaoNaoRealizada: tpEvento = Models.NFe.TEventoInfEventoTpEvento.OperacaoNaoRealizada; nSeqEvento = sequencia.ToString(); id = "ID" + "210240" + chave + nSeqEvento.PadLeft(2, '0'); break; default: throw new NotImplementedException("Tipo de evento não suportado!"); } var dados = new Models.NFe.TEnvEvento { versao = "1.00", idLote = 1.ToString("000000000000000"), evento = new[] { new Models.NFe.TEvento { versao = "1.00", // Versão do layout do evento infEvento = new Models.NFe.TEventoInfEvento { Id = id, // Identificador da TAG a ser assinada, a regra de formação do Id é: “ID” + tpEvento + chave da NF-e + nSeqEvento cOrgao = OrgaoManifesto, // Código do órgão de recepção do Evento. Utilizar a Tabela de UF do IBGE, utilizar 91 para identificar o Ambiente Nacional. tpAmb = _Ambiente, Item = cnpj, ItemElementName = cnpj.Length > 11 ? Models.NFe.TipoPessoa.CNPJ : Models.NFe.TipoPessoa.CPF, chNFe = chave, dhEvento = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"), tpEvento = tpEvento, nSeqEvento = nSeqEvento, verEvento = "1.00", // Identificação da Versão do evento informado em detEvento detEvento = new Models.NFe.TEventoInfEventoDetEvento { versao = Models.NFe.TEventoInfEventoDetEventoVersao.Item100, descEvento = evento, xJust = justificativa } } //Signature = null // Assinatura Digital do documento XML, a assinatura deverá ser aplicada no elemento infEvento } } }; // Corpo var corpo = new XmlDocument(); using var memoryStream = new MemoryStream(); var streamWriter = new StreamWriter(memoryStream); XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", "http://www.portalfiscal.inf.br/nfe"); new XmlSerializer(typeof(Models.NFe.TEnvEvento)).Serialize(streamWriter, dados, ns); corpo.LoadXml(Encoding.UTF8.GetString(memoryStream.ToArray())); //Assinar(ref corpo); corpo = Util.AssinarXML(corpo, _Certificado, "infEvento"); // Chama o web service var resposta = await ws.nfeRecepcaoEventoNFAsync(corpo); // Trabalha com a resposta var retorno = resposta.nfeRecepcaoEventoNFResult.DeserializeTo <Models.NFe.TRetEnvEvento>(); if (retorno.cStat != "128") { throw new SefazException(retorno.cStat, retorno.xMotivo); } var infEvento = retorno.retEvento[0].infEvento; if (infEvento.cStat != "135") { throw new SefazException(infEvento.cStat, infEvento.xMotivo); } }
public Task ManifestarNFe(string cnpj, string chave, Models.NFe.TEventoInfEventoDetEventoDescEvento evento, int sequencia = 1, string justificativa = null) => ManifestarNFeAsync(cnpj, chave, evento, sequencia, justificativa);