Jump to content

Utilizar Webservices da AT


cjulio
Go to solution Solved by thoga31,

Recommended Posts

Boas pessoal sou novo a programar em PHP e tenho tido problemas em conseguir por o módulo da AT a funcionar.

Mas penso que o meu problema poderá estar relacionado com o facto de no pedido eu não enviar o certificado "TesteWebservices".

Alguém me pode dar um exemplo de como o posso fazer? E já agora uma pergunta os campos H1 e H3 tém de ser válidos não pode

ser algo de teste?

Abraço

Boas,

Em relação aos campos do username e password, não vai funcionar sem que o NIF seja real e o sub utilizador exista (e a pass correcta obviamente). Tem lógica, pois o servidor tem que verificar se o documento já existe. Além disso, é necessário para fazer a autenticação com o sub-utilizador.

Também não custa nada, vais aos portal das finanças, crias um sub utilizador e usas estas informações para mandar nos headers. Se usares o servidor de testes, isto não importar quantos documentos envies.. não fica registado na bd fiscal.

Quanto ao método de adicionar o certificado digital à mensagem soap, não te posso ajudar. Não tenho experiência nenhuma sobre isso em php.

Cumps.

Link to comment
Share on other sites

Bem, ao menos dá o erro -99 🙂

Eu não tenho a certeza, mas penso que quando foi inserido o campo InvoiceStatus, se manda-se-mos 2 vezes o mesmo documento mas um com "N" e outro com "A" no estado do documento, o 2º retornava "Documento duplicado". Se assim era, quer dizer que estão a mexer nisso..

Eles não respondem aos emails!! Coloquei essa questão já no início de Dezembro, novamente no fim do mês, e hoje tornei a mandar, e dizem sempre o mesmo.. relativamente a este tipo de assunto é encaminhado para os serviços competentes. Claro que não mando sempre o mesmo texto 🙂 vou acrescentando outras dúvidas.

Estive a experimentar agora e se enviar um documento já inserido e com estado N dá erro -3 Documento duplicado. Se enviar o mesmo documento com estado A dá erro -99 Erro inesperado ... mas confirmo o que disse, porque nos testes que fiz até 31/12 dava sempre documeto duplicado, quer tivesse estado N e A.

Faz todo o sentido que se possa alterar o estado, senão vai ficar uma fatura registada na AT e o contibuinte pode ter o beneficio fiscal (se for o caso) e na bd da empresa e no SAFT o mesmo documento vai marcado como anulado ...

Vamos ver se eles corrigem isto... até hoje a documentação ainda diz que o campo TaxExemptionReason está dentro da tag Tax (1.7.3.4) quando na verdade tem que ir fora (1.7.4) , isto segundo o WDSL

Link to comment
Share on other sites

Estive a experimentar agora e se enviar um documento já inserido e com estado N dá erro -3 Documento duplicado. Se enviar o mesmo documento com estado A dá erro -99 Erro inesperado ... mas confirmo o que disse, porque nos testes que fiz até 31/12 dava sempre documeto duplicado, quer tivesse estado N e A.

Faz todo o sentido que se possa alterar o estado, senão vai ficar uma fatura registada na AT e o contibuinte pode ter o beneficio fiscal (se for o caso) e na bd da empresa e no SAFT o mesmo documento vai marcado como anulado ...

Vamos ver se eles corrigem isto... até hoje a documentação ainda diz que o campo TaxExemptionReason está dentro da tag Tax (1.7.3.4) quando na verdade tem que ir fora (1.7.4) , isto segundo o WDSL

Boas pmmachado,

Que linguagem estás a usar?

Link to comment
Share on other sites

Ninguem!!!!!!!!!!!!!!!!!!!!!!!!!

??????????????????

Bom dia, sou novo aqui no forum, mas gostaria de parabenizar o ótimo trabalho de todos vcs!!! .

Bom antes de mas nada me deram a missão de criar um modulo para AT!!??, bom tive a ler um bocado a documentação deles e os posts de vcs e fiquem com umas duvidas:

1º como crio o CSR (Certificate Signing Request)?

2º como utilizo o TestesWebservices.pfx disponibilizados por eles ( username,password)

3 º copie uns códigos aqui de vcs (nomeadamente em vb.net) e só me retorna o erro (O servidor remoto devolveu um erro: (500) Erro interno de servidor.) no webresponse fica assim

<?xml version='1.0' ?>
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
 <env:Body>
   <env:Fault>
     <faultcode>env:Client</faultcode>
     <faultstring>Internal Error</faultstring>
   </env:Fault>
 </env:Body>
</env:Envelope>

me ajudem tenho pouco tempo para entregar isso!!

Edited by pmg
GeSHi
Link to comment
Share on other sites

Bom dia, sou novo aqui no forum mas gostaria de vos dar os parabéns pelo excelente trabalho que vocês estão a desenvolver.

Isto sim é o verdadeiro suporte que a AT não está a fornecer.

Eu desenvolvo com java e fui obrigado a aumentar os meu conhecimentos sobre autenticação SSL.

Estou com um dilema que para vocês possa até ser fácil de resolver.

Quando uso a trustStore que o pessoal da AT disponibiliza consigo comunicar com o servidor.

Mas não consigo criar a minha própria trustStore .

Alguém sabe explicar qual o certificado que devo colocar lá dentro e como gerar esta trustStore?

Será que existe outra forma de comunicar com o webservice em causa sem utilizar um trustStore?

se sim podem disponibilizar algum exemplo?

Obrigado.

Link to comment
Share on other sites

Boas pessoal,

Continuam aparecer problemas na comunicação com a AT. Depois de ultrapassada a questão de chamar o certificado.

Uso este código em que chamo o certificado e dou-lhe a password, contudo ocorre este erro "unable to use client certificate (no key found or wrong pass phrase?)"

Alguém me pode ajudar e explicar o porquê deste erro e como resolver?

$soap = curl_init();

       curl_setopt($soap, CURLOPT_SSLCERT ,  "C:\wwwroot\www-php\projects\foxfact\TestesWebservices.pfx" );
       curl_setopt($soap, CURLOPT_SSLKEY ,  "TESTEwebservice" );
       curl_setopt($soap, CURLOPT_SSLVERSION, 3);
       curl_setopt($soap, CURLOPT_URL, trim($url));
       curl_setopt($soap, CURLOPT_CONNECTTIMEOUT, 20);
       curl_setopt($soap, CURLOPT_TIMEOUT,        15);
       curl_setopt($soap, CURLOPT_RETURNTRANSFER, true);
       curl_setopt($soap, CURLOPT_SSL_VERIFYPEER, false);
       curl_setopt($soap, CURLOPT_SSL_VERIFYHOST, false);
       curl_setopt($soap, CURLOPT_POST,           true);
       curl_setopt($soap, CURLOPT_POSTFIELDS,     $this->xml);
       curl_setopt($soap, CURLOPT_HTTPHEADER,     $this->headers);

       $result = curl_exec($soap);

       if (curl_errno($soap) > 0) {
           $result = array('errocurl' => curl_errno($soap), 'msgcurl' => curl_error($soap));
           echo curl_error($soap);
           // $result = false;
       }

       curl_close($soap);

       return $result;
Link to comment
Share on other sites

Bom dia a todos (está bué cedo) mas estou desde as 5 da manhã para resolver as coisas agora me dar o seguinte erro!!! está identificado mas não sei onde estou errando



<?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><faultcode>8 </faultcode><faultstring>Rejected: | Codigo: 8 | Erro: Nonce: Não foi possível decifrar o campo | Tentativas Restantes: -1</faultstring><detail>fews.gdcontfsimpostosqua</detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
Edited by apocsantos
geshi
Link to comment
Share on other sites

Bom dia pessoal,

hoje estou a fazer mais alguns testes e pela primeira vez tentei inserir uma fatura com o NIF internacional.

Como tem sido hábito neste processo, nada é facil .... e embora a documentação indique que deve preencher um dos campos <CustomerTaxID> OU <InternationalCustomerTaxID> ao enviar um xml com o <InternationalCustomertaxID> devolve um erro a dizer que falta o campo <CustomerTaxID>, ou seja o NIF do cliente nacional ....

particle 3.1: in element {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceElem of type {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceType, found <InternationalCustomerTaxID> (in default namespace), but next item should be any of [CustomerTaxID, {http://servicos.portaldasfinancas.gov.pt/faturas/}InternationalCustomerTaxID]

Ora bem ... se tem NIF internacional não pode ter NIF nacional ...

já experimentei colocar a tag no NIF nacional com o número 0 mas também dá erro e a branco também e não faz sentido colocar as duas tags pq os campos são mutuamente exclusivos...

Alguém já inseriu um documento com NIF Internacional ??

Link to comment
Share on other sites

Bom dia pessoal,

hoje estou a fazer mais alguns testes e pela primeira vez tentei inserir uma fatura com o NIF internacional.

Como tem sido hábito neste processo, nada é facil .... e embora a documentação indique que deve preencher um dos campos <CustomerTaxID> OU <InternationalCustomerTaxID> ao enviar um xml com o <InternationalCustomertaxID> devolve um erro a dizer que falta o campo <CustomerTaxID>, ou seja o NIF do cliente nacional ....

particle 3.1: in element {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceElem of type {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceType, found <InternationalCustomerTaxID> (in default namespace), but next item should be any of [CustomerTaxID, {http://servicos.portaldasfinancas.gov.pt/faturas/}InternationalCustomerTaxID]

Ora bem ... se tem NIF internacional não pode ter NIF nacional ...

já experimentei colocar a tag no NIF nacional com o número 0 mas também dá erro e a branco também e não faz sentido colocar as duas tags pq os campos são mutuamente exclusivos...

Alguém já inseriu um documento com NIF Internacional ??

Para NIF estrangeiro é colocado assim:

<S:Body>
<ns2:RegisterInvoiceElem xmlns:ns2="http://servicos.portaldasfinancas.gov.pt/faturas/">
 <TaxRegistrationNumber>123456789</TaxRegistrationNumber>
 <ns2:InvoiceNo>FT 1/011</ns2:InvoiceNo>
 <ns2:InvoiceDate>2013-01-11</ns2:InvoiceDate>
 <ns2:InvoiceType>FT</ns2:InvoiceType>
 <ns2:InvoiceStatus>N</ns2:InvoiceStatus>
 <ns2:InternationalCustomerTaxID>
  <TaxIDNumber>123456789</TaxIDNumber>
  <TaxIDCountry>ES</TaxIDCountry>
 </ns2:InternationalCustomerTaxID>
 <Line>
  ...

O erro que dizes:

particle 3.1: in element {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceElem of type {http://servicos.portaldasfinancas.gov.pt/faturas/}RegisterInvoiceType, found <InternationalCustomerTaxID> (in default namespace), but next item should be any of [CustomerTaxID, {http://servicos.portaldasfinancas.gov.pt/faturas/}InternationalCustomerTaxID]

não quer dizer que o campo a seguir tem que ser o CustomerTaxID, mas sim que o campo seguinte é um de dois: CustomerTaxID ou o tipo definido no WSDL InternationalCustomerTaxID.

Cumps.

Edited by RaulLima
Link to comment
Share on other sites

Mais uma vez, um pequeno mas importante pormenor ... é que <CustomerTaxID> funcionava bem e o <InternationalCustomerTaxID> precisa de ter antes o namespace e tinha-me escapado isso ... tem que ser:

<CustomerTaxID>

OU

<ns2:InternationalCustomerTaxID>

<TaxIDNumber>123456789</TaxIDNumber>

<TaxIDCountry>ES</TaxIDCountry>

</ns2:InternationalCustomerTaxID>

Agora ainda fica pendente a alteração do estado de N para A quando se anula um documento ....

Obrigado RaulLima.

Link to comment
Share on other sites

Bom dia a todos (está bué cedo) mas estou desde as 5 da manhã para resolver as coisas agora me dar o seguinte erro!!! está identificado mas não sei onde estou errando



<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/%22><SOAP-ENV:Header/>-<SOAP-ENV:Body>-<SOAP-ENV:Fault><faultcode>8 </faultcode><faultstring>Rejected: | Codigo: 8 | Erro: Nonce: Não foi possível decifrar o campo | Tentativas Restantes: -1</faultstring><detail>fews.gdcontfsimpostosqua</detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Olá grbabus.

Presumo que estejas a usar o endereço https://servicos.portaldasfinancas.gov.pt:400/fews/faturas, certo? Ou seja, o definitivo.

Eu também estou a usar este endereço e estou precisamente com o mesmo problema.

Já conseguiste resolver? Penso ser algo com o certificado e/ou com a chave pública que gerei a partir do ficheiro .cer que eles me enviaram após submissão do CSR.

Não percebo.

Carlos Matos

Carlos Matos 💪

Link to comment
Share on other sites

Boas olha eu aqui outra vez , agora me aconteceu uma coisa estranha mudei o endereço de envio para o de testes ("https://servicos.portaldasfinancas.gov.pt:700/fews/faturas") com o certificado de testes e deu o mesmo erro que descrevi logo mais cedo :Rejected: | Codigo: 8 | Erro: Nonce: Não foi possível decifrar o campo

Já não entendo o que tem de errado !!!

Link to comment
Share on other sites

Bom dia,

Os documentos com estado "A" já não dão erro inesperado (-99). Já dá para inserir documentos anulados.

Contudo, os developers da AT parece que não estão a ligar puto para o que "nós" povo dizemos. Ora vejamos: um documento que já tenha sido inserido, mas se trocarmos apenas o InvoiceStatus, retorna um novo erro (-97) com a descrição "O documento já foi registado pelo emitente com o estado normal / anulado." Para eles já não se trata de um (-3) "Documento duplicado" mas sim que o documento já foi enviado, mas com um estado diferente com que enviamos da primeira vez.

AT rula mesmo!!! lol

Cumps.

Link to comment
Share on other sites

Alo me ajudem !! continuo com o erro 8 de que não consegue descodificar o Nonce ( no de testes usando o certificado de teste)

meu Xml:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<wss:Security xmlns:wss="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wss:UsernameToken>
<wss:Username>263253732/0001</wss:Username>
<wss:Password>2bAJGtVmUsacsit1eul2fQ==</wss:Password>
<wss:Nonce>DX8IkRGGYWJeE+Jer0qzyAsp9VFtGG4XL4FeKKv5YGzzvkbFsRx9aWcJ0CrHwXRWFOaXWcn2Fz7Uy4yyhwXxPSwbeTyCTP6HcalHcgWpTBmMmyEoPokPMzfkatQS7Gxgl6TQSwB8vmBiBVx6a8eR4gel4sno/Hmv+152XzJ9bbyJps1o4Tf6wjzReyeEFs2jI6mlB59tVRrp7iztSa7rbELhiDNM+8OB/Ojj28EJBlWb9RI3AU2GVp6Yp1Qgt63FiPNyVnjDDet6R2dVgS61RDkmevW+RW4SGK/gGl8cAgRhj7WtxA+sI4zmpRY1NNuEBmBqmgkQj9P4wjYDOUEjfw==</wss:Nonce>
<wss:Created>AGOMioRbLNFT+5Pis6hgLMTDb39lC5Hs4sAWu1nqCpM=</wss:Created>
</wss:UsernameToken>
</wss:Security>
</S:Header>
<S:Body>
<ns2:RegisterInvoiceElem xmlns:ns2="http://servicos.portaldasfinancas.gov.pt/faturas/">
<TaxRegistrationNumber>599999993</TaxRegistrationNumber>
<ns2:InvoiceNo>- /1</ns2:InvoiceNo>
<ns2:InvoiceDate>2012-05-05</ns2:InvoiceDate>
<ns2:InvoiceType>FT</ns2:InvoiceType>
<ns2:InvoiceStatus>N</ns2:InvoiceStatus>
<CustomerTaxID>299999998</CustomerTaxID>
<Line>
<ns2:DebitAmount>100</ns2:DebitAmount>
<ns2:Tax>
<ns2:TaxType>IVA</ns2:TaxType>
<ns2:TaxCountryRegion>PT</ns2:TaxCountryRegion>
<ns2:TaxPercentage>23</ns2:TaxPercentage>
</ns2:Tax>
</Line>
<DocumentTotals>
<ns2:TaxPayable>23</ns2:TaxPayable>
<ns2:NetTotal>100</ns2:NetTotal>
<ns2:GrossTotal>123</ns2:GrossTotal>
</DocumentTotals>
</ns2:RegisterInvoiceElem>
</S:Body>
</S:Envelope>

a função para encriptar peguei um exemplo aqui de vcs!!

Dim CaminhoChavePublica As String = "c:\chave\TestesWebServices.pfx" '"c:\chave\certo.cer" '
 ' Variaveis a encriptar
 Dim PassFinancas As String = "TESTEwebservice"
 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, PassFinancas, X509KeyStorageFlags.DefaultKeySet)
 Dim ChavePublica As String = certCP.PublicKey.Key.ToXmlString(False)
 Dim aleatorios As New Random()

 Dim ChaveSimetrica(15) As Byte

 aleatorios.NextBytes(ChaveSimetrica)

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

 ' 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 = System.Convert.ToBase64String(msPassFinancas.ToArray())
 encryptPass = PassFinancasEncriptada
 Dim DataCriacaoEncriptada As String = System.Convert.ToBase64String(msDataCriacao.ToArray())
 encryptDate = DataCriacaoEncriptada
 ' 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 = System.Convert.ToBase64String(Chave)
 rsaPublicKey = ChaveSimetricaEncriptada

já a dias que não passo desse ponto lol por favor me ajudem

Link to comment
Share on other sites

Olá grbabus

Para encriptar os campos password, nonce e created tens que usar o a chave pública da AT fornecido como ficheiro .cer e não o certificado .pfx.

Na primeira linha do teu código tens isso asteriscado e pelos vistos já esteve correcto e depois alteraste. Neste caso, não precisas da pass do certificado de testes das financas.

Deve ser q coisa assim:

Dim CaminhoChavePublica As String = "c:\chave\certo.cer"
	 ' Variaveis a encriptar
	 'xxx Dim PassFinancas As String = "TESTEwebservice"
	 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)
	 ...

Verifica e diz qq coisa.

Link to comment
Share on other sites

Bom dia,

Os documentos com estado "A" já não dão erro inesperado (-99). Já dá para inserir documentos anulados.

Contudo, os developers da AT parece que não estão a ligar puto para o que "nós" povo dizemos. Ora vejamos: um documento que já tenha sido inserido, mas se trocarmos apenas o InvoiceStatus, retorna um novo erro (-97) com a descrição "O documento já foi registado pelo emitente com o estado normal / anulado." Para eles já não se trata de um (-3) "Documento duplicado" mas sim que o documento já foi enviado, mas com um estado diferente com que enviamos da primeira vez.

AT rula mesmo!!! lol

Cumps.

Olá Raul,

Coloquei a questão em relação ao erro que dava quando se tentava enviar um documento com InvoiceStatus a 'S' e eis o que me responderam:

> Tal como no ficheiro SAFT podem ser enviadas faturas anuladas, mas não é possível anular uma fatura que já foi enviada. Se uma fatura tem que ser retificada depois de entregue ao contribuinte só

> pode ser pela emissão duma nota de credito ou nota de debito.

Ou seja, um documento quando é feito, tem que se ter a certeza que está correto e que não houve qualquer engano na sua elaboração, porque depois de este ter sido enviado (e assinado), já não há nada a fazer a não ser anulá-lo com uma nota de débito ou nota de crédito.

O que eu estou a fazer é apenas enviar o documento depois deste ter sido assinado para que não haja incoerências com o SAFT.

Espero ter ajudado.

  • Vote 1

Carlos Matos 💪

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.