galera presciso de alguma forma checar se a chave por exemplo q está no xml está devidamente cadastrada no sefaz, peguei aquela porcaria do projeto NFEphp q é um lixo e só enrola, mta coisa inútil, mta requisição, queria algo mais direto, são notas de terceiros, presciso checar no sefaz pelo WS deles se não foi alterada a nfe, tipo checar os dados do digestvalue se bate com oq está no xml, se alguem puder ajudar, fico grato

Validador De Nf-E
Started By DuuuuDuuuu, 27/08/2011, 10:46
2 replies to this topic
#1
Posted 27/08/2011, 10:46
#2
Posted 28/08/2011, 00:29
Vc tem acesso nisso?
Iniciando na Ajuda On line...
Meu post lhe ajudou? Reputar/votar é uma das formas de agradecer.

#3
Posted 29/08/2011, 10:36
como assim acesso? vc diz a senha e o pass pra se conectar no web services, na verdade eu to procurando mais informações, pois fiquei sabendo q tem uma plataforma de teste pra isso.
olha a uns dias eu to mechendo naquele nfephp q pelo jeito as url dos webservices estão bem ultrapassada, segue o codigo q eu to editando faz uma semana e to com pouco resultado
olha a uns dias eu to mechendo naquele nfephp q pelo jeito as url dos webservices estão bem ultrapassada, segue o codigo q eu to editando faz uma semana e to com pouco resultado
<?php $file = 'nfe.xml'; $chave = '42110875384404000125550040000477231459594050'; function __sendSOAP($urlsefaz,$namespace,$cabecalho,$dados,$metodo,$ambiente,$UF=''){ use_soap_error_handler(true); //versão do SOAP $soapver = SOAP_1_2; //ini_set("soap.wsdl_cache_enabled", "0"); if($ambiente == 1){ $ambiente = 'producao'; } else { $ambiente = 'homologacao'; } //monta a terminação do URL switch ($metodo){ case 'nfeRecepcaoLote2': $usef = "_NFeRecepcao2.asmx"; break; case 'nfeRetRecepcao2': $usef = "_NFeRetRecepcao2.asmx"; break; case 'nfeCancelamentoNF2': $usef = "_NFeCancelamento2.asmx"; break; case 'nfeInutilizacaoNF2': $usef = "_NFeInutilizacao2.asmx"; break; case 'nfeConsultaNF2': $usef = "_NFeConsulta2.asmx"; break; case 'nfeStatusServicoNF2': $usef = "_NFeStatusServico2.asmx"; break; case 'consultaCadastro': $usef = ""; break; } //para os estados de AM, MT e PR é necessário usar wsdl baixado para acesso ao webservice if ($UF=='AM' || $UF=='MT' || $UF=='PR'){ $urlsefaz = "https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx"; } if ($this->enableSVAN){ //se for SVAN montar o URL baseado no metodo e ambiente $urlsefaz = "https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx"; } //verificar se SCAN ou SVAN if ($this->enableSCAN){ //se for SCAN montar o URL baseado no metodo e ambiente $urlsefaz = "https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx"; } //completa a url do serviço para baixar o arquivo WSDL $URL = $urlsefaz.'?WSDL'; $options = array( 'encoding' => 'UTF-8', 'verifypeer' => false, 'verifyhost' => false, 'soap_version' => $soapver, 'style' => SOAP_DOCUMENT, 'use' => SOAP_LITERAL, 'local_cert' => $this->certKEY, 'trace' => true, 'compression' => 0, 'exceptions' => true, 'cache_wsdl' => WSDL_CACHE_NONE ); //instancia a classe soap $oSoapClient = new NFeSOAP2Client($URL,$options); //monta o cabeçalho da mensagem $varCabec = new SoapVar($cabecalho,XSD_ANYXML); $header = new SoapHeader($namespace,'nfeCabecMsg',$varCabec); //instancia o cabeçalho $oSoapClient->__setSoapHeaders($header); //monta o corpo da mensagem soap $varBody = new SoapVar($dados,XSD_ANYXML); //faz a chamada ao metodo do webservices $resp = $oSoapClient->__soapCall($metodo, array($varBody) ); if (is_soap_fault($resp)) { $soapFault = "SOAP Fault: (faultcode: {$resp->faultcode}, faultstring: {$resp->faultstring})"; } $resposta = $oSoapClient->__getLastResponse(); return $resposta; } //fim __sendSOAP function getProtocol($recibo='',$chave='',$tpAmb='',$modSOAP='1'){ //carrega defaults $i = 0; $aRetorno = array('bStat'=>false,'cStat'=>'','xMotivo'=>'','aProt'=>''); $cUF = 'SC'; $UF = 'teste.jpg'; if ($tpAmb != '1' && $tpAmb != '2' ){ $tpAmb = '2'; } //verifica se a chave foi passada if($chave != ''){ //se sim extrair o cUF da chave $cUF = substr($chave,0,2); //testar para ver se é o mesmo do emitente colocar } if ($recibo == '' && $chave == '') { echo 'ERRO. Favor indicar o numero do recibo ou a chave de acesso da NFe!!'; return false; } if ($recibo != '' && $chave != '') { echo 'ERRO. Favor indicar somente um dos dois dados ou o numero do recibo ou a chave de acesso da NFe!!'; return false; } //consulta pelo recibo if ($recibo != '' && $chave == '') { //buscar os protocolos pelo numero do recibo do lote //identificação do serviço $servico = 'NfeRetRecepcao'; //recuperação da versão $namespace = 'http://www.w3.org/2000/09/xmldsig#sha1/wsdl/'.$servico.'2'; //montagem do cabeçalho da comunicação SOAP $cabec = '<nfeCabecMsg xmlns="'.$namespace.'"><cUF>'.$cUF.'</cUF><versaoDados>'.$versao.'</versaoDados></nfeCabecMsg>'; //montagem dos dados da mensagem SOAP $dados = '<nfeDadosMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico2"> <consReciNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="2.00"> <tpAmb>'. $tpAmb.'</tpAmb> <nRec>'.$recibo .'</nRec> </consReciNFe> </nfeDadosMsg>'; //nome do arquivo $nomeArq = $recibo.'-protrec.xml'; } //consulta pela chave if ($recibo == '' && $chave != ''){ //buscar o protocolo pelo numero da chave de acesso //identificação do serviço $servico = 'NfeRetRecepcao'; //recuperação da versão $versao = '2.00'; //recuperação da url do serviço $urlservico = 'https://homologacao.nfe.ms.gov.br/homologacao/services2/NfeRetRecepcao2'; //recuperação do método $metodo = 2; //montagem do namespace do serviço $namespace = 'http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2'; //montagem do cabeçalho da comunicação SOAP $cabec = '<nfeCabecMsg xmlns="'. $namespace . '"><cUF>'.$cUF.'</cUF><versaoDados>'.$versao.'</versaoDados></nfeCabecMsg>'; //montagem dos dados da mensagem SOAP $dados = '<nfeDadosMsg xmlns="'.$namespace.'"> <consSitNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="2.0"> <tpAmb>'.$tpAmb.'</tpAmb> <xServ>CONSULTAR</xServ> <chNFe>'.$chave .'</chNFe> </consSitNFe> </nfeDadosMsg>'; } //envia a solicitação via SOAP $retorno = __sendSOAP($urlservico, $namespace, $cabec, $dados, $metodo, $tpAmb,$UF); //verifica o retorno if ($retorno){ //tratar dados de retorno $doc = new DOMDocument(); //cria objeto DOM $doc->formatOutput = false; $doc->preserveWhiteSpace = false; $doc->loadXML($retorno,LIBXML_NOBLANKS | LIBXML_NOEMPTYTAG); $cStat = !empty($doc->getElementsByTagName('cStat')->item(0)->nodeValue) ? $doc->getElementsByTagName('cStat')->item(0)->nodeValue : ''; if ($cStat == ''){ //houve erro return false; } //o retorno vai variar se for buscado o protocolo ou recibo //Retorno nda consulta pela Chave da NFe //retConsSitNFe 100 aceita 110 denegada 101 cancelada ou outro recusada // cStat xMotivo cUF chNFe protNFe retCancNFe if ($chave != '') { $aRetorno['bStat'] = true; $aRetorno['cStat'] = $doc->getElementsByTagName('cStat')->item(0)->nodeValue; $aRetorno['xMotivo'] = !empty($doc->getElementsByTagName('xMotivo')->item(0)->nodeValue) ? $doc->getElementsByTagName('xMotivo')->item(0)->nodeValue : ''; $infProt = $doc->getElementsByTagName('infProt')->item($i); if(isset($infProt)){ foreach($infProt->childNodes as $t) { $aProt[$i][$t->nodeName] = $t->nodeValue; } } else { $aProt = ''; } $aRetorno['aProt'] = $aProt; //gravar o retorno na pasta temp apenas se a nota foi aprovada ou denegada if ( $aRetorno['cStat'] == 100 || $aRetorno['cStat'] == 110 ){ //nome do arquivo $nomeArq = $chave.'-prot.xml'; $nome = 'teste/'.$nomeArq; $nome = $doc->save($nome); } } //Retorno da consulta pelo recibo //NFeRetRecepcao 104 tem retornos //nRec cStat xMotivo cUF cMsg xMsg protNfe* infProt chNFe dhRecbto nProt cStat xMotivo if ($recibo != ''){ $aRetorno['bStat'] = true; // status do serviço $aRetorno['cStat'] = $doc->getElementsByTagName('cStat')->item(0)->nodeValue; // motivo da resposta (opcional) $aRetorno['xMotivo'] = !empty($doc->getElementsByTagName('xMotivo')->item(0)->nodeValue) ? $doc->getElementsByTagName('xMotivo')->item(0)->nodeValue : ''; if ($cStat == '104'){ //aqui podem ter varios retornos dependendo do numero de NFe enviadas no Lote e já processadas $protNfe = $doc->getElementsByTagName('protNFe'); foreach ($protNfe as $d){ $infProt = $d->getElementsByTagName('infProt')->item($i); $protcStat = $infProt->getElementsByTagName('cStat')->item(0)->nodeValue;//cStat //pegar os dados do protolo para retornar foreach($infProt->childNodes as $t) { $aProt[$i][$t->nodeName] = $t->nodeValue; } $i++; //incluido increment para controlador de indice do array //salvar o protocolo somente se a nota estiver approvada ou denegada if ( $protcStat == 100 || $protcStat == 110 ){ $nomeprot = 'teste/'.$infProt->getElementsByTagName('chNFe')->item(0)->nodeValue.'-prot.xml';//id da nfe //salvar o protocolo em arquivo $novoprot = new DOMDocument('1.0', 'UTF-8'); $novoprot->formatOutput = true; $novoprot->preserveWhiteSpace = false; $pNFe = $novoprot->createElement("protNFe"); $pNFe->setAttribute("versao", "2.00"); // Importa o node e todo o seu conteudo $node = $novoprot->importNode($infProt, true); // acrescenta ao node principal $pNFe->appendChild($node); $novoprot->appendChild($pNFe); $xml = $novoprot->saveXML(); $xml = str_replace('<?xml version="1.0" encoding="UTF-8 standalone="no"?>','<?xml version="1.0" encoding="UTF-8"?>',$xml); $xml = str_replace(array("default:",":default"),"",$xml); $xml = str_replace("\n","",$xml); $xml = str_replace(" "," ",$xml); $xml = str_replace(" "," ",$xml); $xml = str_replace(" "," ",$xml); $xml = str_replace(" "," ",$xml); $xml = str_replace(" "," ",$xml); $xml = str_replace("> <","><",$xml); file_put_contents($nomeprot, $xml); } } } $aRetorno['aProt'] = $aProt; //passa o valor de $aProt para o array de retorno $nomeArq = $recibo.'-recprot.xml'; $nome = 'teste/'.$nomeArq; $nome = $doc->save($nome); } } else { echo 'Nao houve retorno Soap verifique a mensagem de erro e o debug!!'; $aRetorno = false; } return $aRetorno; } //fim getProtocol function verifySignatureXML($conteudoXML, $tag){ $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = false; $dom->loadXML($conteudoXML); $tagBase = $dom->getElementsByTagName($tag)->item(0); // validar digest value $tagInf = $tagBase->C14N(false, false, null, null); $tagInf = str_replace(' xmlns:ds="http://www.w3.org/2000/09/xmldsig#"', '', $tagInf); $digestCalculado = base64_encode(sha1($tagInf, true)); $digestInformado = $dom->getElementsByTagName('DigestValue')->item(0)->nodeValue; if ($digestCalculado != $digestInformado){ echo "O conteúdo do XML não confere com o Digest Value.\nDigest calculado [{$digestCalculado}], informado no XML [{$digestInformado}].\nO arquivo pode estar corrompido ou ter sido adulterado."; return false; } return true; } //verifica se o arquivo existe if ( file_exists($file) ){ //carrega a NFe $xml = file_get_contents($file); //testa a assinatura if (verifySignatureXML($xml,'infNFe')){ //como a ssinatura confere, consultar o SEFAZ para verificar se a NF não foi cancelada ou é FALSA //carrega o documento no DOM $xmldoc = new DOMDocument(); $xmldoc->preservWhiteSpace = false; //elimina espaços em branco $xmldoc->formatOutput = false; $xmldoc->loadXML($xml,LIBXML_NOBLANKS | LIBXML_NOEMPTYTAG); $root = $xmldoc->documentElement; $infNFe = $xmldoc->getElementsByTagName('infNFe')->item(0); //extrair a tag com os dados a serem assinados $id = trim($infNFe->getAttribute("Id")); $chave = preg_replace('/[^0-9]/','', $id); $digest = $xmldoc->getElementsByTagName('DigestValue')->item(0)->nodeValue; //ambiente da NFe sendo consultada $tpAmb = $infNFe->getElementsByTagName('tpAmb')->item(0)->nodeValue; //verifica se existe o protocolo $protNFe = $xmldoc->getElementsByTagName('protNFe')->item(0); if (isset($protNFe)){ $nProt = $xmldoc->getElementsByTagName('nProt')->item(0)->nodeValue; } else { $nProt = ''; } //busca o status da NFe na SEFAZ do estado do emitente $resp = getProtocol('',$chave,$tpAmb,'2'); if ($resp['cStat']!='100'){ //ERRO! nf não aprovada echo "NF não aprovada no SEFAZ!! cStat =" . $resp['cStat'] .' - '.$resp['xMotivo'] ; return false; } else { if ( is_array($resp['aProt'][0])){ $nProtSefaz = $resp['aProt'][0]['nProt']; $digestSefaz = $resp['aProt'][0]['digVal']; //verificar numero do protocolo if ($nProt != '') { if ($nProtSefaz != $nProt){ //ERRO !!!os numeros de protocolo não combinam echo "Os numeros dos protocolos não combinam!! nProtNF = " . $nProt . " <> nProtSefaz = " . $nProtSefaz; return false; } //fim teste do protocolo } else { echo "A NFe enviada não comtêm o protocolo de aceitação !!"; } //verifica o digest if ($digestSefaz != $digest){ //ERRO !!!os numeros digest não combinam echo "Os numeros digest não combinam!! digValSEFAZ = " . $digestSefaz . " <> DigestValue = " . $digest; return false; } //fim teste do digest value } else { //o retorno veio como 100 mas por algum motivo sem o protocolo echo "Falha no retorno dos dados, retornado sem o protocolo !! "; return false; } } } else { echo " Assinatura não confere!!"; return false; } //fim verificação da assinatura } else { echo "Arquivo não localizado!!"; return false; } //fim file_exists ?>
1 user(s) are reading this topic
0 membro(s), 1 visitante(s) e 0 membros anônimo(s)