Ir para conteúdo
  • Cadastre-se

dev botao

Problemas com assinatura digital em xml de NFSe - Prefeitura Uberlândia


Ver Solução Respondido por Italo Giurizzato Junior,
  • Este tópico foi criado há 1043 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Boa noite Italo.

Atualizei os fontes, testei e deu certo. Gerou o xml assinado.

Só uma ressalva ... os valores dos atributos das tags lote e rps estão sendo gerado com um _ (underline) e no manual da NFSe da prefeitura esses ids ficam com : (dois pontos).

Você acha possível substituir <Lote Id="Lote_2"> por <Lote Id="lote:2"> ou <Lote Id="lote2"> e também para os RPSs ...  <RPS Id="Rps_2"> por <RPS Id="rps:1"> ou <RPS Id="rps1"> ?

Não sei, sinceramente se a prefeitura de Uberlândia recusaria a assinatura digital por casa desse underline, como disse, estou seguindo o manual deles. Mas se tivesse como substituir para ficar igual ao manual, serial legal. 

Esqueci de anexar o xml assinado que eu gerei, pelo botão 'Gerar Lote RPS'.

2-env-lot.xml

Postado

Oi Italo. Bom dia.

Testei o envio do lote pelos botões 'Emitir Nota (Novo)' e 'Enviar Lote RPS (Síncrono)', os dois deram erro pois o certificado que tenho para testes, está vencido. Estou verificando aqui com o pessoal da minha empresa para conseguir um certificado atual. O que posso adiantar é que o ''Enviar Lote RPS (Síncrono)' apesar de não ter enviado o lote tmb gerou um xml assinado. Muito bom.

Estou usando, na aba Web Services o ambiente de homologação e escolhi em SSLType o tipo LT_SSLv2. Os demais campos não preenchi, a princípio não vi a necessidade de preencher esses campos, uma vez que no manual da prefeitura, nada é mencionado em relação a usuários e senhas.

Agora, eu volto na dúvida que me fez criar esse post, dei essa volta toda (e tive q dar para aprender a entender melhor o componente) pois estava usando o componente ACBrNFSe e o Juliomar (em resposta a esse post) me disse para utilizar o novo componente ACBrNFSeX pois, o antigo já não possuía mais suporte.

Enfim ... Como eu já tenho uma rotina que gera o xml (e comparando com o xml gerado pelo ACBrNFSeX, através do botão 'Gerar Lote RPS' é exatamente o mesmo, a diferença está nos valores e o meu xml não está assinado), eu precisava apenas de assinar esse xml. Dessa forma, já com uma experiência no uso do componente ACBrNFSeX eu tentei carregar o meu xml e em seguida utilizo a função 'GerarLote' porém ocorrem erros mas não consegui descobrir o motivo do erro. Pode me auxiliar ?

O código que estou tentando gerar a assinatura é esse:

 // **************************************************************************
  //
  // A function GerarLote apenas gera o XML do lote, assina se necessário
  // e valida, salvando o arquivo com o nome: <lote>-lot-rps.xml na pasta Ger
  // Não ocorre o envio para nenhum webservice.
  //
  // **************************************************************************
  vNumLote := '';
  if not(InputQuery('Gerar e Enviar Lote', 'Numero do Lote', vNumLote)) then
    exit;

  vNumRPS := vNumLote;
  if not(InputQuery('Gerar e Enviar Lote', 'Numero do RPS', vNumRPS)) then
    exit;

  ACBrNFSeX1.NotasFiscais.Clear;
  //AlimentarNFSe(vNumRPS, vNumLote);
  ACBrNFSeX1.NotasFiscais.LoadFromLoteNfse('F:\Raiz\Arquivos\eNotasFiscais\4427.xml');

  //ACBrNFSeX1.GerarLote(vNumLote);
  ACBrNFSeX1.GerarLote('4427');

  ChecarResposta(tmGerarLote);

Diz (no memo) que nenhum RPS foi adicionado ao componente ou ao lote ... enfim, pelo o q entendi, a função LoadFromLoteNfse não carregou corretamente os RPSs dentro do componente ACBrNFSeX.

Segue em anexo o print da aba Web Serices, o print do erro de não conseguir assinar o lote e o meu arquivo xml gerado fora do exemplo da acbr.

Capturar.PNG

Erro.PNG

4427.xml

  • Consultores
Postado

Boa tarde Felipe,

No que se refere ao Certificado, ou você informar o path do arquivo PFX e a senha ou o numero de série do certificado.

Como você esta carregando um XML, este tem que ser de Rps, agora se esta mostrando a mensagem que o componente não esta carregado é preciso verificar porque ele não esta carregando o XML.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Boa tarde Italo.

Sobre o certificado, o problema é o q eu estou usando pois, ele está vencido ... estou providenciando um certificado atual.

Sobre o xml, eu vou fazer o seguinte ... como teste ... eu vou remover tudo do meu xml e deixar apenas as tags de rps, e em seguida vou carregar o xml novamente com a função LoadFromLoteNfse. Em seguida vou preencher as tags de cabeçalho através do componente e tentar gerar o lote novamente.

Assim q testar eu envio aqui os resultados.

Postado

Boa noite Italo.

Por enquanto sem sucesso. Tanto com a função LoadFromLoteNfse, quanto com a função LoadFromFile ocorrem erros e o arquivo xml assinado não é gerado.

Com a função LoadFromLoteNfse,  o código ficou assim:

.
.
.

ACBrNFSeX1.NotasFiscais.Clear;
ACBrNFSeX1.NotasFiscais.LoadFromLoteNfse('F:\Raiz\Arquivos\eNotasFiscais\4427.xml');

ACBrNFSeX1.GerarLote('4427');

ChecarResposta(tmGerarLote);

Já com a função LoadFromFile, o código ficou assim:

.
.
.

ACBrNFSeX1.NotasFiscais.Clear;
ACBrNFSeX1.NotasFiscais.LoadFromFile('F:\Raiz\Arquivos\eNotasFiscais\4427.xml');

ACBrNFSeX1.GerarLote('4427');

ChecarResposta(tmGerarLote);

Lembrando que esse código está dentro do evento onclick do botão 'Gerar Lote RPS' do exemplo do componente ACBrNFSeX1.

Segue em anexo os erros apresentados no uso de cada função e também, o xml que estou tentando importar.

P.S. Provável que a estrutura do xml que eu estou enviando está diferente da estrutura esperada pelas funções LoadFromLoteNfse e LoadFromFile. Mas eu não sei que estrutura seria essa. Preciso do auxílio de vocês para descobrir o xml ideal a ser importado.

Erro_LoadFromLoteNfse.PNG

Erro_LoadFromFile.PNG

4427.xml

  • Consultores
Postado

Bom dia Felipe,

Quem esta gerando o XML do Rps, a sua aplicação ou o componente?

Porque você gera o XML do Rps para depois carregar o mesmo e por fim gerar o Lote?

Em vez de gerar o lote e acessar o site do provedor para importar o mesmo, porque não utiliza o método Emitir que já envia para o webservice do provedor?

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Bom dia Italo.

O xml é a aplicação que gera, fora da biblioteca acbr.

"Porque você gera o XML do Rps para depois carregar o mesmo e por fim gerar o Lote?" Na verdade eu gero o arquivo completo (não assinado), esse exemplo que te passei, foi só para ver se eu ia conseguir carregar os rps pelo LoadFromLoteNfse mas, msm com o xml apenas com os RPSs tmb não funcionou.

"Em vez de gerar o lote e acessar o site do provedor para importar o mesmo, porque não utiliza o método Emitir que já envia para o webservice do provedor? " Prq dessa forma eu vou ter q reescrever o meu código todo, alimentando o componente (como é feito naquela função AlimentarNFSe). Para eu usar tanto a função GerarLote ou a Emitir eu precisaria alimentar todas aquelas propriedades do componente ACBrNFSeX. E eu sei que preciso fazer isso mas, queria fazer com o arquivo xml q eu já tenho ao invés de reescrever a rotina para gerar os RPSs.

Segue em anexo o arquivo xml (real) que a minha aplicação gera. Repare q não está assinado mas, está completinho, com todas as informações necessárias para ser enviado a prefeitura.

P.S. Eu posso sim e vou, utilizar a função Emitir para enviar o xml para a prefeitura mas, preciso antes alimentar o componente ACBrNFSeX com os RPSs do meu arquivo xml.

4427_Original.xml

  • Consultores
Postado

Boa tarde Felipe,

Você já parou para pensar que um dia a prefeitura vai mudar de provedor, uma vez que os provedores são contratados por licitação e as licitações tem prazo de validade?

Quando vencer a licitação uma nova terá que ser feita e um novo provedor pode ganhar.

E se esse novo provedor tiver um layout diferente do provedor atual?

Você vai jogar essa rotina que você tem hoje fora e vai ter que escrever uma nova.

Quanto tempo (dinheiro) você vai gastar para escrever essa nova rotina?

Não seria mais prudente você pegar a rotina "AlimentarComponente" que esta no programa exemplo e adaptá-la para a sua aplicação?

A rotina AlimentarComponente do programa exemplo, tanto faz o provedor, o componente vai gerar o XML do Rps, do Lote, assinar se necessário, validar, etc.

Enfim faz tudo o que tem que ser feito.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Boa tarde Italo.

Então, pelo menos por enquanto eu não posso mexer no código que gera o xml na aplicação da empresa onde trabalho. Por agora, realmente eu tenho que apenas assinar o xml.

Sobre a sua explicação, no post anterior, eu concordo, e irei realizar essa implementação sim, mas futuramente. Prq como o código não fui eu quem desenvolveu (só fiz algumas melhorias), eu não posso simplesmente removê-lo e começar outro do zero.

Realmente, não tem hoje, uma forma de eu usar o componente ACBrNFSeX apenas para assinar um xml gerado externamente à acbr ?

  • Consultores
Postado

Boa tarde Felipe,

O componente só vai conseguir ler um XML seja ele um Rps ou NFSe se estiver configurado corretamente.

Detalhe importante, se você tem 30 Rps para serem lidos, se faz necessário ler um de cada vez.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Blz Italo. Vou tentar.

Só uma coisa ... no caso do meu xml externo, ele deve ter apenas as tags <RPS>...</RPS>, fora os itens q tem dentro dele e, apenas 1 RPS por arquivo xml.

É isso né ?

  • 2 meses depois ...
Postado

Bom dia Ítalo. Td bom ?

Segui o seu conselho e passei a usar o componente ACBrNFSeX (em sua totalidade) para gerar o lote (o arquivo xml com os RPSs e enviar para a prefeitura de Uberlândia).

Depois de muito estudo com aquela função AlimentarNFSe, consegui deixar o xml gerado exatamente igual ao arquivo que eu gerava na aplicação da empresa onde trabalho.

Depois de mais alguns estudos e configurações, ontem, consegui realizar a comunicação com o web service da prefeitura, através do botão 'Enviar Lote RPS (Teste)' e também nos botões 'Emitir Nota (Novo)', 'Enviar Lote RPS (Assíncrono)' e 'Enviar Lote RPS (Síncrono)' ... claro que o ideal é, por enquanto utilizar apenas o botão de envio de teste.

Dessa forma, foi gerado o arquivo de retorno do web service, só que com as recusas, ou seja, não gravou o lote e nem converteu os RPSs em NFSEs. 

Foram 5 recusas mas, 4 dessas são questões do cliente da empresa aqui com a prefeitura. Então é algo que eles irão conversar lá e me passar as informações corretas. O problema aqui é a recusa (ou erro) 1206 -- 'Assinatura do RPS incorreta. Código Hash gerado para o campo assinatura do RPS esta invalido.'

A tag <Assinatura></Assinatura> foi a única que eu não descobri uma propriedade (do componente ACBrNFSeX) para preenchê-la manualmente. Na verdade, o próprio componente está preenchendo a tag de forma automática.

Primeiro: Existe a possibilidade de eu fazer o preenchimento manual dessa tag? Pois eu sei como funciona o algoritmo para a criação do hash, do valor dessa tag.

Segundo: Caso, a primeira pergunta não seja possível, como posso proceder para que o valor da tag seja gerada de forma correta.

Segue um resumo do que eu descobri:

  • O hash gerado é esse db31896100a2cb64ea338341fe16a4bcf02e0481 porém o hash correto é 7f658d413161b03f2458dbef1c0a05fa6826523f
  • Parece que o correto é pegar o  valor total dos itens do serviço e remover qualquer separação de milhar e decimal. Se tiver casas decimais, deixar apenas com duas,  como os bancos costumam utilizar. Claro que isso é apenas uma hipótese, não tenho certeza pois não consigo pegar o hash gerado pelo componente e descriptografar ele. Então eu não sei exatamente que valores o componente pegou, para gerar o hash db31896100a2cb64ea338341fe16a4bcf02e0481.

Poderiam me auxiliar, por favor, nessa questão ? Ou gerar manualmente o hash ou corrigir o que está sendo gerado pelo componente.

Segue em anexo os arquivos (xml) do lote (gerado pelo componente) e do retorno do web service.

 

7-env-lot-sinc.xml 7-lista-nfse-sinc.xml

  • Consultores
Postado

Boa tarde Felipe,

Na Unit ISSDSF.GravarXml mais precisamente na function GerarXml você encontra as linhas que monta a string chamada sAssinatura.

Você pode conferir com o seu algoritmo e fazer as devidas correções na Unit.

A minha duvida é se não vai gerar algum efeito colateral para outras cidades que utilizam o mesmo provedor.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Boa tarde Ítalo.

Deu certinho a sua dica, vlw msm. Eu só não alterei a unit ISSDSF.GravarXml. Na verdade, bastou depurar ela e descobrir a propriedade que estava com o valor errado.

Era a NFSe.Servico.Valores.ValorServicos, estava zerado. E o correto é atribuir a ela o valor total dos itens dos serviços daquele RPS.

Ficou agora só as 4 recusas que eu vou ter q ver com o cliente, prq aí já é coisa dele e da prefeitura.

Só vou te pedir para não trancar ainda o tópico pois, eu preciso resolver essas 4 recusas e testar o envio novamente.

Mais uma vez obrigado Ítalo.

  • Curtir 1
  • 3 semanas depois ...
Postado

Bom dia Ítalo.

Consegui, ontem, fazer o envio com sucesso do lote de RPSs para a prefeitura de Uberlândia. Registrou o lote lá e converteu o RPS em NFSe.

Ontem mesmo eu finalizei o uso daquele botão de teste (que também funcionou mas ele não grava o lote na prefeitura e nem converte rps em nfse) e em seguida enviei o lote através do botão 'Emitir Nota (Novo)', achei ele interessante pois permite que o próprio webservice decida o tipo de envio (síncrono ou assíncrono).

Depois disso percebi que não gerou o xml da NFSe. Estudando o manual do webservice da prefeitura de Uberlândia, vi que eu tinha que consultar as nfses pelo número (método ConsultaNota no webservice) para que o próprio webservice envie esse xml de resposta, do método, que já é a NFSe que eu estava esperando.

Analisando os botões da aba 'Consulta' do exemplo da acbr, vi que o que mais se encaixava no que eu queria era o botão 'Consultar NFSe por numero' porém, ao clicar nele vi que está com erro. Aparentemente na função de consulta os parâmetros de datas estão vindo como null mas, não consegui identificar o problema. Poderiam verificar por favor. Vou enviar em anexo, um print do erro no memo de log.

OBS: Utilizando o botão 'Consultar NFSe por RPS' funciona e é retornado o xml da NFSe. Mas creio que é interessante também utilizar a consulta pelo número da nota.

 

ErroConsultarNFSePorNumero.PNG

Postado

Boa tarde Ítalo.

Atualizei os fontes, inclusive deu um conflito no Frm_ACBrNFSeX.pas ... aí preferi dar um revert e pegar o que está no servidor.

Dei um update em toda a pasta acbr, só que agora quando eu vou abrir o formulário, parece que está faltando uma propriedade no componente ACBrNFSeX.

Vou te enviar os prints ... Eu consigo até compilar o programa mas não consigo abrir o formulário.

Erro1.PNG

Erro2.PNG

  • Este tópico foi criado há 1043 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.