Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Envío de registros y sus respuestas (https://www.clubdelphi.com/foros/forumdisplay.php?f=66)
-   -   ¿Como enviar facturas al web service? (https://www.clubdelphi.com/foros/showthread.php?t=97180)

Jarogo08 24-01-2025 12:54:30

¿Como enviar facturas al web service?
 
Buenos días a todos


Estoy peleándome con el web service del Verifactu y quería preguntar como estáis haciendo para enviar los registros de facturas.


En un código que está anclado en el foro vi que lo que se manda es el xml, pero me gustaría saber si es la única manera o hay algo parecido el envío en el SII, que puedes enviar el "objeto" SuministroLRFacturasEmitidas que construyes (en el caso del Verifactu sería el objeto "RegFactuSistemaFacturacion")


El código que vi para enviar al Verifactu:


Código:

  Dim webRequest As HttpWebRequest = CType(Net.WebRequest.Create("...prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP"), HttpWebRequest)
        webRequest.ContentType = "text/xml;charset=""utf-8"""
        webRequest.Accept = "text/xml"
        webRequest.Method = "POST"

        webRequest.ClientCertificates.Add(certificate)

        Using stream As Stream = webRequest.GetRequestStream()
          doc.Save(stream)        'EN ESTE DOC ESTÁ EL XML
        End Using

        Dim response As HttpWebResponse = CType(webRequest.GetResponse(), HttpWebResponse)
        Dim statusDescription As String = response.StatusDescription
        Dim dataStream As Stream = response.GetResponseStream()
        Dim responseFromServer As String

        Using reader As StreamReader = New StreamReader(dataStream)
            responseFromServer = reader.ReadToEnd()
            reader.Close()
            dataStream.Close()
            response.Close()
        End Using

El código que uso para enviar al SII:
Código:

        Dim Ws As WSEmitidas.siiSOAPClient = New WSEmitidas.siiSOAPClient("SuministroFactEmitidasPruebas", New EndpointAddress("...prewww1.aeat.es/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP"))
        Ws.Endpoint.Binding = binding
        Ws.ClientCredentials.ClientCertificate.Certificate = certifikat
        Dim RespuestaEnvioFactura As RespuestaLRFEmitidasType = Ws.SuministroLRFacturasEmitidas(ObjetoFacturaEmitida)
        MsgBox(RespuestaEnvioFactura.EstadoEnvio)

Muchas gracias a todos de antemano por la ayuda

Neftali [Germán.Estévez] 24-01-2025 13:45:07

En este mensaje tienes un programa de ejemplo "completo" que ha publicado un forero (seccion_31) que incluye el envío del fichero utilizando HTTPRio.
El código fuente está disponible en Github, puedes revisarlo.


El código simplificado es algo así:

Código Delphi [-]
      // --> envío pre-produccion:  'https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP';
      try
          HTTPRIO1.HTTPWebNode.ClientCertificate.SerialNum := Buscar_Certificado_SERIAL( comboCertificados.text );  // coloca el certificado
          direccion_envio := editURL.text;
          if sender=soloXML then HTTPRIO1.Tag:=1                                                                             // 0-envio  1-generar XML
                            else HTTPRIO1.Tag:=0;                                                                            // 0-envio  1-generar XML
          res:=   RespuestaRegFactuSistemaFacturacionType.Create;
          res:=   GetsfPortTypeVerifactu( false, direccion_envio , HTTPRIO1 ).RegFactuSistemaFacturacion( veriFactu );        // enviarlo !
          // resultado del envio:   (se colocara el csv si la factura ha sido aceptada, en la base de datos: facturas.xml)
          procesarEnvio(res);
      except
            on E:Exception do
                  memoRes.text  :=Format('Error al realizar el envío; (%s)-%s',[E.ClassName, E.Message]);
      end;

gcqZW 24-01-2025 14:03:08

Si no me equivoco, se debería poder hacer de ambas maneras, generando tú el XML a mano o pasando por la función "RegFactuSistemaFacturacion", yo personalmente monto el XML a mano por ahora, pero como te dice neftali échale un ojo al github que te aclarará mas que cualquier respuesta.

Jarogo08 24-01-2025 14:20:15

Gracias a ambos por las respuestas.


Es que estaba montando el objeto "RegFactuSistemaFacturacion" (como la hacía en el SII)
Código:


Dim objectoFactEmitida As RegFactuSistemaFacturacion = New WSVerifactu.RegFactuSistemaFacturacion

objectoFactEmitida.Cabecera = New CabeceraType
objectoFactEmitida.Cabecera.ObligadoEmision = New PersonaFisicaJuridicaESType
objectoFactEmitida.Cabecera.ObligadoEmision.NombreRazon = "AAAA"
objectoFactEmitida.Cabecera.ObligadoEmision.NIF = "BBBB"
objectoFactEmitida.Cabecera.Representante = New PersonaFisicaJuridicaESType
objectoFactEmitida.Cabecera.Representante.NombreRazon = "CCCC"
....

y una vez que terminé quería enviarlo al web service, pero no encuentro la manera. Sí que lo conseguí comunicar una factura enviando un xml, pero quería asegurarme si es la única manera.


Porque al convertir el objeto "RegFactuSistemaFacturacion" al xml lo monta regular: las etiquetas no comienzan por "<sum:" o "<sum1:" y me dice que el xml es incorrecto. Si lo edito a mano poniendo los "sum " me funciona, pero es un poco rollo.


También puedo olvidarme del objeto "RegFactuSistemaFacturacion" y montarlo a mano como dices, pero me parece más engorroso, quería agotar todas las vías antes


Probaré lo que me decís a ver si avanzo algo


Muchas gracias!

Neftali [Germán.Estévez] 24-01-2025 14:54:35

Revisa los mensajes existentes.
Ya hay muchos hablando del envío, donde puedes ver código.

rci 24-01-2025 15:29:22

Cita:

Empezado por Jarogo08 (Mensaje 561419)
Gracias a ambos por las respuestas.


Es que estaba montando el objeto "RegFactuSistemaFacturacion" (como la hacía en el SII)
Código:


Dim objectoFactEmitida As RegFactuSistemaFacturacion = New WSVerifactu.RegFactuSistemaFacturacion

objectoFactEmitida.Cabecera = New CabeceraType
objectoFactEmitida.Cabecera.ObligadoEmision = New PersonaFisicaJuridicaESType
objectoFactEmitida.Cabecera.ObligadoEmision.NombreRazon = "AAAA"
objectoFactEmitida.Cabecera.ObligadoEmision.NIF = "BBBB"
objectoFactEmitida.Cabecera.Representante = New PersonaFisicaJuridicaESType
objectoFactEmitida.Cabecera.Representante.NombreRazon = "CCCC"
....

y una vez que terminé quería enviarlo al web service, pero no encuentro la manera. Sí que lo conseguí comunicar una factura enviando un xml, pero quería asegurarme si es la única manera.


Porque al convertir el objeto "RegFactuSistemaFacturacion" al xml lo monta regular: las etiquetas no comienzan por "<sum:" o "<sum1:" y me dice que el xml es incorrecto. Si lo edito a mano poniendo los "sum " me funciona, pero es un poco rollo.


También puedo olvidarme del objeto "RegFactuSistemaFacturacion" y montarlo a mano como dices, pero me parece más engorroso, quería agotar todas las vías antes


Probaré lo que me decís a ver si avanzo algo


Muchas gracias!

Si que puedes enviar el objeto directamente usando las clases que se generan al importar el wsdl

Este código c# lo encontré en este foro, de algún compañero:

Código:

var basicbinding = new BasicHttpsBinding();
basicbinding.Name = "sfVerifactu";
basicbinding.Security.Mode = BasicHttpsSecurityMode.Transport;
basicbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
basicbinding.MaxReceivedMessageSize = 100 * 1024 * 1024;
var service = new sfPortTypeVerifactuClient(basicbinding, new EndpointAddress(new Uri(url)));
service.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(certificate);
RespuestaRegFactuSistemaFacturacionType wsResponse = wsResponse = service.RegFactuSistemaFacturacion(objectoFactEmitida);

Espero que te sirva, seguro que puedes adaptarlo a tu lenguaje fácilmente ;)

Jarogo08 26-01-2025 22:45:43

Cita:

Empezado por rci (Mensaje 561424)
Si que puedes enviar el objeto directamente usando las clases que se generan al importar el wsdl

Este código c# lo encontré en este foro, de algún compañero:

Código:

var basicbinding = new BasicHttpsBinding();
basicbinding.Name = "sfVerifactu";
basicbinding.Security.Mode = BasicHttpsSecurityMode.Transport;
basicbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
basicbinding.MaxReceivedMessageSize = 100 * 1024 * 1024;
var service = new sfPortTypeVerifactuClient(basicbinding, new EndpointAddress(new Uri(url)));
service.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(certificate);
RespuestaRegFactuSistemaFacturacionType wsResponse = wsResponse = service.RegFactuSistemaFacturacion(objectoFactEmitida);

Espero que te sirva, seguro que puedes adaptarlo a tu lenguaje fácilmente ;)

Muchas gracias por el código, lo voy a probar. ¿podrías indicarme de que hilo lo sacaste? porque por más que he buscado no lo encontré

gcqZW 27-01-2025 08:51:17

Cita:

Porque al convertir el objeto "RegFactuSistemaFacturacion" al xml lo monta regular: las etiquetas no comienzan por "<sum:" o "<sum1:" y me dice que el xml es incorrecto. Si lo edito a mano poniendo los "sum " me funciona, pero es un poco rollo.
Me pasaba lo mismo, yo lo que hacía era un replace de las etiquetas para que quedaran con sum y sum1, pero vamos que al final me monte una función que me componía el xml a partir de un array por que me daba problemas la otra manera.

Jarogo08 27-01-2025 13:27:59

Cita:

Empezado por gcqZW (Mensaje 561449)
Me pasaba lo mismo, yo lo que hacía era un replace de las etiquetas para que quedaran con sum y sum1, pero vamos que al final me monte una función que me componía el xml a partir de un array por que me daba problemas la otra manera.


Si no lo consigo de otra manera tendré que tirar por ahí, pero me parece mucho más cómo crear y mandar el objeto RegFactuSistemaFacturacion.


Seguiré investigando y si lo consigo lo pongo aquí


Muchas gracias igualmente!

rci 27-01-2025 14:00:29

Cita:

Empezado por Jarogo08 (Mensaje 561443)
Muchas gracias por el código, lo voy a probar. ¿podrías indicarme de que hilo lo sacaste? porque por más que he buscado no lo encontré

Hola Jarogo08 ahora no encuentro donde lo vi pero he encontrado este otro post que creo que te puede ayudar:
https://www.clubdelphi.com/foros/sho...postcount=3119

También te podría ser útil revisar los ejemplos publicados en el post #2:
https://www.clubdelphi.com/foros/showthread.php?t=95235

Saludos

Jarogo08 29-01-2025 09:26:51

Conseguido
 
Buenas a todos


al final lo conseguí, pongo aquí el código por si puede ayudarle a alguien más:


Código:

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

        Dim ws As sfVerifactu = New WSVerifactu.sfVerifactu
        ws.ClientCertificates.Add(certificate)
        ws.Url = "https : // prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP"  'quitar los espacios

        Dim RespuestaEnvioFactura As WSVerifactu.RespuestaRegFactuSistemaFacturacionType = ws.RegFactuSistemaFacturacion(objectoFactEmitida)

        MsgBox(RespuestaEnvioFactura.EstadoEnvio & "/" & RespuestaEnvioFactura.RespuestaLinea.Length)

        For x As Integer = 0 To RespuestaEnvioFactura.RespuestaLinea.Length - 1
            MsgBox(RespuestaEnvioFactura.RespuestaLinea(x).IDFactura.NumSerieFactura.ToString & ": " & RespuestaEnvioFactura.RespuestaLinea(x).CodigoErrorRegistro & " - " & RespuestaEnvioFactura.RespuestaLinea(x).DescripcionErrorRegistro)
        Next

Tenía mal la URL en el app.config y por eso no me funcionaba


Gracias a todos por la ayuda


La franja horaria es GMT +2. Ahora son las 02:53:23.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi