dúvidas NFE(nota fiscal eletrônica)

blz pessoal?

Aqui na empresa em que trabalho iremos desenvolver um sistema que irá consumir os webservices da Sefaz para podermos consultar notas fiscais eletrônicas. Iremos realizar apenas consultas para saber se a nota está ativa, etc. Portanto não iremos gerar notas fiscais.

Esse é o primeiro projeto que fazemos que tem relação com nfe. Li alguns documentos do site da secretaria da fazenda e vários posts aqui do fórum mas ainda não está claro para mim o que precisamos para implementar de fato.

Algumas dúvidas:

1-precisamos de um certificado A1 ou de um e-CNPJ ? ou precisamos dos 2 ?
2-Posso usar algum certificado de teste só para testar os webservices da Sefaz antes de adquirir um ?
3-com o certificado A1 em mãos preciso instalar ele onde? No sistema operacional, na JVM, no Tomcat, no browser ?
4-alguém poderia por favor escrever todos passos que devemos seguir para consumirmos os webservices da Sefaz? pode ser tipo um checklist só para servir de diretriz e sabermos tudo que precisaremos fazer.

A princípio preciso dessas informações. Qualquer ajuda é bem-vinda. Se tiverem alguns links úteis postem ai também.

Obrigado.

Tem um tutorial referente à geração do keystore, que é onde você vai precisar deixar seu certificado, talvez ele clarifique as coisas pra você

http://www.makerportal.com.br/?p=361

Respondendo:

1 - Para emitir a nota vc precisa de um certificado especificio para Nfe (podendo ser o tipo A1), para somente consulta não sei se o e-CNPJ serve.

2 - Infelizmente não existem certificados para testes, vc irá precisar do certificado proprio.

3 - O certificado A1 pode ser instalado no SO e acessado pelo aplicativo, ou pode ser utilizado diretamente pelo aplicativo passando-se o caminho dele. (normalmente *.cer)

4- Neste link existe exemplos do uso dos webservices, deve te ajudar. http://www.javac.com.br/jc/posts/list/997-projeto-nfe-cte-cce-comece-por-aqui.page

[]'s

Bom dia,

Compramos o certificado A1. Como instalo ele no SO ? Minha máquina é Linux Ubuntu.

O certificado que tenho é um .pfx. Li em alguns lugares que parece que tem que converter para .pem ou .p12 para rodar no Linux, isso procede?

Obrigado.

Você não precisa instalar, pode usar diretamente o .pfx, segue uma classe de exemplo, você precisará fazer algo parecido para utilizar seu certificado: [code]package br.com.nfe;

import java.security.Security;

public class NFeSSL{

private static final String CAMINHO_CERTIFICADO = "CAMINHO DO SEU ARQUIVO .pfx";
private static final String SENHA_CERTIFICADO = "SENHA DO SEU CERTIFICADO";
private static final String CAMINHO_ARQUIVO_CACERTS = "ARQUIVO CACERTS PARA O ESTADO DO SERVIÇO";

public static void configurar(){
	
	System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
	Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

	System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");

	System.clearProperty("javax.net.ssl.keyStore");
	System.clearProperty("javax.net.ssl.keyStorePassword");
	System.clearProperty("javax.net.ssl.trustStore");

	System.setProperty("javax.net.ssl.keyStore", CAMINHO_CERTIFICADO);
	System.setProperty("javax.net.ssl.keyStorePassword", SENHA_CERTIFICADO);

	System.setProperty("javax.net.ssl.trustStoreType", "JKS");
	System.setProperty("javax.net.ssl.trustStore", CAMINHO_ARQUIVO_CACERTS);
	
}

}[/code]

valeu pela resposta, mas para pegar o wsdl do site da fazenda não tenho que instalar o certificado no browser ou no SO ? Como pego o wsdl ?

Por exemplo esse link não acessa:
https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx?WSDL

“The page requires a client certificate”

Depois que pegar o wsdl eu uso a classe que postou, certo?

valeu!

[quote=bruno_r_santana]valeu pela resposta, mas para pegar o wsdl do site da fazendo não tenho que instalar o certificado no browser ou no SO ? Como pego o wsdl ?

Por exemplo esse link não acessa:
https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx?WSDL

“The page requires a client certificate”

Depois que pegar o wsdl eu uso a classe que postou, certo?

valeu![/quote]
Ah sim, isso é verdade. :slight_smile:
Não sei como configurar no Ubuntu.

Olá,

Eu li esses links:
http://www.guj.com.br/java/233156-certificados-a1-e-a3---funciona-em-linux-ubuntu
http://www.dvdadvdr.com/forums/showthread.php?t=67676

Vi em um dos links que converteram o .pfx em .p12. No outro link fala que pode-se importar um certificado com extensão .p12 no Firefox ao contrário de um .pfx. Então converti o meu arquivo .pfx para .p12 com os seguintes comandos:

openssl pkcs12 -in certificado.pfx -out certificado.pem
openssl pkcs12 -export -in certificado.pem -inkey certificado.pem -out certificado.p12

Esse comando aqui não funcionou para mim para converter em .p12:
openssl pkcs12 -export -chain -CAfile certificado.pem -in certificado.pem -out certificado.p12

Como não tinha nem idéia de como importar o certificado no OS eu importei o certificado .p12 no Firefox mas não acessou a url do wsdl:

https://homologacao.nfe.fazenda.sp.gov.br/nfeweb/services/NfeRecepcao2.asmx?WSDL

Aparece a mensagem:

The page requires a client certificate
The page you are attempting to access requires your browser to have a Secure Sockets Layer (SSL) client certificate that the Web server will recognize. The client certificate is used for identifying you as a valid user of the resource.

Please try the following:

Contact the Web site administrator if you believe you should be able to view this directory or page without a client certificate, or to obtain a client certificate.
If you already have a client certificate, use your Web browser's security features to ensure that your client certificate is installed properly. (Some Web browsers refer to client certificates as browser or personal certificates.)

HTTP Error 403.7 - Forbidden: SSL client certificate is required.
Internet Information Services (IIS)

Technical Information (for support personnel)

Go to Microsoft Product Support Services and perform a title search for the words HTTP and 403.
Open IIS Help, which is accessible in IIS Manager (inetmgr), and search for topics titled About Certificates, Using Certificate Trust Lists, Enabling Client Certificates, and About Custom Error Messages.

==========================

Detalhe, importando o certificado .pfx no Windows e no Internet Explorer consegui acessar a url do wsdl. Porém precisa fazer rodar aqui na minha máquina que é Linux. Alguém sabe o que mais posso tentar?

Abraço.

Bom dia,

Nesse link http://thiagofranca78.blogspot.com.br/2012/02/cadeia-de-certificados-da-sefaz-sp-sera.html li algo sobre cadeias de certificados, mas não consegui entender se preciso instalar isso e nem achei o link de onde baixar. Será que é essa a causa do problema que reportei na minha última mensagem?

obrigado.

Pessoal,

Vou descrever o que fiz até agora. No Linux instalei o certificado no Firefox conforme mencionei anteriormente mas não consegui acessar o wsdl pelo browser então nem tentei gerar os stubs no Netbeans, mas se tiverem alguma sugestão de como fazer funcionar no Linux me digam por favor. Criei uma VM Windows e instalei o certificado pfx dando 2 cliques nele e pelo browser consegui acessar o wsdl normalmente. Gerei um client do web service pelo Netbeans e depois criei as 2 classes de exemplo que peguei aqui:

http://www.javac.com.br/jc/posts/list/224-resolvendo-o-problema-4037-forbidden-para-certificado-a1-protocolsocketfactory.page

Alterei o código fonte do arquivo NFeStatusServicoFactoryDinamicoA1 colocando um XML de teste para tentar consumir o serviço NfeStatusServico2. Ao executar a classe aparece na saída do Netbeans:

log4j:WARN No appenders could be found for logger (org.apache.axiom.om.util.StAXUtils).
log4j:WARN Please initialize the log4j system properly.
INFO: 2SP_NFE_PL_006j215Rejeição: Falha no schema XML352012-11-13T15:44:38
CONSTRUÍDO COM SUCESSO (tempo total: 4 segundos)

Já verifiquei diversos links que falam desse problema “Falha no schema XML”. Um deles é esse que fala que tenho que enviar um lote para a fazenda:

http://www.flexdocs.com.br/suporte/knowledgebase.php?article=154

Será que é esse o problema? Alguma sugestão?

Na verdade criei essas classes acima para teste, para me familiarizar com o processo de consumir os webservices da fazenda, mas minha aplicação vai requerer que eu consuma o serviço NfeConsulta2 e não o serviço NfeStatusServico2. Precisarei alterar muita coisa?

Estou no caminho certo pessoal para poder fazer minha app consumir o serviço NfeStatusServico2 ?

Obrigado.

Tenta pegar o corpo da mensagem que o seu codigo esta enviando para o servidor, através dele fica mais facil identificar o que esta indo de errado. Eu tive problemas com schema a um tempo atrás devido namespaces do xml.

[]'s

Bom dia,

Consegui fazer funcionar com essas duas classes, segue código caso alguém mais tenha o mesmo problema:

public class ConsultaNFE {

    private static final int SSL_PORT = 443;

    public static void main(String[] args) {
        try {
            String codigoDoEstado = "35";
            URL url = new URL("https://nfe.fazenda.sp.gov.br/nfeweb/services/nfeconsulta2.asmx");

            String caminhoDoCertificadoDoCliente = "caminho/certificado.pfx";
            String senhaDoCertificado = "senha";
            String arquivoCacertsGeradoTodosOsEstados = "caminho/nfe-cacerts";

            InputStream entrada = new FileInputStream(caminhoDoCertificadoDoCliente);
            KeyStore ks = KeyStore.getInstance("pkcs12");
            try {
                ks.load(entrada, senhaDoCertificado.toCharArray());
            } catch (IOException e) {
                throw new Exception("Senha do Certificado Digital esta incorreta ou Certificado inválido.");
            }

            String alias = "";
            Enumeration<String> aliasesEnum = ks.aliases();
            while (aliasesEnum.hasMoreElements()) {
                alias = (String) aliasesEnum.nextElement();
                if (ks.isKeyEntry(alias)) {
                    break;
                }
            }
            X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);
            PrivateKey privateKey = (PrivateKey) ks.getKey(alias, senhaDoCertificado.toCharArray());
            SocketFactoryDinamico socketFactoryDinamico = new SocketFactoryDinamico(certificate, privateKey);
            socketFactoryDinamico.setFileCacerts(arquivoCacertsGeradoTodosOsEstados);

            Protocol protocol = new Protocol("https", socketFactoryDinamico, SSL_PORT);
            Protocol.registerProtocol("https", protocol);

            /**
             * Xml de Consulta.
             */
         
            String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                    + "<consSitNFe versao=\"2.01\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">"
                    + "<tpAmb>1</tpAmb>"
                    + "<xServ>CONSULTAR</xServ>"
                    + "<chNFe>35120161203931000262550020000260651005925256</chNFe>"
                    + "</consSitNFe>";

            OMElement ome = AXIOMUtil.stringToOM(xml);
            NfeConsulta2Stub.NfeDadosMsg dadosMsg = new NfeConsulta2Stub.NfeDadosMsg();
            dadosMsg.setExtraElement(ome);

            NfeConsulta2Stub.NfeCabecMsg nfeCabecMsg = new NfeConsulta2Stub.NfeCabecMsg();
            /**
             * Código do Estado.
             */
            nfeCabecMsg.setCUF(codigoDoEstado);

            /**
             * Versao do XML
             */
            nfeCabecMsg.setVersaoDados("2.01");
            NfeConsulta2Stub.NfeCabecMsgE nfeCabecMsgE = new NfeConsulta2Stub.NfeCabecMsgE();
            nfeCabecMsgE.setNfeCabecMsg(nfeCabecMsg);

            NfeConsulta2Stub stub = new NfeConsulta2Stub(url.toString());
            NfeConsulta2Stub.NfeConsultaNF2Result result = stub.nfeConsultaNF2(dadosMsg, nfeCabecMsgE);

            info(result.getExtraElement().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void info(String log) {
        System.out.println("INFO: " + log);
    }

    private static void error(String log) {
        System.out.println("ERROR: " + log);
    }
}

[code]
public class SocketFactoryDinamico implements ProtocolSocketFactory {
private SSLContext ssl = null;
private X509Certificate certificate;
private PrivateKey privateKey;
private String fileCacerts;

public SocketFactoryDinamico(X509Certificate certificate,  
        PrivateKey privateKey) {  
    this.certificate = certificate;  
    this.privateKey = privateKey;  
}  

private SSLContext createSSLContext() {  
    try {  
        KeyManager[] keyManagers = createKeyManagers();  
        TrustManager[] trustManagers = createTrustManagers();  
        SSLContext sslContext = SSLContext.getInstance("TLS");  
        sslContext.init(keyManagers, trustManagers, null);  

        return sslContext;  
    } catch (KeyManagementException e) {  
        error(e.toString());  
    } catch (KeyStoreException e) {  
        error(e.toString());  
    } catch (NoSuchAlgorithmException e) {  
        error(e.toString());  
    } catch (CertificateException e) {  
        error(e.toString());  
    } catch (IOException e) {  
        error(e.toString());  
    }  
    return null;  
}  

private SSLContext getSSLContext() {  
    if (ssl == null) {  
        ssl = createSSLContext();  
    }  
    return ssl;  
}  

public Socket createSocket(String host, int port, InetAddress localAddress,  
        int localPort, HttpConnectionParams params) throws IOException,  
        UnknownHostException, ConnectTimeoutException {  
    if (params == null) {  
        throw new IllegalArgumentException("Parameters may not be null");  
    }  
    int timeout = params.getConnectionTimeout();  
    SocketFactory socketfactory = getSSLContext().getSocketFactory();  
    if (timeout == 0) {  
        return socketfactory.createSocket(host, port, localAddress,  
                localPort);  
    }  

    Socket socket = socketfactory.createSocket();  
    SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);  
    SocketAddress remoteaddr = new InetSocketAddress(host, port);  
    socket.bind(localaddr);  
    try {  
        socket.connect(remoteaddr, timeout);  
    } catch (Exception e) {  
        error(e.toString());  
        throw new ConnectTimeoutException("Possível timeout de conexão", e);  
    }  

    return socket;  
}  

public Socket createSocket(String host, int port, InetAddress clientHost,  
        int clientPort) throws IOException, UnknownHostException {  
    return getSSLContext().getSocketFactory().createSocket(host, port,  
            clientHost, clientPort);  
}  

public Socket createSocket(String host, int port) throws IOException,  
        UnknownHostException {  
    return getSSLContext().getSocketFactory().createSocket(host, port);  
}  

public Socket createSocket(Socket socket, String host, int port,  
        boolean autoClose) throws IOException, UnknownHostException {  
    return getSSLContext().getSocketFactory().createSocket(socket, host,  
            port, autoClose);  
}  

public KeyManager[] createKeyManagers() {  
    HSKeyManager keyManager = new HSKeyManager(certificate, privateKey);  

    return new KeyManager[] { keyManager };  
}  

public TrustManager[] createTrustManagers() throws KeyStoreException,  
        NoSuchAlgorithmException, CertificateException, IOException {  
    KeyStore trustStore = KeyStore.getInstance("JKS");  

    trustStore.load(new FileInputStream(fileCacerts), "changeit".toCharArray());  
    TrustManagerFactory trustManagerFactory = TrustManagerFactory  
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());  
    trustManagerFactory.init(trustStore);  
    return trustManagerFactory.getTrustManagers();  
}  

class HSKeyManager implements X509KeyManager {  

    private X509Certificate certificate;  
    private PrivateKey privateKey;  

    public HSKeyManager(X509Certificate certificate, PrivateKey privateKey) {  
        this.certificate = certificate;  
        this.privateKey = privateKey;  
    }  

    public String chooseClientAlias(String[] arg0, Principal[] arg1,  
            Socket arg2) {  
        return certificate.getIssuerDN().getName();  
    }  

    public String chooseServerAlias(String arg0, Principal[] arg1,  
            Socket arg2) {  
        return null;  
    }  

    public X509Certificate[] getCertificateChain(String arg0) {  
        return new X509Certificate[] { certificate };  
    }  

    public String[] getClientAliases(String arg0, Principal[] arg1) {  
        return new String[] { certificate.getIssuerDN().getName() };  
    }  

    public PrivateKey getPrivateKey(String arg0) {  
        return privateKey;  
    }  

    public String[] getServerAliases(String arg0, Principal[] arg1) {  
        return null;  
    }  
}  

public void setFileCacerts(String fileCacerts) {  
    this.fileCacerts = fileCacerts;  
}  

/** 
 * Log Error. 
 * @param log 
 */  
private static void error(String log) {  
    System.out.println("ERROR: " + log);  
}  

} [/code]

Mas ainda gostaria de fazer funcionar no Linux. O problema maior no Linux para mim é a instalação do certificado que não funciona. Se alguém puder ajudar nessa questão eu agradeço.

Obrigado.