Jump to content

Utilizar Webservices da AT


Recommended Posts

Boa Tarde para todos.

Eu sou um completo nabo nisto por isso se as minhas preguntas forem muito disparatadas não levem a mal.

Pelo que encontrei na net no VFP para usar web services tenho que:

1 - Criar um soapEnvelope (alguem tem por ai um de exemplo do conteudo é que pelo http://info.portaldasfinancas.gov.pt/NR/rdonlyres/02357996-29FC-4F11-9F1D-6EA2B9210D60/0/factemiws.wsdl nao consigo descortinar quase nada daquilo).

2 - Fazer open('POST', 'endereço?????' ,.f.) (mas não sei a que endereço).

3 - Fazer setrequestheader('SOAPAction', 'endereço?????') (mas tambem não sei a que endereço).

4 - Fazer setrequestheader('Content-Type','text/xml;charset=UTF-8')

5 - fazer send (soapenvelope).

6 - fazer responsexml.getElementsByTagName('TAGNAME???') (tambem nao sei o que por aqui)

Se alguem poder ajudar....

Obrigado.

Link to comment
Share on other sites

Boa obrigado pela dica já li. e neste momento ja entendi a estrutura.

Estou á espera de uma reposta por parte da AT desde o dia 07-12 sobre o porque é que não consigo submeter nada via webservices tenho instalados os certificados de testes e nada...

Estou a tentar submeter o exemplo que vem no PDF e não dá.

O código actual resumido.

open('POST', 'https://servicos.portaldasfinancas.gov.pt/faturas/' ,.f.)
setrequestheader('SOAPAction', 'https://servicos.portaldasfinancas.gov.pt/faturas/RegisterInvoice')
setrequestheader('Content-Type','text/xml;charset=UTF-8')
send (soapenvelope).
strtofile(responseText, 'responseText.txt')
Link to comment
Share on other sites

Boa noite,

Pelo ambiente de testes disponibilizado pela AT, percebe-se que o serviço está feito em Java.

A minha questao fundamental é saber se consigo fazer um client em .NET (VB) que se consiga conetar ao dito :S

Comecei com WCF's, penso que a parte relativa à encriptação está feita, mas agora tenho sempre um erro maluco ao tentar enviar a fatura. Alguém também está a desenvolver em .NET?

Link to comment
Share on other sites

Fiz agora uma nova aproximação, usando HttbWebRequest e passando a mensagem XML via string.

É preciso adicionar o System.Security às referências.

Basicamente, recebo ja o user, a password encriptada, o nonce e a hora também já encriptados e tento enviar a mensagem. O codigo tem demasiados imports, mas já foram testes e mais testes 🙂

Imports System.IO
Imports System.Reflection
Imports System.Security.Cryptography
Imports System.Text
Imports System.Security.Cryptography.X509Certificates
Imports System.Xml
Imports System.Text.UTF8Encoding
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Net

  Public Function Teste(ByVal User As String, ByVal Password As String, ByVal Nonce As String, ByVal Created As String)

     Try


        Dim store As New X509Store(StoreName.Root, StoreLocation.CurrentUser)
        store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
        Dim certs As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(store.Certificates, "Certificados", "Escolher o certificado Teste Web Services", X509SelectionFlag.SingleSelection)


        Dim request As HttpWebRequest = DirectCast(WebRequest.Create("https://servicos.portaldasfinancas.gov.pt:700/fews/faturas"), HttpWebRequest)
        request.ClientCertificates.Add(certs(0))
        request.Headers.Add("SOAPAction", "http://servicos.portaldasfinancas.gov.pt/faturas/RegisterInvoice")
        request.Method = "POST"
        request.ContentType = "text/xml; charset=utf-8"
        request.Accept = "text/xml"

        Dim requeststr As String = ""
        requeststr = "<S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"">"
        requeststr += "<S:Header>"
        requeststr += "<wss:Security xmlns:wss=""http://schemas.xmlsoap.org/ws/2002/12/secext"">"
        requeststr += "<wss:UsernameToken>"
        requeststr += "<wss:Username>" & User & "</wss:Username>"
        requeststr += "<wss:Password>" & Password & " </wss:Password>"
        requeststr += "<wss:Nonce>" & Nonce & "</wss:Nonce>"
        requeststr += "<wss:Created>" & Created & "</wss:Created>"
        requeststr += "</wss:UsernameToken>"
        requeststr += "</wss:Security>"
        requeststr += "</S:Header>"
        requeststr += "<S:Body>"
        requeststr += "<ns2:RegisterInvoiceElem xmlns:ns2=""http://servicos.portaldasfinancas.gov.pt/faturas/"">"
        requeststr += "<TaxRegistrationNumber>500555333/0001</TaxRegistrationNumber>"
        requeststr += "<ns2:InvoiceNo>FT/1</ns2:InvoiceNo>"
        requeststr += "<ns2:InvoiceDate>2012-05-05</ns2:InvoiceDate>"
        requeststr += "<ns2:InvoiceType>FT</ns2:InvoiceType>"
        requeststr += "<CustomerTaxID>299999998</CustomerTaxID>"
        requeststr += "<Line>"
        requeststr += "<ns2:DebitAmount>100</ns2:DebitAmount>"
        requeststr += "<ns2:Tax>"
        requeststr += "<ns2:TaxType>IVA</ns2:TaxType>"
        requeststr += "<ns2:TaxCountryRegion>PT</ns2:TaxCountryRegion>"
        requeststr += "<ns2:TaxPercentage>23</ns2:TaxPercentage>"
        requeststr += "</ns2:Tax>"
        requeststr += "</Line>"
        requeststr += "<DocumentTotals>"
        requeststr += "<ns2:TaxPayable>23</ns2:TaxPayable>"
        requeststr += "<ns2:NetTotal>100</ns2:NetTotal>"
        requeststr += "<ns2:GrossTotal>123</ns2:GrossTotal>"
        requeststr += "</DocumentTotals>"
        requeststr += "</ns2:RegisterInvoiceElem>"
        requeststr += "</S:Body>"
        requeststr += "</S:Envelope>"


        MsgBox(requeststr)
        Dim utfEncoder As System.Text.UTF8Encoding = New UTF8Encoding()
        Dim requestBytes As Byte() = utfEncoder.GetBytes(requeststr)
        request.ContentLength = requestBytes.Length

        Dim theStream As Stream = request.GetRequestStream()
        theStream.Write(requestBytes, 0, requestBytes.Length)
        theStream.Close()

        Using Response As HttpWebResponse = request.GetResponse()

           MsgBox(Response.Headers.ToString)
           Response.ContentType = "text/xml; charset=utf-8"

           Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
           Dim readStream As New StreamReader(Response.GetResponseStream(), encode)
           Dim results As String = readStream.ReadToEnd()
           Response.Close()
        End Using

     Catch ex As WebException
        Using response As WebResponse = ex.Response
           Dim httpResponse As HttpWebResponse = DirectCast(response, HttpWebResponse)
           MsgBox("Erro: " & httpResponse.StatusCode)
           Using data As Stream = response.GetResponseStream()
              Dim text As String = New StreamReader(data).ReadToEnd()
              MsgBox(text)
           End Using
        End Using
     End Try


  End Function

O problema com isto é que o que recebo é um internal server error, com a seguinte mensagem.

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultstring/>
<detail>fews.gdcontfsimpostos</detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Com a aproximação que fiz em WFC, que refiro no post anterior, tenho exatamente a mesma mensagem.

Alguém tem ideias do que poderá ser?

Link to comment
Share on other sites

Boas,

Tenho estado a desenvolver para PHP, até agora a encriptação e construção do XML está feita mas sempre que tento enviar pelo RegisterInvoice retorna-me sempre "Could not connect to host", o estranho é que consigo fazer a ligação para o Soap e se não enviar algum campo no XML retorna-me erro de campo em falta.

Alguém já conseguiu fazer algum envio em alguma linguagem ?

  • Vote 1
Link to comment
Share on other sites

Viva, estava com o mesmo problema, e enviei email para que mo identificassem (com informação do ip, data e hora do envio).

Recebi agora a resposta (por email) que o erro era:

Rejected: | Codigo: 11 | Erro: Validade da credencial expirada(2012-12-17T18:33:34.661Z) | Tentativas Restantes: -1

É o mesmo erro que dá online no teste do webservice.

Acontece que para pedir o certificado digital, também há problemas no site. Embora exijam 2048 bits no CSR, no site obriga a 1024.

Também para isto já recebi resposta, a dizer que têm conhecimento e que informam assim que esteja corrigido.

Portanto, resta esperar!

Link to comment
Share on other sites

Boas,

Para quem está a desenvolver em PHP e estiver com dificuldades ao efectuar a ligação ao webservice, devem efectuar o SoapClient da seguinte forma:

new SoapClient(NULL, array(
   'local_cert' => CERTIFICADO,
   'passphrase' => PASSWORD_CERTIFICADO,
   'location' => "http://info.portaldasfinancas.gov.pt/NR/rdonlyres/02357996-29FC-4F11-9F1D-6EA2B9210D60/0/factemiws.wsdl",
   'uri' => "https://servicos.portaldasfinancas.gov.pt:700/"
));
Link to comment
Share on other sites

Viva, estava com o mesmo problema, e enviei email para que mo identificassem (com informação do ip, data e hora do envio).

Recebi agora a resposta (por email) que o erro era:

Rejected: | Codigo: 11 | Erro: Validade da credencial expirada(2012-12-17T18:33:34.661Z) | Tentativas Restantes: -1

É o mesmo erro que dá online no teste do webservice.

Acontece que para pedir o certificado digital, também há problemas no site. Embora exijam 2048 bits no CSR, no site obriga a 1024.

Também para isto já recebi resposta, a dizer que têm conhecimento e que informam assim que esteja corrigido.

Portanto, resta esperar!

"Rejected: | Codigo: 11 | Erro: Validade da credencial expirada(2012-12-17T18:33:34.661Z) | Tentativas Restantes: -1"

Verifica de tens a hora correcta no pc onde estás a testar o webservice .... andei muito tempo as voltas com esse erro ao utilizar o teste de webservice da AT e o problema era o facto de ter o relógio do pc atrasado +- 2 minutos em relação à hora oficial (Site do Observatório ... link na página 11 da documentação da AT http://www.oal.ul.pt/index.php?link=acerto)

Verifica a hora e diz se resolveu.

Agora ando às cabeçadas com a chamada ao webservice. Vou acompanhando o tópico e se houver novidades publico aqui. Espero que façam o mesmo se avançarem ....

Link to comment
Share on other sites

E a partir de dia 31 de dez de 2012 como testamos , ainda nao consegui acabar isto ... não mt entendo sobre isto dos certificados ... alguem pode explicar como funciona O que é o NONCE e o ficheiro que eles dão suposto certificado (o suposto certificado que tou a usar nem sei se é um certificado , sem querer apaguei o email que eles enviara, e nao o consigo recuperar , ja pedi novamente) o que faço com ele ... tenho o http com ssl e dou como certificado um ficheiro mas isto resposnde que nao consegue carregar o certificado ( o programa que utilizo para https usa a versao open ssl 096a) alguem pode por aki certificado de amosta ?

Link to comment
Share on other sites

Boas,

Desde já expresso a minha surpresa em encontrar um tópico sobre tema na Internet. É que incrivelmente, a AT não tem prestado apoio praticamente ou até mesmo nenhum. Mas prontos!

Agora em relação ao que me trás aqui:

Já alguém conseguiu inserir um documento com taxa de IVA isenta? Não dá problema nenhum a inserir um e/ou mais taxas de IVA desde que não seja do tipo isenta. Já experimentei tirar o campo do motivo, mas nesse caso dá erro de parâmetros de entrada!! O erro devolvido é totalmente inútil, penso eu:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultstring/>
<detail>fews.gdcontfsimpostos</detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Normalmente apresentava um faultstring a especificar do que se tratava o erro, mas neste caso em particular, nada.

E já agora, mais um pormenor, já alguém sabe como se vão lidar com os documentos anulados?

Cumprimentos,

Raul Lima

Link to comment
Share on other sites

Boa noite RaulLima,

Esse é precisamente o erro que obtenho, do qual espero uma resposta há cerca de 2 semanas por parte da AT para saber o que é. Qual é a plataforma de desenvolvimento que está a usar? Relativamente aos documentos anulados, e dado que não existe na estrutura a enviar nada que defina o estado do documento, assumo que não serão para enviar - não faz sentido enviar um documento do qual a empresa não irá liquidar IVA. Realmente é pena a AT não dar mais atenção a quem está a desenvolver, até porque se formos a ver, na prática há 2 semanas que temos toda a informação necessária para testar as aplicações.

Link to comment
Share on other sites

Bom dia pessoal ... espero que todos tenham tido um Natal Feliz.

Voltamos ao trabalho e aos webservices da AT ... Alguém tem código a funcionar em .net utilizando Service References ?

Com Service References, adiciono o certificado e preencho os dados, mas obtenho o seguinte erro: "Ocorreu um erro ao efectuar o pedido HTTP a https://servicos.portaldasfinancas.gov.pt:700/fews/faturas. Isto pode ser causado pelo facto do certificado do servidor não estar correctamente configurado com HTTP.SYS no caso HTTPS. Isto também pode ser causado por um erro de correspondência do enlace de segurança entre o cliente e o servidor." O que faço é chamar o webservice, mas não tenho como adicionar os dados do SoapHeader Security -> username,password e nonce

Alguém por aí está a usar Service references com sucesso ?

Relativamente ao site de testes, já alguém tem informação se vai continuar a funcionar depois de 31/12/2012 ? vai se preciso outro certificado de testes ...

Cumps.

Link to comment
Share on other sites

Bom dia padrinho,

Eu estou a desenvolver em VB.NET.

Há umas semanas estive em contacto com um sujeito na AT e falei-lhe na questão dos documentos anulados, e o que ele disse é que não tinham pensado nessa situação e que iriam analisar. O problema é que nunca mais me disseram nada.. para variar!

Ora reparem neste caso: eu (cliente) estou a efetuar faturas, e cada vez que finalizo uma, a aplicação envia a fatura eletrónica. Depois de imprimir reparo que tenho uma das linhas com erros, Preciso alterar a fatura. Como não é possível, tenho que anula-la. Até aqui não há problema, pois no SAF-T vai a indicação de que o documento foi anulado. Contudo, a fatura já segui para a AT. É necessário enviar alguma informação para a AT a indicar que esse documento foi anulado. Pois para todos os efeitos, a informação que está nos servidores deles, fica errada.

Eu penso que deveria haver uma forma de atualizar um determinado documento!

pmmachado: Em relação à utilização do webservice usando proxy class, eu digo-te que eu não cheguei a conseguir. Mas como só andei 3 dias à volta disso (no início quando saiu o comunicado em Novembro) e não estava a conseguir comunicar, pus de parte. Pode ter sido por diversas razões, pois na altura ainda não estava a conseguir encriptar correctamente, também não tinha a certeza de que os headers estavam bem definidos, e ainda não tinha a certeza que o certificado estava a ser anexado ou não sei lá!

Ora, depois disto tudo, resolvi criar eu mesmo a mensagem em XML. Pronto, de resto é basicamente usar o código que o padrinho deixou neste tópico. A única diferença para o meu é que eu carrego o certificado do ficheiro, em vez de ser escolhido pelo cliente.

Edited by RaulLima
Link to comment
Share on other sites

Boa tarde a todos,

Reparei ao bocado que saiu uma atualização à definição do webservice ontem. Já contabilizam se o documento está ou não anulado. Contudo ainda precisam de pensar uma forma de atualizar o documento para o estado anulado, pois é uma situação perfeitamente normal que aconteca.

Entretanto, consegui ultrapassar o problema de enviar um documento com IVAs isentos. Ora, o problema está na definição (pdf do comunicado). Eles desde o primeiro dia que cometem erros nesse documento, contudo este é mesmo o cumulo. O nó TaxExemptionReason não pode ser definido dentro do Tax mas sim no Line (no pdf indica que o TaxExemptionReason é o número 1.7.3.4 mas devia ser o nr. 1.7.4). Detetei isto, porque fui analisar as proxy class. E reparei nesse grande pormenor.

Espero que ajude alguém esta dica.

Cumps.

Link to comment
Share on other sites

Boas RaulLima,

realmente estive a rever umas notas que tinha quando analisei o doc da AT e tinha lá riscado o ponto 1.7.3.4 e escrito 1.7.4 porque, tal como tu, tentei utilizar o Service Reference e ao testar as classes criadas verifiquei isso ... boa anotação porque nestas pequenas coisas pode-se perder horas...

sem querer abusar da colaboração, podes avançar com algumas dicas sobre a parte de encriptação para o header ... da At recebemos o certificado e um ficheiro .cer com a chave publica ... tens código que possas partilhar com o pessoal ? não é preguiça ... que o tempo está muito curto.

Cumps,

Link to comment
Share on other sites

Espero que ajude

VB.NET

Dim CaminhoChavePublica As String = "C:\Caminho_Ficheiro_cer\ficheiro.cer"

' Variaveis a encriptar
Dim PassFinancas As String = "123456"
Dim DataCriacao As String = Date.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.ff") & "Z"

' Carregar chave pública
Dim certCP As New X509Certificate2
certCP.Import(CaminhoChavePublica)
Dim ChavePublica As String = certCP.PublicKey.Key.ToXmlString(False)

' Gerar Chave Simétrica para o envio da informação
' Esta chave tem que ser diferente em todos os envios, pelo que deverão arranjar um método de ser sempre diferente
' Comprimento: 16
' Exemplo
' Dim ChaveSimetrica As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
Dim ChaveSimetrica() As Byte = GerarChaveSimetrica()

' Inserir Chave Simetrica nos parametros de encriptação
Dim rijn As SymmetricAlgorithm = SymmetricAlgorithm.Create()
rijn.Key = ChaveSimetrica
rijn.IV = ChaveSimetrica
rijn.Mode = CipherMode.ECB

' Encriptar password das financas
Dim msPassFinancas As New MemoryStream
Dim csPassFinancas As New CryptoStream(msPassFinancas, rijn.CreateEncryptor(rijn.Key, rijn.IV), CryptoStreamMode.Write)
Using swPassFinancas As New StreamWriter(csPassFinancas)
swPassFinancas.Write(PassFinancas)
End Using

' Encriptar data de criação
Dim msDataCriacao As New MemoryStream
Dim csDataCriacao As New CryptoStream(msDataCriacao, rijn.CreateEncryptor(rijn.Key, rijn.IV), CryptoStreamMode.Write)
Using swDataCriacao As New StreamWriter(csDataCriacao)
swDataCriacao.Write(DataCriacao)
End Using

' Converter de bytes para string
Dim PassFinancasEncriptada As String = Convert.ToBase64String(msPassFinancas.ToArray())
Dim DataCriacaoEncriptada As String = Convert.ToBase64String(msDataCriacao.ToArray())

' Encriptar a chave simetrica com o algoritmo RSA e com a chave pública
Dim AlgRSA As New RSACryptoServiceProvider
AlgRSA.FromXmlString(ChavePublica)
Dim Chave() As Byte = AlgRSA.Encrypt(ChaveSimetrica, False)
Dim ChaveSimetricaEncriptada As String = Convert.ToBase64String(Chave)

Cumprimentos

  • Vote 1
  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.