Página 1 de 2
Assinar Rps e Lote na NFSe
Enviado: 28 Jan 2016 09:06
por Eroni
Bom dia a todos,
Alguém já conseguiu fazer mais de uma assinatura no mesmo xml como exigem algumas prefeituras?
Tenho desenvolvido a NFSe para algumas cidades, derivando do projeto HBNFe, mas estou tendo problema ao assinar o rps o lote, já tentei varias opções:
Assinar somente o rps - Ok, assinatura válida, mas o provedor não aceita
Assinar somente o lote - Ok, o provedor aceita, mas ao pegar o retorno, retorna mensagem de rejeição por falta de assinatura no rps
Assinar os dois separadamente e depois juntar em um só xml. A assinatura fica inválida. Tanto o validador de assinaturas da receita quanto o provedor rejeitam.
Tanto o rps assinado individualmente quanto e o lote assinado individualmente são aceitos pelo validador da receita, isto quer dizer que a assinatura em si é válida, acho que o problema é que quando vai ser assinado o xml, a assinatura é feita somente no rps, pois o mesmo está antes do local reservado para o lote, pode ser na hora de posicionar a tag correta para a assinatura, alguém sabe como fazer isso?
O projeto está sendo portado para vários provedores, quando estiver pronto pretendo disponibilizar aqui.
Abraços a todos.
Assinar Rps e Lote na NFSe
Enviado: 28 Jan 2016 10:24
por JoséQuintas
Esse tipo de pergunta já passou por aqui.
a nota é algo como <nfe>sdfdsdd</nfe>
o lote é algo como <lote>dsfsfsdfd<nfe>..</nfe><nfe></nfe></lote>
é uma assinatura dentro de cada bloco <nfe>, e depois uma assinatura no bloco <lote>
Para a rotina de assinatura é passada a URI que indica o bloco a ser assinado.
Sua rotina de assinatura precisa tratar diferente quando o bloco for <nfe> ou quando o bloco for <lote>
Confirme na rotina de assinatura como é obtida a posição para o bloco <Signature>
Assinar Rps e Lote na NFSe
Enviado: 28 Jan 2016 10:51
por Eroni
Obrigado pela resposta José.
A posição obtida é assim:
xmldsig:signature := oDOMDoc:selectSingleNode( './/ds:Signature' )
Mas não sei se está correto, o xml é o abaixo:
<?xml version="1.0"?><EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/nfse.xsd"><LoteRps Id="lote220" versao="1.00">
<NumeroLote>220</NumeroLote>
<Cnpj>19337655000188</Cnpj>
<InscricaoMunicipal>09340450014</InscricaoMunicipal>
<QuantidadeRps>1</QuantidadeRps>
<ListaRps>
<Rps>
<InfRps Id="RPS1">
<IdentificacaoRps>
<Numero>1</Numero>
<Serie>1</Serie>
<Tipo>1</Tipo>
</IdentificacaoRps>
<DataEmissao>2016-01-26T10:38:58</DataEmissao>
<NaturezaOperacao>1</NaturezaOperacao>
<RegimeEspecialTributacao>6</RegimeEspecialTributacao>
<OptanteSimplesNacional>1</OptanteSimplesNacional>
<IncentivadorCultural>2</IncentivadorCultural>
<Status>1</Status>
<Servico>
<Valores>
<ValorServicos>100.00</ValorServicos>
<ValorDeducoes>0.00</ValorDeducoes>
<ValorPis>0.00</ValorPis>
<ValorCofins>0.00</ValorCofins>
<ValorInss>0.00</ValorInss>
<ValorIr>0.00</ValorIr>
<ValorCsll>0.00</ValorCsll>
<IssRetido>1</IssRetido>
<ValorIss>2.79</ValorIss>
<OutrasRetencoes>0.00</OutrasRetencoes>
<Aliquota>0.0279</Aliquota>
<DescontoIncondicionado>0.00</DescontoIncondicionado>
<DescontoCondicionado>0.00</DescontoCondicionado>
</Valores>
<ItemListaServico>17.19</ItemListaServico>
<CodigoTributacaoMunicipio>171900188</CodigoTributacaoMunicipio>
<Discriminacao>CONTABILIDADE SERVICO </Discriminacao>
<CodigoMunicipio>3106200</CodigoMunicipio>
</Servico>
<Prestador> <Cnpj>19337655000188</Cnpj> <InscricaoMunicipal>09340450014</InscricaoMunicipal></Prestador>
<Tomador> <IdentificacaoTomador> <CpfCnpj> <Cnpj>04280451000180</Cnpj> </CpfCnpj> <InscricaoMunicipal>01641950010</InscricaoMunicipal> </IdentificacaoTomador> <RazaoSocial>TEC SOLUCOES CORPORATIVAS LTDA</RazaoSocial> <Endereco> <Endereco>RUA ADALBERTO FERRAZ</Endereco> <Numero>42</Numero> <Bairro>LAGOINHA</Bairro> <CodigoMunicipio>3106200</CodigoMunicipio> <Uf>MG</Uf> <Cep>31210020</Cep> </Endereco>
</Tomador>
</InfRps>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#RPS1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo></KeyInfo>
</Signature>
</Rps>
</ListaRps>
</LoteRps>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#lote220">
<Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envel ... <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>
</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo></KeyInfo>
</Signature>
</EnviarLoteRpsEnvio>
Alguma idéia de onde preciso modificar?
Grato.
Assinar Rps e Lote na NFSe
Enviado: 28 Jan 2016 11:34
por Kapiaba
bom dia Eroni, use este leitor de XML, para validar o seu .XML.
https://leitorxmlnfe.websiteseguro.com/
Veja se esse serve para você também:
http://www.semx.com.br/
Abs
Assinar Rps e Lote na NFSe
Enviado: 28 Jan 2016 11:43
por JoséQuintas
1. Separar cada nota, e assinar cada nota
2. Juntar tudo como está aí
3. Assinar o lote.
A assinatura:
A rotina de assinatura costuma gerar a assinatura preenchida, e precisa trocar o bloco de assinatura vazio, pelo da assinatura preenchida.
Acabei de acrescentar a última linha aqui mas não testei, serve como base de comparação pras diversas assinaturas:
Código: Selecionar todos
aDelimitadores := { ;
{ "<enviMDFe", "</MDFe></enviMDFe>" }, ;
{ "<eventoMDFe", "</eventoMDFe>" }, ;
{ "<eventoCTe", "</eventoCTe>" }, ;
{ "<infMDFe", "</MDFe>" }, ;
{ "<infCte", "</CTe>" }, ;
{ "<infNFe", "</NFe>" }, ;
{ "<infDPEC", "</envDPEC>" }, ;
{ "<infInut", "<inutNFe>" }, ;
{ "<infCanc", "</cancNFe>" }, ;
{ "<infInut", "</inutNFe>" }, ;
{ "<infEvento", "</evento>" }, ;
{ "<infPedidoCancelamento", "</Pedido>" }, ; // NFSE ABRASF Cancelamento
{ "<infRps", "</Rps>" }, ; // NFSE ABRASF
{ "<LoteRps", "</EnviarLoteRpsEnvio>" } } // Lote NFSE
Nota: supondo que realmente sejam necessárias duas assinaturas.
Assinar Rps e Lote na NFSe - Resolvido
Enviado: 28 Jan 2016 13:02
por Eroni
Obrigado ao Kapi e ao José pelas dicas, mas o xml está ok, testei inclusive pelo link que o kapi mencionou.
Quanto ao procedimento descrito pelo José, é o que eu havia fazendo, porém o provedor recusa com a mensagem de assinatura inválida.
Se eu assinar somente o lote o provedor recebe, porém ao pegar o retorno também há a recusa de falta de assinatura no rps, então, infelizmente, é obrigatório as duas assinaturas, em todos os exemplos de manuais que eu vi constam duas assinaturas.
O problema é fazer a assinatura de um documento só em dois locais, esse é o ponto que está a dificuldade.
Assinar Rps e Lote na NFSe
Enviado: 02 Fev 2016 10:06
por Eroni
Resolvido com a mudança no processo de pegar o bloco de assinatura, alternando-se entre os nodes de assinaturas. Se alguém passar pelo mesmo problema entre em contato para mais detalhes.
Abraço a todos.
Assinar Rps e Lote na NFSe
Enviado: 02 Fev 2016 12:39
por JoséQuintas
Olhei de novo a rotina, e eu tinha invertido a análise.
Com a inversão, sempre ia considerar nota, e a assinatura iria entrar na primeira nota.
https://github.com/JoseQuintas/sefazclass
Nota: A rotina não assina nota dentro de lote. Precisa fazer cada nota individualmente, e só no final juntar tudo e assinar o lote.
Assinar Rps e Lote na NFSe
Enviado: 17 Nov 2017 17:47
por quelps
Boa tarde Eroni, estou com o mesmo o problema na assinatura do RPS e do LoteRPS, estou fazendo a assinatura pelo Capicom.
tem como vc passar um exemplo de como vc fez para conseguir as duas assinaturas no mesmo XML?
Assinar Rps e Lote na NFSe
Enviado: 17 Nov 2017 18:15
por JoséQuintas
Estou tentando entender, porque parece que a segunda parte desta rotina não serve pra nada com uma assinatura, mas estraga se tiver várias assinaturas.
Não lembro porque a coloquei.
Código: Selecionar todos
STATIC FUNCTION AssinaAjustaAssinado( cXml )
LOCAL nPosIni, nPosFim, nP, nResult
cXml := StrTran( cXml, Chr(10), "" )
cXml := StrTran( cXml, Chr(13), "" )
nPosIni := At( [<SignatureValue>], cXml ) + Len( [<SignatureValue>] )
cXml := Substr( cXml, 1, nPosIni - 1 ) + StrTran( Substr( cXml, nPosIni, Len( cXml ) ), " ", "" )
nPosIni := At( [<X509Certificate>], cXml ) - 1
nP := At( [<X509Certificate>], cXml )
nResult := 0
DO WHILE nP <> 0
nResult := nP
nP := hb_At( [<X509Certificate>], cXml, nP + 1 )
ENDDO
nPosFim := nResult
cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )
RETURN cXml
Esta parte aqui:
Código: Selecionar todos
nPosIni := At( [<X509Certificate>], cXml ) - 1
nP := At( [<X509Certificate>], cXml )
nResult := 0
DO WHILE nP <> 0
nResult := nP
nP := hb_At( [<X509Certificate>], cXml, nP + 1 )
ENDDO
nPosFim := nResult
cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )
E na primeira parte, seria trocar At() por Rat(), assim pega a última assinatura, e não a primeira.
Assinar Rps e Lote na NFSe
Enviado: 17 Nov 2017 18:27
por JoséQuintas
Sinceramente não lembro se tem utilidade.... rs
Na dúvida, achei um meio-termo:
usei hb_At() pra achar o último bloco de <SignatureValue> e a partir daí vai fazer o mesmo processo de antes.
Desse jeito, não faz diferença pra uma assinatura, mas faz se tiverem várias assinaturas no XML, porque só vai mexer na última, que seria do lote.
Código: Selecionar todos
STATIC FUNCTION AssinaAjustaAssinado( cXml )
LOCAL nPosIni, nPosFim, nP, nResult
cXml := StrTran( cXml, Chr(10), "" )
cXml := StrTran( cXml, Chr(13), "" )
nPosIni := RAt( [<SignatureValue>], cXml ) + Len( [<SignatureValue>] )
cXml := Substr( cXml, 1, nPosIni - 1 ) + StrTran( Substr( cXml, nPosIni, Len( cXml ) ), " ", "" )
nPosIni := hb_At( [<X509Certificate>], cXml, nPosIni ) - 1
nP := nPosIni + 1
nResult := 0
DO WHILE nP <> 0
nResult := nP
nP := hb_At( [<X509Certificate>], cXml, nP + 1 )
ENDDO
nPosFim := nResult
IF nPosIni > 0 .AND. nPosFim > 0
cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )
ENDIF
RETURN cXml
Testar a compilação e subir pro github.
Assinar Rps e Lote na NFSe
Enviado: 17 Nov 2017 18:29
por JoséQuintas
Acho que por aqui fica mais nítido o que foi alterado.
https://github.com/JoseQuintas/sefazcla ... bac7ea53ee
Assinar Rps e Lote na NFSe
Enviado: 17 Nov 2017 18:41
por JoséQuintas
Aproveitei pra reduzir fonte..... rs
Eu criava nResult pra depois colocar em nPosfim... ué... só usar nPosFim de uma vez, pra que outra variável.... rs
Essas coisas é que dá pra gente ver conforme vai dividindo em rotinas menores.
No começo a assinatura era uma rotina gigante.... rs
E retirei o IF que acrescentei antes: nunca vai ser menor que 1, não precisa testar.
https://github.com/JoseQuintas/sefazcla ... 7d851829a2
Assinar Rps e Lote na NFSe
Enviado: 03 Nov 2020 11:01
por sygecom
Eroni escreveu:Resolvido com a mudança no processo de pegar o bloco de assinatura, alternando-se entre os nodes de assinaturas. Se alguém passar pelo mesmo problema entre em contato para mais detalhes.
Abraço a todos.
Eroni, bom dia.
Estou com mesmo problema aqui na NFSe de NATAL-RN, poderia postar um exemplo de como resolveu ou como resolveu ?
Assinar Rps e Lote na NFSe
Enviado: 03 Nov 2020 11:28
por JoséQuintas
Geralmente usamos At() pra achar o bloco de assinatura, isso pega o primeiro bloco.
Normal, já que cada nota tem seu próprio bloco.
No caso do lote, já vai existir uma assinatura da nota, então tem que usar Rat() pra localizar o último bloco que é do lote.
Se não fizer isso, vai pegar bloco da nota e não do lote.
Aliás... talvez melhor pegar sempre o último, já que quando só tem um, tanto faz se pesquisar a partir do início ou do final.