Ir para o conteúdo
cjulio

Utilizar Webservices da AT

Mensagens Recomendadas

abrito    13
abrito
6 horas atrás, nunopicado disse:

 

Obrigado @abrito, já consigo carregar o ficheiro.
O que não consegui foi adicioná-lo no OnBeforePost do TReqResp. Como é que ligaste uma coisa à outra?
Obrigado! ;)

tens que converter o certificado x509 para CERT_CONTEXT do windows

com i2d_X509 e CertCreateCertificateContext que te vai dar o PCCERT_CONTEXT que tanto precisas.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado
Em 16/08/2017 às 16:40, abrito disse:

tens que converter o certificado x509 para CERT_CONTEXT do windows

com i2d_X509 e CertCreateCertificateContext que te vai dar o PCCERT_CONTEXT que tanto precisas.

Obrigado! ;)
Entretanto, já o tenho a bombar sem CapiCOM!

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado

Já agora, lembrando que o ChavePublicaAT.cer expira a 2017-11-18, pelo que por essa altura temos de andar atentos à renovação.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
abrito    13
abrito
Em 18/08/2017 às 17:57, nunopicado disse:

Obrigado! ;)
Entretanto, já o tenho a bombar sem CapiCOM!

Ainda bem, como vez não era tão difícil assim.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado
1 minuto atrás, abrito disse:

Ainda bem, como vez não era tão difícil assim.

Até era, que isto de encriptação para mim é chinês medieval... :D
Mas deste-me uns ponteiros importantes para as pesquisas! Obrigado!

CapiCOM, bon voyage! :cheesygrin:

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado

Não sei se ainda há alguém a usar o meu projecto WS-DLL para a comunicação de guias de transporte por webservice, mas se houver, este post é para esses:

Dado os recentes desenvolvimentos, especialmente tendo em conta a falta de confiança que o status Obsoleto da CapiCOM apresenta, resolvi fazer um update ao projecto, aproveitando para pôr em prática algumas alterações há muito necessárias a nível de estrutura do código.

O projecto mudou de nome, chamando-se agora AtWS, e pode ser encontrado no meu repositório GitHub, aqui: https://github.com/nunopicado/AtWS

As mudanças passaram pela já mencionada CapiCOM, que deixou de ser necessária, pela opcionalidade de existir o ficheiro ChavePublicAT.pem (se não for fornecido, será usada a versão hardcoded), pelo fim de algumas dependências de código de terceiros, como DelphiOnRails, SuperObject e UIB, e pelo uso de interfaces na estrutura, facilitando a alteração de uma qualquer implementação por quem achar que o deva fazer.

A própria chamada à DLL passa por um interface, que será retornado pela chamada e a partir do qual se poderá fazer o envio dos documentos.

Nunca tentei fazer o envio de uma fatura para o WS da AT, apenas documentos de transporte. Não estou certo que funcione, mas é uma possibilidade. De qualquer forma, só documentos de transporte foram testados aqui.

Editado por nunopicado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado

Pessoal, estava aqui a alterar o projecto demo do AtWS para testar a comunicação de faturas também, e usando o XML de exemplo que está no manual de comunicação de faturas, devidamente alterado com os meus dados, e a resposta que me é dada é a seguinte:
 

  <ReturnCode>-1</ReturnCode>
  <ReturnMessage>O NIF do emitente do documento é inválido.</ReturnMessage>

 

Ora, eu usei o meu NIF para o teste, e está a funcionar perfeitamente com documentos de transporte, pelo que a mensagem NIF Inválido é estranha.
Nas permissões do portal, tenho autorização WFA no user, para emitir faturas, pelo que também não seria por aí.

Alguma ideia do que mais possa ser?

 

 

EDIT: Vi aqui no forum pessoal a queixar-se disso em 2015, e pelos vistos é defeito o WS de testes de faturas.

Alguém que esteja a trabalhar com isto em produção pode fazer o teste para confirmar se é mesmo do server?

Editado por nunopicado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Jose Guerreiro    0
Jose Guerreiro
3 minutos atrás, rukako disse:

Alguem está com problemas em comunicar/aceder ao site da AT?

Confirmo,

The underlying connection was closed: An unexpected error occurred on a receive.

Mais alguem?

 

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
iSilva    2
iSilva
7 minutes ago, Jose Guerreiro said:

Confirmo,

The underlying connection was closed: An unexpected error occurred on a receive.

Mais alguem?

 

Yeap...também estou igual.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
JQWERTY    0
JQWERTY
On 4/17/2013 at 8:59 AM, tony.amfo said:

Para criar o pedido em VB.NET

1. Adicionam a Web Reference ao projecto em causa, e será criada a classe "documentosTransporte" e restantes classes associadas;

2. Criam um soap header com o código seguinte:

 


<System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.5420"), _
 System.SerializableAttribute(), _
 System.ComponentModel.DesignerCategoryAttribute("code"), _
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True, [Namespace]:="http://schemas.xmlsoap.org/ws/2002/12/secext"), _
 System.Xml.Serialization.XmlRootAttribute([Namespace]:="http://schemas.xmlsoap.org/ws/2002/12/secext", IsNullable:=False)> _
Partial Public Class Security
	Inherits SoapHeader
	Private usernameTokenField As SecurityUsernameToken
	Public Sub New()
		MyBase.New()
		Me.usernameTokenField = New SecurityUsernameToken
	End Sub
	Public Sub New(ByVal utilizador As String, ByVal senha As String, ByRef criacao As String, ByRef nonce As String)
		Me.New()
		usernameTokenField.Username = utilizador
		usernameTokenField.Password = senha
		usernameTokenField.Nonce = nonce
		usernameTokenField.Created = criacao
	End Sub
	<System.Xml.Serialization.XmlElementAttribute(Order:=0)> _
	Public Property UsernameToken() As SecurityUsernameToken
		Get
			Return Me.usernameTokenField
		End Get
		Set(ByVal value As SecurityUsernameToken)
			Me.usernameTokenField = value
		End Set
	End Property
End Class
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.5420"), _
 System.SerializableAttribute(), _
 System.ComponentModel.DesignerCategoryAttribute("code"), _
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True, [Namespace]:="http://schemas.xmlsoap.org/ws/2002/12/secext")> _
Partial Public Class SecurityUsernameToken
	Private usernameField As String
	Private passwordField As String
	Private nonceField As String
	Private createdField As String
	<System.Xml.Serialization.XmlElementAttribute(Order:=0)> _
	Public Property Username() As String
		Get
			Return Me.usernameField
		End Get
		Set(ByVal value As String)
			Me.usernameField = value
		End Set
	End Property
	<System.Xml.Serialization.XmlElementAttribute(Order:=1)> _
	Public Property Password() As String
		Get
			Return Me.passwordField
		End Get
		Set(ByVal value As String)
			Me.passwordField = value
		End Set
	End Property
	<System.Xml.Serialization.XmlElementAttribute(Order:=2)> _
	Public Property Nonce() As String
		Get
			Return Me.nonceField
		End Get
		Set(ByVal value As String)
			Me.nonceField = value
		End Set
	End Property
	<System.Xml.Serialization.XmlElementAttribute(Order:=3)> _
	Public Property Created() As String
		Get
			Return Me.createdField
		End Get
		Set(ByVal value As String)
			Me.createdField = value
		End Set
	End Property
End Class
 

 

3. Adicionam a propriedade do header na classe "documentosTransporte" criada pelo WSDL:

 


	Private _security As GENERIC.Security
	Public Property SecurityToken() As GENERIC.Security
		Get
			Return _security
		End Get
		Set(ByVal value As GENERIC.Security)
			_security = value
		End Set
	End Property
 

 

4 - Adicionam a TAG ao método de evocação com a indicação da propriedade do header :

 


<System.Web.Services.Protocols.SoapHeader("SecurityToken")> _
 

 

ou seja, como resultado:

 


	'''<remarks/>
	<System.Web.Services.Protocols.SoapHeader("SecurityToken")> _
	<System.Web.Services.Protocols.SoapDocumentMethodAttribute("https://servicos.portaldasfinancas.gov.pt:701/sgdtws/documentosTransporte/", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Bare)> _
	Public Function envioDocumentoTransporte(<System.Xml.Serialization.XmlElementAttribute([Namespace]:="https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/")> ByVal envioDocumentoTransporteRequestElem As StockMovement) As <System.Xml.Serialization.XmlElementAttribute("envioDocumentoTransporteResponseElem", [Namespace]:="https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/")> StockMovementResponse
		Dim results() As Object = Me.Invoke("envioDocumentoTransporte", New Object() {envioDocumentoTransporteRequestElem})
		Return CType(results(0), StockMovementResponse)
	End Function
 

 

5 - Instanciar a classe StockMovement, carregar os dados e evocar o método "envioDocumentoTransporte" da classe "documentosTransporte"

ATENÇÂO: neste caso, estou a alterar a classe gerada pela ferramenta, o que na prática não é muito aconselhado, contudo, tratando-se apenas de adicionar uma propriedade, representa um grande ganho de tempo face ao uso de outros métodos (trace extensions) para adicionar o header...

Abraço a Todos.

Esta abordagem ajudou-me bastante no processo :), e está a funcionar no servidor de testes. 

Quem seguir esta abordagem, não se esqueçam que têm de adicionar uma "web reference" e não um "service reference".

Na minha abordagem criei um novo ficheiro que é partial da classe  "documentosTransporte" e um novo método para realizar o pedido à At (no código abaixo como "Enviar") para permitir adicionar o atributo ao método. Com esta abordagem não altero a classe gerada pela ferramenta.

Importante: Para efetuar o pedido à At utilizo o novo método "Enviar"!

 

public partial class documentosTransporte
    {
        public Security SecurityToken { get; set; }

        /// <remarks/>
        [System.Web.Services.Protocols.SoapHeader("SecurityToken")]
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("envioDocumentoTransporteResponseElem", Namespace = "https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/")]
        public StockMovementResponse Enviar([System.Xml.Serialization.XmlElementAttribute(Namespace = "https://servicos.portaldasfinancas.gov.pt/sgdtws/documentosTransporte/")] StockMovement envioDocumentoTransporteRequestElem)
        {  
            object[] results = this.Invoke("Enviar", new object[] {
                envioDocumentoTransporteRequestElem});
            return ((StockMovementResponse)(results[0]));
        }
    }

 

Editado por JQWERTY

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
paulofreitas05    0
paulofreitas05

Boas, nãos sei se esta minha questão já foi respondida aqui no fórum mas pelo que pesquisei não me pareceu.

O webservice das finanças tem alguma forma de conseguir validar o login antes de eu guardar no meu software através do webservice fornecido por eles?? 

 

Obrigado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado
43 minutos atrás, paulofreitas05 disse:

Boas, nãos sei se esta minha questão já foi respondida aqui no fórum mas pelo que pesquisei não me pareceu.

O webservice das finanças tem alguma forma de conseguir validar o login antes de eu guardar no meu software através do webservice fornecido por eles?? 

Tanto quanto sei, não...

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Rodrigo Gomes    0
Rodrigo Gomes

Ora boas,

Já a muito que sigo este forum e têm me ajudado bastante.

Mas deparei me com uma situação,

No android não estou a ser capaz de pedir o código a AT para os documentos de transporte via Webservice.

Retorna sempre o erro nr 8 "Nonce: Cifra da chave pública inválida"

e nao consigo entender o porque.

Pedia ajuda a quem já programou esta parte no android se me podia dar umas luzes ;)

esta parte de código é usada no campo nonce

1 para gerar a chave simétrica

2 retorna a chave publica da AT

3 encripta o nonce com a chave publica

Tenho exatamente o mesmo código numa aplicação java e funciona ( a unica diferença é o Base64.encode) onde na aplicação java utilizo 


            final byte[] encriptedSimetricKey = cypherRequestKey((PublicKey) publicKey, simetricKey);
            final String b64EncryptedSimetricKey = new BASE64Encoder().encodeBuffer(encriptedSimetricKey);

 

public static byte[] geraChaveSimetrica() {
        try {
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            gen.init(128);
            SecretKey key = gen.generateKey();
            return key.getEncoded();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Key getPublicKeyFromKeystore(Context mContext) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, InvalidKeyException, NoSuchProviderException, SignatureException, InvalidKeySpecException, NoSuchPaddingException {
        InputStream fin = mContext.getAssets().open("ChavePublicaAT.cer");
        CertificateFactory f = CertificateFactory.getInstance("X509");
        X509Certificate certificate = (X509Certificate) f.generateCertificate(fin);
        PublicKey pk = certificate.getPublicKey();
        return pk;
    }

    public static byte[] cypherRequestKey(PublicKey publicKey, byte[] requestKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, NoSuchProviderException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(requestKey);
    }


            byte[] encryptedSimetricKey = cypherRequestKey(publicKey, simetricKey);
            b64EncryptedSimetricKey = new String(Base64.encode(encryptedSimetricKey, Base64.DEFAULT));

 

Editado por Rodrigo Gomes
Update

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
derrerter    8
derrerter
1 hora atrás, Azurem disse:

Cumprimentos a todos.

Desculpem se a pergunta já foi feitas mas aqui vai:

Como posso listar mais de 300 aqui https://faturas.portaldasfinancas.gov.pt/consultarDocumentosAdquirente.action, ou qual será a melhor forma para o fazer?

Obrigado

Sim, foi feita e muitas vezes.

Resposta rápida, não podes.

Podes é sacar 300 muitas vezes. Ciclos diários, semanais ou como lhe apetecer.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
nunopicado    1069
nunopicado

Pessoal, estou com uma dúvida existencial... :P
 

DGITA Issuing CA1 / DGITA Root CA

As dúvidas são (olha, afinal são duas):

  • Quem emite isto? Qual a autoridade de certificação em Portugal responsável por este root certificate?
  • É legal exportar e distribuir este certificado raíz?

 

Editado por nunopicado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
joaquimpais    0
joaquimpais

Guias dos Açores.

Desde a mudança de hora quer tive que fazer uma mudança na hora de saída das Guias, tive que acrescentar uma hora para conseguir obter código caso contrário daa sempre hora de saída já passou será apenas considerada uma mera comunicação à AT.

Eu estou a enviar a hora no Formato ToUniversalTime().

Já vi aqui no forum que passaram pela mesma situação como resolveram?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade