Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   TICKET BAI (TicketBAI); Nuevo sistema de la Agencia Tributaria del Pais Vasco (https://www.clubdelphi.com/foros/showthread.php?t=94264)

canfora 20-05-2021 11:04:56

PHP Envío a TBAI GIP
 
Buenos días,

Me acabo de poner con la programación en php para el envío de XML a TBAI a Gipuzkoa.
Estoy utilizando el código que sugerís a continuación y recibo en todo momento el siguiente error:
"
No se puede conectar con la TBAI GIP.

Error: unable to use client certificate (no key found or wrong pass phrase?)

Respuesta de la TBAI GIP: 312
"
Tengo un certificado pfx, el cual indico en la línea de declaración del CURLOPT_SSLCERT y añado la siguiente linea:
curl_setopt($soap_do, CURLOPT_SSLCERTPASSWD, $pass);

Si utilizo una conexión más sencilla, como la que indico a continuación, recibo el siguiente error:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $server);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestXML);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

ERROR:
"
01
Rechazado
Baztertua

001
Error: No se ha utilizado certificado de cliente.
Errorea: Ez da erabili bezeroaren ziurtagiririk.
"

Muchísimas gracias por vuestra ayuda.

Cita:

Empezado por bilbur (Mensaje 540774)
Os adjunto lo que tengo hecho para el envío a Gipuzkoa
Este envío es el más sencillo
Más o menos lo que hago es:
  1. Proceso previo o simultáneo a la emisión y firma de la factura
  2. En el directorio donde están las facturas firmadas, creo, si no están, los directorios de Envios y Respuestas.
  3. Si la factura firmada existe en el directorio de facturas firmadas, la envío a TBAI GIP
  4. Me guardo la respuesta y si es afirmativa muevo la factura firmada al directorio de Envios
<div>
Código PHP:

if($hacienda_foral == 'GIP' && $orden_tbai != '000000')     {    
    
$directorio_TBAI $originales."TBAI/".$cif_340."/";
    
$directorio_TBAI_envios $originales."TBAI/".$cif_340."/Envios/";        
    if (!
is_dir($directorio_TBAI_envios))  mkdir($directorio_TBAI_envios0777);
    
$directorio_respuestas $directorio_TBAI.'Respuestas/';   
    if (!
is_dir($directorio_respuestas))  mkdir($directorio_respuestas0777);    

    
$estado_tbai '';
    
$xml_enviado_tbai $orden_tbai.'.xsig';
    
$guardado_enviar_tbai $directorio_TBAI.$xml_enviado_tbai;    
    if (
file_exists($guardado_enviar_tbai)) 
    {    
    
$estado_tbai 'No enviado';
    
$descripcion_TBAI $estado_tbai;
    
$xml file_get_contents($guardado_enviar_tbai);

    
$header_soap = array(
    
"Content-Type: application/xml;charset=utf-8",
    
"Accept: application/xml",
    
"Content-length: ".strlen($xml)
    );

$soap_do curl_init();
curl_setopt($soap_doCURLOPT_URL$url_TBAI );
curl_setopt($soap_doCURLOPT_CONNECTTIMEOUT100);
curl_setopt($soap_doCURLOPT_TIMEOUT,        100);
curl_setopt($soap_doCURLOPT_RETURNTRANSFERtrue);
curl_setopt($soap_doCURLOPT_FOLLOWLOCATIONtrue);
curl_setopt($soap_doCURLOPT_SSL_VERIFYPEERfalse);
curl_setopt($soap_doCURLOPT_SSL_VERIFYHOSTfalse);
curl_setopt($soap_doCURLOPT_USERAGENT'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($soap_doCURLOPT_POST,           true );
curl_setopt($soap_doCURLOPT_SSLCERT,        getcwd().'/_certificandos'.$alias_pdf.'/'.$cif_340.'.pem' );
curl_setopt($soap_doCURLOPT_POSTFIELDS,     $xml);
curl_setopt($soap_doCURLOPT_HTTPHEADER,     $header_soap);

    
$response curl_exec($soap_do);     
    if(!
curl_exec($soap_do)) {
    
$err 'Error: ' curl_error($soap_do);
    
curl_close($soap_do);
    echo 
"<br>No se puede conectar con la TBAI GIP.<br><br>";    
    
print_r($err);
    echo 
"<br>";    
    echo 
"<br><b>Respuesta de la TBAI GIP: 312</b><br><br>";    
    
print_r($response);
    } else {
    
curl_close($soap_do);

    
$response preg_replace('/(<\s*)\w+:/','$1',$response);   // removes <xxx:
    
$response preg_replace('/(<\/\s*)\w+:/','$1',$response); // removes </xxx:
    
$response preg_replace('/\s+xmlns:[^>]+/','',$response); // removes xmlns:...    

    
$use_errors libxml_use_internal_errors(true);    
    
$parser simplexml_load_string($response);
    if (
$parser === false) {
    echo 
"<br>No se puede cargar el fichero xml devuelto por la TBA GIP.<br><br>";
    echo 
"<br>";    
    echo 
"<br><b>Respuesta de la TBAI GIP:</b><br><br>";    
    
print_r($response);
    }
    
libxml_clear_errors();
    
libxml_use_internal_errors($use_errors);    
    if (
$parser === false) exit();
    
$parser->asXML($directorio_respuestas.$orden_tbai.'.xml');
    }

    
$facturas_en_TBAI $parser;
    if (
$facturas_en_TBAI === false)    
    {
    echo 
"<br><b>Respuesta de TBAI parser:</b><br><br>";
    
print_r ($facturas_en_TBAI);
    }
    
$guardado_enviado_tbai $directorio_TBAI_envios.$xml_enviado_tbai;
    
    
$nodo $facturas_en_TBAI->Salida;
    
$Estado $nodo->Estado;    
    if(
$Estado == '00')    
    
rename($guardado_enviar_tbai,$guardado_enviado_tbai); /// atencion a esto
    
unset($facturas_en_TBAI);
    }    
     } 
// if($hacienda_foral == 'GIP') 

</div>Aparte tengo un script para visualizar la respuesta
En este lo más interesante puede ser la generación de la url del mensaje TBAI para verlo como si se tratara del código QR



Código PHP:

<?php

    $directorio_respuestas 
$directorio_TBAI.'Respuestas/';   
    if (!
is_dir($directorio_respuestas))  mkdir($directorio_respuestas0777);
    
$directorio_envios $directorio_TBAI.'Envios/';   
    if (!
is_dir($directorio_envios))  mkdir($directorio_envios0777);
    
    
$estado_tbai '';

    
$xml_enviado_tbai $orden_tbai.'.xsig';    
    
$guardado_enviado_tbai $directorio_envios.$xml_enviado_tbai;    
    if (
file_exists($guardado_enviado_tbai)) 
    
$estado_tbai 'Enviado'; else $estado_tbai 'No enviado';
    
$descripcion_TBAI $estado_tbai;

    if(
$estado_tbai == 'Enviado')
    {    
    
$msg_TBAI '';
    
$xml_actual_enviado simplexml_load_file($guardado_enviado_tbai);    
    
$signatureNodeActual $xml_actual_enviado->children('ds'true)->Signature;    
    
$SignatureValueFirmaFacturaActual $signatureNodeActual->SignatureValue;
    
$SignatureValueFirmaFacturaActual substr($SignatureValueFirmaFacturaActual,0,13);    
    
$factura_tbai_serie  $xml_actual_enviado->Factura->CabeceraFactura->SerieFactura;    
    
$factura_tbai_numero $xml_actual_enviado->Factura->CabeceraFactura->NumFactura;
    
$factura_tbai_fecha  $xml_actual_enviado->Factura->CabeceraFactura->FechaExpedicionFactura;    
    
$factura_tbai_fecha_dd substr($factura_tbai_fecha,0,2);
    
$factura_tbai_fecha_mm substr($factura_tbai_fecha,3,2);    
    
$factura_tbai_fecha_aa substr($factura_tbai_fecha,-2);        
    
$factura_tbai_importe  $xml_actual_enviado->Factura->DatosFactura->ImporteTotalFactura;        
    
$TBAIID  'TBAI'.$caracterSeparador.$cif_340.$caracterSeparador.$factura_tbai_fecha_dd;
    
$TBAIID .= $factura_tbai_fecha_mm.$factura_tbai_fecha_aa.$caracterSeparador;
    
$TBAIID .= $SignatureValueFirmaFacturaActual.$caracterSeparador;
    
$TBAIID utf8_encode($TBAIID);    
    
$cod_crc8 crc8($TBAIID);
    
$TBAIID  $TBAIID.$cod_crc8;
    unset(
$xml_actual_enviado);
    
$msg_TBAI =  $url_TBAI_QR.'?id='.$TBAIID.'&s='.$factura_tbai_serie.'&nf='.$factura_tbai_numero.'&i='.$factura_tbai_importe;
    
$msg_TBAI utf8_encode($msg_TBAI);    
    
$cod_crc8 crc8($msg_TBAI);
    
$msg_TBAI $msg_TBAI.'&cr='.$cod_crc8;    
    
$xml_respuesta $orden_tbai.'.xml';
    
$guardado_respuesta $directorio_respuestas.$xml_respuesta;
    if (
file_exists($guardado_respuesta)) 
    {
    
$respuesta_tbai simplexml_load_file($guardado_respuesta);
    if (
$respuesta_tbai === false) {
    
$estado_tbai 'No se puede leer la respuesta de TBAI';
    } else {
    
$estado_tbai 'Existe respuesta de TBAI';
    }
    } else {
    
$estado_tbai 'No se encuentra la respuesta de TBAI';
    
$sin_respuesta_tbai     '<?xml version="1.0" encoding="UTF-8"?>';
    
$sin_respuesta_tbai    .= '<Salida></Salida>';
    
$respuesta_tbai simplexml_load_string($sin_respuesta_tbai);    
    }
    
$descripcion_TBAI $estado_tbai;

    
$nodo $respuesta_tbai->Salida;
    
$Estado $nodo->Estado;
    
$FechaRecepcion $nodo->FechaRecepcion;

    if(
$Estado == '00')
    {    
    
$IdentificadorTBAI $nodo->IdentificadorTBAI;    
    
$Descripcion $nodo->Descripcion;
    
$Descripcion utf8_decode($Descripcion);
    
$CSV_tbai 'CSV: '.$nodo->CSV;
    
$ResultadosValidacion $nodo->ResultadosValidacion;
    
$CodigoRV $ResultadosValidacion->Codigo;
    if(
$CodigoRV)    
    
$DescripcionRV $errores_envio_TBAI["$CodigoRV"];    
    
$estado_tbai 'Correcto';    
    
$descripcion_TBAI $estado_tbai.': '.$IdentificadorTBAI.' '.$FechaRecepcion.' '.$Descripcion.' '.$CSV_tbai;
    if(
$CodigoRV)
    {    
    
$descripcion_TBAI .= ' '.$CodigoRV.' '.$DescripcionRV;
    
$estado_tbai 'Aviso';    
    }
    }    
    
    if(
$Estado == '01')    
    {
    
$ResultadosValidacion $nodo->ResultadosValidacion;
    
$CodigoRV $ResultadosValidacion->Codigo;
    
$DescripcionRV $errores_envio_TBAI["$CodigoRV"];    
    if(
substr($DescripcionRV,0,5) == 'Aviso' || $CodigoRV == '005' )
    
$estado_tbai 'Aviso';    
    else    
$estado_tbai 'Rechazado';
    
$descripcion_TBAI $estado_tbai.': '.$FechaRecepcion.' '.$CodigoRV.' '.$DescripcionRV;
    }
    unset(
$respuesta_tbai);
    } 
//  enviado

Tengo, si interesa, la generación del código QR para PDF con la libreria fpdf.


Comentamos ...


tejano 20-05-2021 11:35:27

Buenos días,

Estoy con el formato LROE 240 de la DFB.
Sobre el campo "Factura emitida", "TicketBai" hay que codificar el fichero TicketBai en Base64.
El fichero TicketBai al que se refieren que hay que codificar, es el fichero ya firmado, no?

Gracias

Neftali [Germán.Estévez] 20-05-2021 11:38:09

Cita:

Empezado por canfora (Mensaje 541008)
01
Rechazado
Baztertua

001
Error: No se ha utilizado certificado de cliente.
Errorea: Ez da erabili bezeroaren ziurtagiririk.


El error parece claro, no les está llegando el certificado al enviar.

keys 20-05-2021 12:11:08

Cita:

Empezado por tejano (Mensaje 541009)
Buenos días,

Estoy con el formato LROE 240 de la DFB.
Sobre el campo "Factura emitida", "TicketBai" hay que codificar el fichero TicketBai en Base64.
El fichero TicketBai al que se refieren que hay que codificar, es el fichero ya firmado, no?

Gracias

Si hay que enviar el fichero ya firmado.

bilbur 20-05-2021 13:19:07

Cita:

Empezado por canfora (Mensaje 541008)
Buenos días,

Me acabo de poner con la programación en php para el envío de XML a TBAI a Gipuzkoa.
Estoy utilizando el código que sugerís a continuación y recibo en todo momento el siguiente error:
"
No se puede conectar con la TBAI GIP.

Error: unable to use client certificate (no key found or wrong pass phrase?)

Respuesta de la TBAI GIP: 312
"
Tengo un certificado pfx, el cual indico en la línea de declaración del CURLOPT_SSLCERT y añado la siguiente linea:
curl_setopt($soap_do, CURLOPT_SSLCERTPASSWD, $pass);

Si utilizo una conexión más sencilla, como la que indico a continuación, recibo el siguiente error:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $server);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestXML);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

ERROR:
"
01
Rechazado
Baztertua

001
Error: No se ha utilizado certificado de cliente.
Errorea: Ez da erabili bezeroaren ziurtagiririk.
"

Muchísimas gracias por vuestra ayuda.

Pasa el certificado a .pem
En el envío a GIP o BAtUZ hay que identificarse, pero no firmar
El certificado ha de estar tb instalado en el navegador (creo)
El .pem no requiere pass
Si necesitas el "como" tengo un apaño para importar certificados pfx y pasarlos a pem
Ya dices

canfora 20-05-2021 15:19:18

Buenas,

tengo este pequeño código para pasar el certificado a pem, pero sigue sin funcionarme.

Código:

$data = file_get_contents($dir_cert);
openssl_pkcs12_read($data, $certs, $certPassword);

$publicChain = array($certs['cert']);
if (!empty($certs['extracerts'])) {
        $publicChain = array_merge($publicChain, $certs['extracerts']);
}
$privateKey = openssl_pkey_get_private($certs['pkey']);

Paso la variable $publicChain

Muchas gracias!!



Cita:

Empezado por bilbur (Mensaje 541012)
Pasa el certificado a .pem
En el envío a GIP o BAtUZ hay que identificarse, pero no firmar
El certificado ha de estar tb instalado en el navegador (creo)
El .pem no requiere pass
Si necesitas el "como" tengo un apaño para importar certificados pfx y pasarlos a pem
Ya dices


canfora 21-05-2021 09:27:00

Buenos días!!!

Ya conseguí la conexión. Ahora toca pegarse con el XML.

Muchas gracias,

Cita:

Empezado por canfora (Mensaje 541013)
Buenas,

tengo este pequeño código para pasar el certificado a pem, pero sigue sin funcionarme.

Código:

$data = file_get_contents($dir_cert);
openssl_pkcs12_read($data, $certs, $certPassword);

$publicChain = array($certs['cert']);
if (!empty($certs['extracerts'])) {
        $publicChain = array_merge($publicChain, $certs['extracerts']);
}
$privateKey = openssl_pkey_get_private($certs['pkey']);

Paso la variable $publicChain

Muchas gracias!!


kino_ct 21-05-2021 16:32:19

Cita:

Empezado por espinete (Mensaje 539825)
Gracias,. keys.


Después de colocarlo todo en el orden correcto, ahora obtengo un error que me hace mucha menos gracia que todos los anteriores:

B4_1000002 - Todos los registros incluidos en la petición son incorrectos.

Pues menuda gracia.
Me ocurre con el 240 y con el 140. Este es el código que utilizo para generar y firmar el XML:
¿En serio? TODOS los registros incluidos en la petición son incorrectos???!?!?

Obviamente en el xml y en el envío no he puesto XXXXXXXX sino los datos correctos, que coinciden con el del certificado digital que estoy usando.

¿Alguien más ha tenido este problema? ¿A qué campos se refiere exactamente?




Buenas

Tengo el mismo problema y me ha parecido super bizarro el mensaje y sobre todo la ayuda que da la documentación sobre él.


{StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
eus-bizkaia-n3-mensaje-respuesta: Todos los registros incluidos en la petición son incorrectos.
eus-bizkaia-n3-codigo-respuesta: B4_1000002
eus-bizkaia-n3-numero-registro:
eus-bizkaia-n3-tipo-respuesta: Incorrecto


Alguién sabe como solucionarlo o por donde tirar?


un saludo y gracias

Galaxian 21-05-2021 18:57:54

Cita:

Empezado por kino_ct (Mensaje 541020)
Buenas

Tengo el mismo problema y me ha parecido super bizarro el mensaje y sobre todo la ayuda que da la documentación sobre él.


{StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
eus-bizkaia-n3-mensaje-respuesta: Todos los registros incluidos en la petición son incorrectos.
eus-bizkaia-n3-codigo-respuesta: B4_1000002
eus-bizkaia-n3-numero-registro:
eus-bizkaia-n3-tipo-respuesta: Incorrecto


Alguién sabe como solucionarlo o por donde tirar?


un saludo y gracias

En el XML comprimido que devuelve la petición tienes toda la información sobre el error (dependiendo del lenguaje y/o librerías que uses es posible que tengas que descomprimirlo dos veces).

Galaxian 22-05-2021 12:01:43

Buenas,

Acabo de hacer una prueba de envío del 140 y me sale un error ya conocido:

Cita:

El XML no cumple el esquema.[Linea:2 Columna:200] Error:cvc-elt.1.a: Cannot find the declaration of element 'lrpficfcsgap:LROEPF140IngresosConFacturaConSGAltaPeticion'.
Lo que significa que no puede encontrar el xsd indicado por xmlns:lrpficfcsgap, por lo que he puesto en el navegador la URL de la versión 1.0.1:

Y, efectivamente, no existe, por lo que he probado con la de la versión 1.0.2:

Y esa sí que existe, por lo que he modificado la cabecera del 140 para que coja la URL de la versión 1.0.2 y... ¡sorpresa! error 500 (error interno del servidor).

Es decir, que con la URL de la versión 1.0.1 dice que no encuentra el xsd, y cuando se pone el xsd correcto da un error 500. ¡Maravilloso!

¿A alguien más le pasa?
¿Alguna solución?

keys 24-05-2021 09:54:34

Hola a todos.

¿Alguien esta teniendo problemas hoy lunes al enviar a Bizkaia?.

tejano 24-05-2021 13:14:58

Envio XML
 
Buenos días,
Hoy he estado en un Webinar sobre "Batuz" y me ha parecido entender hay que enviar el XML firmado a la hacienda. Yo tenía entendido que los datos del XML se envían codificados en Base64 sobre el fichero LROE y en ningún momento hay que enviar el XML firmado.
El XML firmado tenemos que tenerlo guardado por si hay alguna inspección o algo similar.
Podéis decirme si estoy en lo correcto?
Gracias

keys 24-05-2021 13:19:27

Cita:

Empezado por tejano (Mensaje 541025)
Buenos días,
Hoy he estado en un Webinar sobre "Batuz" y me ha parecido entender hay que enviar el XML firmado a la hacienda. Yo tenía entendido que los datos del XML se envían codificados en Base64 sobre el fichero LROE y en ningún momento hay que enviar el XML firmado.
El XML firmado tenemos que tenerlo guardado por si hay alguna inspección o algo similar.
Podéis decirme si estoy en lo correcto?
Gracias

El xml codificado tiene que estar firmado. La aplicación debe conservar los xml firmados y poder acceder a ellos para una posible inspección.

Un Saludo.

tejano 24-05-2021 14:24:36

Cita:

Empezado por keys (Mensaje 541026)
El xml codificado tiene que estar firmado. La aplicación debe conservar los xml firmados y poder acceder a ellos para una posible inspección.

Un Saludo.

Pero en ningún momento hay que enviar estos XML a la DFB, no? Solo hay que enviarlos en el LROE codificados en Base64.
Gracias

keys 24-05-2021 15:19:05

Cita:

Empezado por tejano (Mensaje 541027)
Pero en ningún momento hay que enviar estos XML a la DFB, no? Solo hay que enviarlos en el LROE codificados en Base64.
Gracias

Los ficheros se envian dentro del LROE, no hay que enviarlos por si solos a ningún sitio (Bizkaia), hay que conservarlos en algún sitio de la aplicación. No vale con generarlos cada vez que los necesites, ya que con la firma sería distinto, por eso lo de firmarlos ,

Un Saludo.

tejano 24-05-2021 15:27:14

Cita:

Empezado por keys (Mensaje 541028)
Los ficheros se envian dentro del LROE, no hay que enviarlos por si solos a ningún sitio (Bizkaia), hay que conservarlos en algún sitio de la aplicación. No vale con generarlos cada vez que los necesites, ya que con la firma sería distinto, por eso lo de firmarlos ,

Un Saludo.

Graciasssss Keys

keys 25-05-2021 08:58:35

Hola.


Lo interesante es la última pregunta.

https://www.deia.eus/bizkaia/2021/05...a/1122904.html

Cuando el rio suena.

Galaxian 25-05-2021 09:17:46

Cita:

Empezado por keys (Mensaje 541026)
El xml codificado tiene que estar firmado. La aplicación debe conservar los xml firmados y poder acceder a ellos para una posible inspección.

Un Saludo.

Pues conservar los XML firmados individualmente es un problema inafrontable en el sector al que va destinado nuestro programa, ya que cada negocio puede generar una media de 1000 facturas diarias, y dado que hay que conservarlas durante 4 años, una simple multiplicación deja las cosas claras:

Suponiendo que el negocio abre 300 días al año, se generarían 300.000 XML al año y 1.200.000 en 4 años, lo que a unos 15KB por XML hace la friolera de 18GB, siendo el número de XML individuales y el espacio en disco inmanejables.

La cosa se complica si el programa, como ocurre en nuestro caso, hace copias de seguridad diarias en la nube, y en estas circunstancias la única solución posible es almacenar los XML comprimidos en una base de datos capaz de hacer copias de seguridad incrementales o diferenciales, cosa que no todas hacen.

Todo un reto

Neftali [Germán.Estévez] 25-05-2021 09:50:03

Cita:

Empezado por Galaxian (Mensaje 541033)
Pues conservar los XML firmados individualmente es un problema inafrontable en el sector al que va destinado nuestro programa, ya que cada negocio puede generar una media de 1000 facturas diarias, y dado que hay que conservarlas durante 4 años, una simple multiplicación deja las cosas claras:

Suponiendo que el negocio abre 300 días al año, se generarían 300.000 XML al año y 1.200.000 en 4 años, lo que a unos 15KB por XML hace la friolera de 18GB, siendo el número de XML individuales y el espacio en disco inmanejables.


Yo lo veo más sencillo que conservar eso en papel... ;);)

tejano 25-05-2021 12:26:15

Buenas, estoy enviando datos a la DFB y me devuelve este error, os ha pasado o sabéis a que puede ser debido?
<html><head><title>Error</title></head><body>Bad Request</body></html>

Gracias

Galaxian 25-05-2021 12:28:11

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 541034)
Yo lo veo más sencillo que conservar eso en papel... ;);)

Ya, pero eso no hace que el problema deje de existir.

Neftali [Germán.Estévez] 25-05-2021 15:52:40

Cita:

Empezado por Galaxian (Mensaje 541037)
Ya, pero eso no hace que el problema deje de existir.


Lo se. Nuestro trabajo es dar soluciones (más o menos complejas) a esos problemas.
Por eso nos pagan.

tejano 25-05-2021 16:51:08

Buenas tardes, alguien ha probado a enviar datos con el comando de Windows curl?
El programa de gestión que tenemos es bastante antiguo y necesito tirar de programa externos para hacer todo lo que piden.
Si alguno lo ha utilizado podría poner los parámetros que ha puesto
Gracias

batuzail 26-05-2021 07:52:41

Memoria TBAI
 
Hola,
Estoy preaprando la memoria para darnos de alta como software garante. Aún no tengo todo acabado.
Alguien que este usando los componentes de chilckat puede decirme que certificados permite usar?, ya que hay que indicar los tipos de certificados permitidos.
El QR debe aparecer en la parte inferior, pero no se especifica la alineación, el QR se puede alinear libremente?
El Qr debe de aparacer en todas las páginas de factura o solo en la última?

Gracias

Noe277 26-05-2021 09:51:31

cabecera esta mal informada
 
Buenos días,

Envió el 140 y me dice que la cabecera esta mal informada.
1- No se si se refiere a la cabecera del xml 140 o a los datos de cabecera que mandamos para realizar el envió.
2- El certificado de empresa tiene que coincidir con los datos de la cabecera del envió?

Gracias.

Band 26-05-2021 10:22:43

Yo para el curl creo así los parámetros, y luego ejecuto el curl con shellexecute.

Código Delphi [-]
curlCommand := '-F "data=@' + nombreArchivo + '" ' +  
    ' -H "Content-Type: application/xml;charset=UTF-8" ' + // Si no pongo este content type me da error 415 y en un documento de ellos comentan que se ponga este content type y efectivamente ya no da error 
    ' -H "Accept-Encoding: ''gzip''" ' +
    ' -H "Content-Encoding: ''gzip''" ' +   
    ' -H "eus-bizkaia-n3-version: ''1.0''" ' + 
    ' -H "eus-bizkaia-n3-content-type: ''application/xml''" ' +
    ' -H "eus-bizkaia-n3-data: ' + json + '"' + 
    ' -X POST ' + url ;

Entiendo que es correcto porque el servidor me devuelve la siguiente respuesta:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:TicketBaiResponse xmlns:ns2="urn:ticketbai:emision">
<Salida>
<FechaRecepcion>25-05-2021 18:20:50</FechaRecepcion>
<Estado>01</Estado>
<Descripcion>Rechazado</Descripcion>
<Azalpena>Baztertua</Azalpena>
<ResultadosValidacion>
<Codigo>001</Codigo>
<Descripcion>Error: No se ha utilizado certificado de cliente.</Descripcion>
<Azalpena>Errorea: Ez da erabili bezeroaren ziurtagiririk.</Azalpena>
</ResultadosValidacion>
</Salida>
</ns2:TicketBaiResponse>

Lo cual es correcto imagino, ya que no le estoy enviando el certificado. Para enviar el certificado en curl, en teoría sería así:

Código Delphi [-]
--cacert PATH\certificado.crt

Yo ando un poco perdido con el tema del certificado. Sirve enviar uno de prueba? (Me interesa saberlo porqué aqui: web.uanataca.com/es/certificados-prueba se pueden conseguir. También hay otros sitios) Lo que pasa es que cuando envio uno de estos certificados me sigue dando el mismo error y tengo mis dudas de si no lo envío bien o realmente no és válido (tampoco sé si debe ser crt, pem). Alguien me puede contestar a esto?

Por cierto, soy nuevo en el foro y pido perdón por si no he puesto bien las etiquetas del código.

Muchas gracias.

Sistel 26-05-2021 10:49:06

Cita:

Empezado por Noe277 (Mensaje 541043)
...
2- El certificado de empresa tiene que coincidir con los datos de la cabecera del envió?
...

Hola,

Si el certificado utilizado para firmar no es de la empresa o autónomo que emite la factura, es preciso añadir:
Código:

<EmitidaPorTercerosODestinatario>T</EmitidaPorTercerosODestinatario>
Dentro del nodo <Sujetos>
"T" es el valor de la clave L4 de la página 15 del documento de especificaciones de TicketBAI

Saludos

Sistel 26-05-2021 10:53:52

Cita:

Empezado por Band (Mensaje 541044)
...
<Descripcion>Error: No se ha utilizado certificado de cliente.</Descripcion>
<Azalpena>Errorea: Ez da erabili bezeroaren ziurtagiririk.</Azalpena>

Hola,

Lo mismo de mi respuesta anterior a Noe277
Si el certificado utilizado para firmar no es de la empresa o autónomo que emite la factura, es preciso añadir:
Código:

<EmitidaPorTercerosODestinatario>T</EmitidaPorTercerosODestinatario>
Dentro del nodo <Sujetos>
"T" es el valor de la clave L4 de la página 15 del documento de especificaciones de TicketBAI

Saludos

Noe277 26-05-2021 11:01:35

Cita:

Empezado por Sistel (Mensaje 541045)
Hola,

Si el certificado utilizado para firmar no es de la empresa o autónomo que emite la factura, es preciso añadir:
Código:

<EmitidaPorTercerosODestinatario>T</EmitidaPorTercerosODestinatario>
Dentro del nodo <Sujetos>
"T" es el valor de la clave L4 de la página 15 del documento de especificaciones de TicketBAI

Saludos

Eso es correcto si hablamos del fichero Ticketbai.xml yo me refería al 140.xml en el que incrusto el gz de los tickets.

Código:

request.Headers["eus-bizkaia-n3-data"] = "{\"con\": \"LROE\", \"apa\": \"1.1\", \"inte\": {\"nif\": \"" + Nif + "\",\"nrs\":\"" + RazonSocial + "\",\"ap1\": \"" + apellido1 + "\",\"ap2\": \"" + apellido2+ "\"},\"drs\": { \"mode\": \"140\",\"ejer\": \"" + ejercicioPROVISIONAL + "\"}};";
Mi pregunta es si el Nif que mando aquí tiene que corresponder con el certificado a la hora de hacer el envio.

Neftali [Germán.Estévez] 26-05-2021 11:06:46

Cita:

Empezado por Noe277 (Mensaje 541043)
Envió el 140 y me dice que la cabecera esta mal informada.


¿Cual es el código y el mensaje exacto del error?

Neftali [Germán.Estévez] 26-05-2021 11:10:42

Cita:

Empezado por Band (Mensaje 541044)
Yo ando un poco perdido con el tema del certificado. Sirve enviar uno de prueba?
Alguien me puede contestar a esto?

Puedes usar certificados de prueba. Desde la web de Izenpe creo que se pueden descargar algunos.
Eso te servirá para avanzar un paso más y saber si lo envía correctamente, pero entonces obtendrás un error de este estilo:

<012 - Aviso: Error en verificación alta-inscripción software TicketBAI: los datos de registro no coinciden.>

Que significa que el certificado llega bien, pero no "cuadra" con los datos que tienen ellos.

Al final, para poder enviar facturas y que te las acepten, debes usar un certificado "bueno", que coincida con los datos de empresa y que "cuadre" con los datos que tienen ellos (hay que darlos de alta).


Cita:

Empezado por Band (Mensaje 541044)
Por cierto, soy nuevo en el foro y pido perdón por si no he puesto bien las etiquetas del código.

^\||/^\||/^\||/

HerensugeBeltz 26-05-2021 12:13:51

Hola a todos!

Me acaban de endosar la adaptación a TicketBAI de una pequeña aplicación de facturación. Hemos adquirido los componentes SecureBlackBox2020 y ya tengo dos prototipos de prueba: uno de firma del XML y otro para el envío TLS del XML firmado a la Hacienda de Gipuzkoa.

Adelanto ya que nunca he tenido que pelearme con certificados digitales y todo esto es nuevo para mí.
La duda que me surge es que, tanto para la firma como para el envío, al cargar el certificado tengo que especificar su contraseña. Entiendo que la firma del XML debe ser automática, sin que intervenga el usuario. ¿Hay alguna forma de firmar o enviar el documento firmado sin que el usuario tenga que indicar su contraseña en, por ejemplo, una pantalla de configuración de la aplicación?

Muchas gracias.

Nota: soy nuevo en el foro y no he encontrado una opción de nuevo mensaje, por lo que he pulsado en respuesta rápida. SI he hecho mal que alguien me corrija.

Noe277 26-05-2021 13:21:16

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 541049)
Al final, para poder enviar facturas y que te las acepten, debes usar un certificado "bueno", que coincida con los datos de empresa y que "cuadre" con los datos que tienen ellos (hay que darlos de alta).

^\||/^\||/^\||/

Gracias. Pensábamos que no tenían por que coincidir con la cabecera del envió.

En cuanto a HerensugeBeltz. Nosotros guardamos en local el certificado que vamos a usar para que no nos lo pida cada vez, aunque la contraseña si la pide. Hay maneras de instalar el certificado para que no pida la contraseña pero esto ya es externo a la aplicación es mas del almacén de certificados.

luismartin 26-05-2021 14:28:47

Cita:

Empezado por canfora (Mensaje 541008)
Buenos días,

Me acabo de poner con la programación en php para el envío de XML a TBAI a Gipuzkoa.
Estoy utilizando el código que sugerís a continuación y recibo en todo momento el siguiente error:
"
No se puede conectar con la TBAI GIP.

Error: unable to use client certificate (no key found or wrong pass phrase?)

Respuesta de la TBAI GIP: 312
"
Tengo un certificado pfx, el cual indico en la línea de declaración del CURLOPT_SSLCERT y añado la siguiente linea:
curl_setopt($soap_do, CURLOPT_SSLCERTPASSWD, $pass);

Si utilizo una conexión más sencilla, como la que indico a continuación, recibo el siguiente error:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $server);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestXML);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

ERROR:
"
01
Rechazado
Baztertua

001
Error: No se ha utilizado certificado de cliente.
Errorea: Ez da erabili bezeroaren ziurtagiririk.
"

Muchísimas gracias por vuestra ayuda.


Hola Canfora, a ver si esto te puede ayudar, ya que llegué a ese punto, y finalmente la conexión me la validó (aunque ahora estoy con otro problema):
como te indica Bilbur, debes usar un certificado de tipo PEM, pero según he hecho yo, generando 3 ficheros PEM por separado (usando el comando openssl): el del cliente, el de la clave privada, y el de la autoridad certificadora:

Cita:

openssl pkcs12 -in abcd.pfx -out ca.pem -cacerts -nokeys
openssl pkcs12 -in abcd.pfx -out client.pem -clcerts -nokeys
openssl pkcs12 -in abcd.pfx -out key.pem -nocerts
No he podido poner el enlace de la fuente por ser un usuario nuevo :( Y lo que tampoco tengo aún claro, es cómo hacer esta conversión de forma automática, sin necesidad de user input.

Al final, el código de la petición cURL es este:

Código PHP:

        $xmlStr file_get_contents($rutaFacturaXML);
        
        
$ch curl_init($url);
        
curl_setopt($chCURLOPT_POST1);
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
curl_setopt($chCURLOPT_SSLCERTPATH_TEMP '/client.pem');
        
curl_setopt($chCURLOPT_SSLKEYPATH_TEMP '/key.pem');
        
curl_setopt($chCURLOPT_CAINFOPATH_TEMP '/ca.pem');
        
curl_setopt($chCURLOPT_SSLKEYPASSWD$clave);
        
curl_setopt($chCURLOPT_SSL_VERIFYPEER1);
        
curl_setopt($chCURLOPT_POSTFIELDS$xmlStr);
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: application/xml; charset=utf-8')); 
        
$resp curl_exec($ch); 


tejano 26-05-2021 15:38:00

Cita:

Empezado por Band (Mensaje 541044)
Yo para el curl creo así los parámetros, y luego ejecuto el curl con shellexecute.

Código Delphi [-]
curlCommand := '-F "data=@' + nombreArchivo + '" ' +  
    ' -H "Content-Type: application/xml;charset=UTF-8" ' + // Si no pongo este content type me da error 415 y en un documento de ellos comentan que se ponga este content type y efectivamente ya no da error 
    ' -H "Accept-Encoding: ''gzip''" ' +
    ' -H "Content-Encoding: ''gzip''" ' +   
    ' -H "eus-bizkaia-n3-version: ''1.0''" ' + 
    ' -H "eus-bizkaia-n3-content-type: ''application/xml''" ' +
    ' -H "eus-bizkaia-n3-data: ' + json + '"' + 
    ' -X POST ' + url ;

Entiendo que es correcto porque el servidor me devuelve la siguiente respuesta:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:TicketBaiResponse xmlns:ns2="urn:ticketbai:emision">
<Salida>
<FechaRecepcion>25-05-2021 18:20:50</FechaRecepcion>
<Estado>01</Estado>
<Descripcion>Rechazado</Descripcion>
<Azalpena>Baztertua</Azalpena>
<ResultadosValidacion>
<Codigo>001</Codigo>
<Descripcion>Error: No se ha utilizado certificado de cliente.</Descripcion>
<Azalpena>Errorea: Ez da erabili bezeroaren ziurtagiririk.</Azalpena>
</ResultadosValidacion>
</Salida>
</ns2:TicketBaiResponse>

Lo cual es correcto imagino, ya que no le estoy enviando el certificado. Para enviar el certificado en curl, en teoría sería así:

Código Delphi [-]
--cacert PATH\certificado.crt

Yo ando un poco perdido con el tema del certificado. Sirve enviar uno de prueba? (Me interesa saberlo porqué aqui: web.uanataca.com/es/certificados-prueba se pueden conseguir. También hay otros sitios) Lo que pasa es que cuando envio uno de estos certificados me sigue dando el mismo error y tengo mis dudas de si no lo envío bien o realmente no és válido (tampoco sé si debe ser crt, pem). Alguien me puede contestar a esto?

Por cierto, soy nuevo en el foro y pido perdón por si no he puesto bien las etiquetas del código.

Muchas gracias.

Gracias, creo que me servirá parte de lo que has puesto.

Si miras el documento de ESPECIFICACIONES FUNCIONALES Y TECNICAS DEL ENVIO MASIVO DEL LROE, en la página 17 y 18 verás:
Para el LROE, se deben incluir en la cabecera HTTP de la petición obligatoriamente los siguientes parámetros con los valores que se indican a continuación:
▪ Accept-Encoding = gzip.
▪ Content-Encoding = gzip.
▪ Content-Length = tamaño del cuerpo del mensaje.
▪ Content-Type = application/octet-stream.
▪ eus-bizkaia-n3-version = 1.0.
▪ eus-bizkaia-n3-content-type = application/xml.
▪ eus-bizkaia-n3-data = contenido del fichero json.
Json - eus-bizkaia-n3-data = { "con": "LROE", "apa": "1.1", "inte": { "nif": "número de identificación fiscal", "nrs": "nombre o Razón social", "ap1": "primer apellido", "ap2": "segundo apellido" }, "drs": { "mode": "140/240", "ejer": "ejercicio" } }

Creo que te falta el content-length, el content-Type creo que esta mal y por lo demás todo OK.

Una cosilla para todos, si sabéis...... el LROE de facturas recibidas hay que comprimir el fichero en formato gzip?

Gracias

luismartin 26-05-2021 15:45:33

(002) Error: No se permite firma Enveloping.
 
Hola a todos, soy nuevo en el foro, aunque ya lo llevo usando un tiempo, y me ha sido de gran ayuda para la generación de las facturas TBAI.

El problema con el que me encuentro ahora, es que al realizar el envío, recibo este error:

Código:

(002) Error: El fichero de alta TicketBAI no cumple el esquema XSD. No se permite firma Enveloping.
En la documentación de TBAI, vi que esto se debe a que la firma que genero, se hace en formato Enveloping, cuando debería ser Enveloped.

Para la generación de la firma en el documento, utilizo el comando de la aplicación Autofirma, con las siguientes opciones:

Código:

autofirma  sign -i ruta/fichero.xml -o ruta/fichero.firmado.xml -format xades -store pkcs12:certificado.pfx -password ***** -filter "imported"
El fichero generado, fichero.firmado.xml, pasa la validación de estos validadores que he encotrado en este mismo hilo:
Uno de chilkat
Y otro de uanataca (lo siento, aún no puedo poner enlaces al ser usuario nuevo)

Posteriormente, vi el mensaje #470 en el hilo, y añadí la opción que indica poner:
Código:

-config="format=XAdES Enveloped\npolicyIdentifier=h......"
Pero al hacerlo, recibo el error de formato no permitido.

Alguien sabría decirme qué más debo hacer para obtener la firma en el formato Enveloped??

Gracias!

Band 26-05-2021 16:22:31

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 541049)
Puedes usar certificados de prueba. Desde la web de Izenpe creo que se pueden descargar algunos.
Eso te servirá para avanzar un paso más y saber si lo envía correctamente, pero entonces obtendrás un error de este estilo:

<012 - Aviso: Error en verificación alta-inscripción software TicketBAI: los datos de registro no coinciden.>

Que significa que el certificado llega bien, pero no "cuadra" con los datos que tienen ellos.

Al final, para poder enviar facturas y que te las acepten, debes usar un certificado "bueno", que coincida con los datos de empresa y que "cuadre" con los datos que tienen ellos (hay que darlos de alta).



^\||/^\||/^\||/


Gracias! Tiraré por este camino de los certificados de prueba de Izenpe (solo para probar el envío del certificado). Después ya me haré con uno "bueno" para seguir con los errores de validación del xml que puedan haber, que seguro que los habrá xD

Band 26-05-2021 16:27:56

Cita:

Empezado por tejano (Mensaje 541053)
Gracias, creo que me servirá parte de lo que has puesto.

Si miras el documento de ESPECIFICACIONES FUNCIONALES Y TECNICAS DEL ENVIO MASIVO DEL LROE, en la página 17 y 18 verás:
Para el LROE, se deben incluir en la cabecera HTTP de la petición obligatoriamente los siguientes parámetros con los valores que se indican a continuación:
▪ Accept-Encoding = gzip.
▪ Content-Encoding = gzip.
▪ Content-Length = tamaño del cuerpo del mensaje.
▪ Content-Type = application/octet-stream.
▪ eus-bizkaia-n3-version = 1.0.
▪ eus-bizkaia-n3-content-type = application/xml.
▪ eus-bizkaia-n3-data = contenido del fichero json.
Json - eus-bizkaia-n3-data = { "con": "LROE", "apa": "1.1", "inte": { "nif": "número de identificación fiscal", "nrs": "nombre o Razón social", "ap1": "primer apellido", "ap2": "segundo apellido" }, "drs": { "mode": "140/240", "ejer": "ejercicio" } }

Creo que te falta el content-length, el content-Type creo que esta mal y por lo demás todo OK.

Una cosilla para todos, si sabéis...... el LROE de facturas recibidas hay que comprimir el fichero en formato gzip?

Gracias


Cierto, falta el content-length pero de momento no se me ha quejado de esto. Si me da algún tipo de problema ya lo pondré. El content-type ya digo, yo tuve que cambiar el "application/octet-stream" por "application/xml;charset=UTF-8". Esto lo encontré en algún documento de FAQ para desarrolladores (concretamente el documento se llama "Problemas y dudas frecuentes en servicios de alta y anulación de facturas"). Lo encontré de chiripa poniendo "ticket bai error 415" en google

Sistel 26-05-2021 16:35:48

Cita:

Empezado por luismartin (Mensaje 541052)
Código PHP:

        $xmlStr file_get_contents($rutaFacturaXML);
        
        
$ch curl_init($url);
        
curl_setopt($chCURLOPT_POST1);
        
curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
curl_setopt($chCURLOPT_SSLCERTPATH_TEMP '/client.pem');
        
curl_setopt($chCURLOPT_SSLKEYPATH_TEMP '/key.pem');
        
curl_setopt($chCURLOPT_CAINFOPATH_TEMP '/ca.pem');
        
curl_setopt($chCURLOPT_SSLKEYPASSWD$clave);
        
curl_setopt($chCURLOPT_SSL_VERIFYPEER1);
        
curl_setopt($chCURLOPT_POSTFIELDS$xmlStr);
        
curl_setopt($chCURLOPT_HTTPHEADER, array('Content-Type: application/xml; charset=utf-8')); 
        
$resp curl_exec($ch); 


Hola luismartin,

Cuando ya tienes convertido el certificado a formato PEM, ya no necesitas la clave.
Puedes quitar la línea curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $clave);
Tampoco se necesita el certificado CA de la Autoridad Certificadora.
Así que puede quitar también curl_setopt($ch, CURLOPT_CAINFO, PATH_TEMP . '/ca.pem');

Saludos

tejano 26-05-2021 16:43:31

Cita:

Empezado por luismartin (Mensaje 541054)
Hola a todos, soy nuevo en el foro, aunque ya lo llevo usando un tiempo, y me ha sido de gran ayuda para la generación de las facturas TBAI.

El problema con el que me encuentro ahora, es que al realizar el envío, recibo este error:

Código:

(002) Error: El fichero de alta TicketBAI no cumple el esquema XSD. No se permite firma Enveloping.
En la documentación de TBAI, vi que esto se debe a que la firma que genero, se hace en formato Enveloping, cuando debería ser Enveloped.

Para la generación de la firma en el documento, utilizo el comando de la aplicación Autofirma, con las siguientes opciones:

Código:

autofirma  sign -i ruta/fichero.xml -o ruta/fichero.firmado.xml -format xades -store pkcs12:certificado.pfx -password ***** -filter "imported"
El fichero generado, fichero.firmado.xml, pasa la validación de estos validadores que he encotrado en este mismo hilo:
Uno de chilkat
Y otro de uanataca (lo siento, aún no puedo poner enlaces al ser usuario nuevo)

Posteriormente, vi el mensaje #470 en el hilo, y añadí la opción que indica poner:
Código:

-config="format=XAdES Enveloped\npolicyIdentifier=h......"
Pero al hacerlo, recibo el error de formato no permitido.

Alguien sabría decirme qué más debo hacer para obtener la firma en el formato Enveloped??

Gracias!

Te doy las instrucciones para la DBF con la línea de comando de autofirma "autofirmacommandline"

AutoFirmaCommandLine.exe sign
-i nombre_fichero
-o nombre_fichero_firmado
-store pkcs12:nombre_certificado.p12
-password contraseña_certificado
-filter nombre_certificado.p12
-format xades -xml
-config "format=XAdES Enveloped
\npolicyIdentifier=https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf
\npolicyIdentifierHash=Quzn98x3PMbSHwbUzaj5f5KOpiH0u8bvmwbbbNkO9Es=
\npolicyIdentifierHashAlgorithm=http://www.w3.org/2001/04/xmlenc#sha256
\npolicyQualifier=https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf

A mi me funciona bien, aunque tarda unos 3 sg por cada fichero.

Esto lo pusieron en el foro hace algún tiempo y me ayudo mucho.


La franja horaria es GMT +2. Ahora son las 22:52:17.

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