I try to connect to the Web Service of the AEAT (SII) to send XML files. I've spent a tremendous amount of time researching and testing, but I'm very close to giving up, or postponing it until there's more information on the web.
For sending, I am trying to use the SERVERXMLHTTP library This would be the code:
Dim oWS As MSXML2.ServerXMLHTTP
Set oWS = New MSXML2.ServerXMLHTTP
Dim xmlResponse As MSXML2.DOMDocument
'Abrimos conexión'
oWS.Open "POST", strURL, False
oWS.setRequestHeader "Content-Type", "text/xml"
'Autentificación'
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT,
'Envío'
Call oWS.send(strXml)
Note that strURL is a correct and verified path, and strXML is correct XML.
The response I can see is: (I add full TEXT response at the end of the query)
oWS.Status 'Respuesta = 200 (OK)'
oWS.ResponseXML 'Esta respuesta está vacía'
oWS.ResponseText 'Aquí hay un html que vendría a ser un formulario en el que me piden que entre la Cl@ve Pin'.
In short, what I seem to be missing is the digital certificate. Maybe I don't know how to call the certificate, but I've already tried a thousand ways and I can't figure out how to use it:
Option 1: As I could read, if we do not specify the certificate, the first one that exists is selected (in my case I only have one certificate installed conscientiously, but I can understand that something else is taking me
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, ""
Option 2: Many people talked about looking for the record like: MY\ This information is very abstract for me. I managed to see that the certificates are located in the registry at these paths:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\
'Y allí dentro hay un directorio con muchos números y letras:'
HKEY_LOCAL_MACHINE\...\Certificates\A1234C5678950E8F4295EA63D9515E3689B8EBC1
'Y dentro de ella hay una clave llamaada <Blob>'
Knowing this, I tried several approaches:
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "LOCAL_MACHINE\MY\A1234C5678950E8F4295EA63D9515E3689B8EBC1"
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "LOCAL_MACHINE\MY\Certificates\A1234C5678950E8F4295EA63D9515E3689B8EBC1"
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "LOCAL_MACHINE\MY\Certificates\A1234C5678950E8F4295EA63D9515E3689B8EBC1\Blob"
Option 3: I could also read that the CN name of the certificate should be specified sxh.setOption(3) = "Common Name (CN) part of certificate's Subject name"
'Nombre completo que pude encontrar en CN:'
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "PEPITO GRILLO - 39301234P"
'Parte del nombre que pude encontrar en CN:'
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "39301234P"
'Nombre completo CN, pero añadiendo la ruta'
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, "LOCAL_MACHINE\MY\PEPITO GRILLO - 39301234P"
Anyway... a thousand ways to try to locate and be able to use the certificate. But none worked for me. The answer is always the same.
Maybe I'm wrong about something?
The certificate could be located in several ways
> MMC.exe
> Archivo > Agregar o quitar complementos...
> Certificados (Equipo local)
> FIREFOX
> Opciones > Avanzado... > Certificados > Ver Certificados...
> Sus Certificados:
> FNMT-RCM
> PEPITO GRILLO - 39301234P
In both cases we can locate the certificates. And once located, if we double click on the certificate, all the information appears, such as the CN that I tried to use in option 3, or the sequence of numbers and letters that I found in the registry (the value of the Fingerprint SHA1 is what was in the windows registry)
Leaving a bit of vba, I have a final note:
Since I couldn't get it to work, I tried using CURL.EXE. I will not go into detail for now on how I sent the data, but the answer it gave me was the same (answer that forwards to a form where you have to enter the Cl@ve Pin"
In short, I'm not doing something right because it doesn't capture my certificates, but I don't know how to fix it.
APPENDIX 1: I add TEXT response that returns the attempt to send to the AEAT:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="es" xmlns="http://www.w3.org/1999/xhtml" xml:lang="es">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-15" />
<title>Autenticación - Cl@ve PIN</title>
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<link href="/static_files/common/css/xzhtcs04.css" rel="stylesheet" type="text/css"/>
<link href="/static_files/common/internet/dep/aplicaciones/ov/css/p24idecs.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="/static_files/common/internet/dep/aplicaciones/ov/script/aeatrsc0.js"></script>
<script type="text/javascript" src="/static_files/common/internet/dep/aplicaciones/ov/script/p24a01cd.js"></script>
<script src="/static_files/common/internet/script/clave_pin.js" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
jQuery.noConflict();
var ref = "/wlpl/SII-FACT/ws/fe/SiiFactFEV1SOAP";
var from = '';
var bfprint = '&BFPRINT;';
var storksp = '';
var qaa = '';
var msg = '';
//]]>
</script>
</head>
<body onload="init();" onfocus="focoEnPagina();">
<!-- p24Aut01.html -->
<div id="AEAT_header"></div>
<div id="p24h-pane" class="AEAT_contenedor">
<div id="p24h-title" class="AEAT_contenedor">
<h2>Autenticación</h2>
</div>
<div id="qaa-2" style="display:none;text-align: right;font-size: xx-small;">Nivel básico</div>
<div id="qaa-3" style="display:none;text-align: right;font-size: xx-small;">Nivel sustancial</div>
<!-- div class="AEAT_bloque_avisos p24h-avisos">
<h2>Avisos:</h2>
<p>Para el correcto funcionamiento del servicio Cl@ve PIN es necesario que su navegador permita la utilización
de cookies y la ejecución de javascript</p>
</div-->
<div id="errores" class="AEAT_bloque_errores p24h-errores" style="display: none"></div>
<div id="avisos" class="AEAT_bloque_avisos p24h-avisos" style="display: none"></div>
<div id="p24h-form" class="AEAT_contenedor">
<form id="iden-form" name="iden-form" action="/es12/l/es02genp24h1" method="post" class="AEAT_form" autocomplete="off">
El asterisco <span class="obligatorio"> * </span> indica que es imprescindible completar este dato<br/><br/>
<table id="p24h-campos" class="ancho_100">
<tr id="campo-nif"><td class="ancho_25" style="text-align: right">
<label for="nif">
<span class="obligatorio">* </span><acronym title="Documento Nacional de Identidad">DNI</acronym>/<acronym title="Número de Identificación de Extranjero">NIE</acronym>
</label></td>
<td>
<input type="text" id="nif" name="NIF" size="9em" maxlength="9" placeholder="DNI/NIE" style="width: 11ex" value="" onblur="chequearNIF();$('msg-nif').hide();" onfocus="activarMsg('msg-nif');"/>
<span id="msg-nif" style="display: none">« Introduzca el <acronym title="Documento Nacional de Identidad">DNI</acronym>/<acronym title="Número de Identificación de Extranjero">NIE</acronym></span>
</td></tr>
<tr id="campo-ape" style="display: none"><td class="ancho_25" style="text-align: right">
<span class="obligatorio">* </span> <label for="ape">Primer apellido</label>
</td><td>
<input type="text" id="ape" name="APE" size="20em" maxlength="20" placeholder="Primer Apellido" style="width: 22ex" value="" onfocus="activarMsg('msg-ape');" onblur="$('msg-ape').hide();"/>
<span id="msg-ape" style="display: none">« Introduzca su primer apellido</span>
</td></tr>
<tr id="campo-clv">
<td class="ancho_25" style="text-align: right">
<label for="clv"><span class="obligatorio">* </span>Código</label>
</td>
<td>
<input type="text" id="clv" name="CLV" size="4em" maxlength="4" value="" placeholder="Clave" style="width: 5ex" onfocus="$('clv').select();activarMsg('msg-clv');" onblur="$('msg-clv').hide();"/>
<span id="msg-clv" style="display: none">« Introduzca el código elegido en el proceso de obtención</span>
</td>
</tr>
<tr id="campo-pin">
<td class="ancho_25" style="text-align: right">
<label for="pin"><span class="obligatorio">* </span><acronym title="Número Personal de Identificación">PIN</acronym></label>
</td>
<td>
<input type="password" id="pin" name="PIN" size="3em" maxlength="3" value="" placeholder="PIN" style="width: 5ex" onfocus="$('pin').select();activarMsg('msg-pin');" onblur="$('msg-pin').hide();"/>
<span id="msg-pin" style="display: none">« Introduzca el <acronym title="Número Personal de Identificación">PIN</acronym> que ha recibido en su teléfono móvil. Estará compuesto por letras (excluida la eñe) y/o dígitos (excluidos el cero, uno, ocho y nueve).</span>
<!--span id="msg-pin" style="display: none">« Introduzca el <acronym title="Número Personal de Identificación">PIN</acronym> que ha recibido en el <acronym title="Servicio de Mensajería Corta">SMS</acronym></span-->
</td>
</tr>
<!-- Opcional. Número de teléfono -->
<tr id="campo-tmv" style="display: none"><td class="ancho_25" style="text-align: right">
<label for="tmv"><span class="obligatorio">* </span>Teléfono móvil</label>
</td><td>
<input id="tmv" name="TMV" size="15em" maxlength="15" placeholder="teléfono móvil" style="width: 17ex" value="" onfocus="activarMsg('msg-tmv');" onblur="$('msg-tmv').hide()"/>
<span id="msg-tmv" style="display: none">« Introduzca el número de teléfono con el que dió de alta el servicio <acronym title="Servicio de autenticación por PIN de 24 horas">PIN</acronym></span>
</td></tr>
</table>
<div id="botones" class="AEAT_bloque_botones p24-botones">
<input type="button" id="boton-acceder" class="AEAT_boton" value="Acceder" onclick="acceder('es');"/>
<input type="button" id="boton-solicitar" class="AEAT_boton" value="No tengo PIN" onclick="solicitudDePin('es');"/>
<input type="button" id="boton-acceso-registro" class="AEAT_boton" value="No estoy registrado" onclick="accederRegistroClave('es');"/>
</div>
<!-- ATENCIÓN: El orden es significativo -->
<input type="hidden" id="ref" name="REF" value="/wlpl/SII-FACT/ws/fe/SiiFactFEV1SOAP"/><!-- referrer que me pasa la infraestructura del CWS -->
<input type="hidden" id="from" name="FROM" value=""/><!-- origen de la petición actual, para stork -->
<input type="hidden" id="bfprint" name="BFPRINT" value="&BFPRINT;"/><!-- firgerprint del usuario -->
<input type="hidden" id="storksp" name="STORKSP" value="&STROKSP;"/><!-- origen de la petición actual, para stork -->
<input type="hidden" id="qaa" name="QAA" value=""/><!-- qaa solicitado desde el SP (Proveedor de servicios) -->
<input type="hidden" id="msg" value=""/><!-- mensage que me pasa la infraestructura del CWS -->
<input type="hidden" id="idi" value="es"/><!-- idioma en el que se encuentra la página -->
</form>
</div>
</div>
<div id="p24h-registro-clave" title="Registro en Cl@ve" style="display:none">
<p>La Administración Estatal ha implantando el sistema <strong class="azul">Cl@ve</strong>, que permite el acceso sencillo a los
servicios electrónicos de diferentes administraciones públicas.</p>
<p>Si quiere beneficiarse de esta plataforma, sólo será necesario que se dé de alta en un
registro único. Una vez registrado en <strong class="azul"> Cl@ve </strong> podrá utilizar algunos de los sistemas de
identificación y autenticación que forman parte de la plataforma, para acceder a los
diferentes servicios de administración electrónica que se han integrado en la plataforma,
y sin necesidad de contar con diferentes altas en cada servicio.</p>
<p>Los sistemas que permiten la identificación al acceder a los servicios electrónicos
son el sistema Cl@ve PIN y el sistema Cl@ve Permanente. Para más información sobre las
características de estos sistemas, visite <a href="http://clave.gob.es/">
clave.gob.es</a>.</p>
<p>Los sistemas que forman parte de <strong class="azul">Cl@ve</strong> permiten cubrir las diferentes necesidades y
circunstancias de los ciudadanos que necesitan realizar trámites administrativos y de
los órganos u organismos que los ofrecen a través de sus Sedes Electrónicas.</p>
<p>A partir del 1 de enero de 2016, el sistema PIN24H desaparece para integrarse definitivamente
en Cl@ve PIN. Como usuario registrado del sistema PIN24H, puede incorporar sus datos
a la nueva plataforma <strong class="azul">Cl@ve</strong> de forma sencilla. Si usted desea beneficiarse de las ventajas
que ofrece esta nueva plataforma, por favor haga clic en <em>registrarse en Cl@ve</em> y le guiaremos en el proceso.</p>
</div>
<div id="p24h-aviso-tdp" title="Importante:" style="display: none">
<p>Se ha detectado que el número de teléfono móvil que constaba asociado al
<acronym title="Documento Nacional de Identidad">DNI</acronym>/<acronym title="Número de Identificación de Extranjero">NIE</acronym>
indicado se encuentra actualmente asignado a otro usuario del sistema <strong class="azul"> Cl@ve </strong>.</p>
<p>Por su seguridad, para poder recibir el <acronym title="Número Personal de Identificación">
PIN</acronym> vía <acronym title="Servicio de Mensajería Corta">SMS</acronym> y continuar con el trámite es
necesario que actualice su número de teléfono.</p>
<p>Esta actualización se puede realizar presencialmente en una Oficina de Registro de usuarios de la plataforma
<strong class="Azul"> Cl@ve </strong> o de forma telemática con certificado o <acronym title="Documento Nacional de Identidad">DNI</acronym>
electrónico en la Sede Electrónica de la Agencia Estatal de Administración Tributaria. La relación de
Oficinas de Registro se encuentra publicada en el Portal <a href="http://administracion.gob.es">Punto de Acceso General</a>.</p>
</div>
<div id="p24h-error-bfp" title="Atención" style="display:none">
<p>Se ha detectado una modificación en las características del dispositivo desde el que está intentando
acceder al sistema <strong class="azul"> Cl@ve </strong> <acronym title="Número Personal de Identificación">PIN</acronym>.</p>
<p>Por su seguridad, para continuar con el trámite es necesario que obtenga un nuevo
<acronym title="Número Personal de Identificación">PIN</acronym>.</p>
</div>
<div id="p24h-fuera-de-servicio" title="Aplicación fuera de servicio" style="display:none">
<p id="msg-fuera-servicio"></p>
</div>
<!-- para ponerlos disponibles en la página que llama a registro previos -->
<div id="p24h-datos" style="display: none">
<input type="hidden" id="extrainfo" value=""/>
</div>
</body>
<script type="text/javascript">
//<![CDATA[
/*
* Si el parámetro entorno es "", activarFueraDeServicio no hace nada.
*/
//activarFueraDeServicio({entorno: "PRO",dia: "2016-11-16",desde: "14.30.00"});
/* Prioridad en el tratamiento de los lenguajes
* 1.- valor de la cookie aeat-language
* 2.- variable id en la queryString
* 3.- valor de la cabecera accept-language
*/
var qs = location.search.toQueryParams();
if ($('idi').value == 'es') {
/* solo se realiza la redirección desde la página en español */
var aeatLanguage = AEAT.getCookie("aeat-language");
var acceptLanguage = window.navigator.userLanguage || window.navigator.language;
var idi = qs.idi;
var qstr = "?ref=" + encodeURIComponent(unescape($('ref').value.stripTags())) + "&msg=" + $('msg').value ;
var h = $H(qs);
h.each(function(pair){
if (pair.key != 'ref') {
qstr = qstr + "&" + pair.key + "=" + pair.value;
}
});
var value = "";
if (aeatLanguage != null && aeatLanguage != undefined) {
value = aeatLanguage;
} else if (idi != null && idi != undefined) {
value = idi;
} else if (acceptLanguage != null && acceptLanguage != undefined){
value = acceptLanguage;
}
switch (value.substring(0,2)) {
case "ca":
case "CA":
case "ca_ES" : location.href="/es13/h/p24autc1.html"+qstr;break;
case "gl":
case "GL":
case "gl_ES" : location.href="/es13/h/p24autg1.html"+qstr;break;
case "va":
case "VA":
case "va_ES" : location.href="/es13/h/p24autv1.html"+qstr;break;
default: break;
}
}
/* para el resto de los los idiomas (no español) */
$('ref').value = (qs.ref != undefined) ? decodeURIComponent(unescape(qs.ref.stripTags())) : "/wlpl/SII-FACT/ws/fe/SiiFactFEV1SOAP";
$('msg').value = (qs.msg != undefined) ? qs.msg : "";
$('from').value = (qs.from != undefined) ? qs.from : "";
$('storksp').value = (qs.storksp != undefined) ? qs.storksp: "";
$('qaa').value = (qs.qaa != undefined) ? qs.qaa : "";
var bfp = new Fingerprint().get({screen_resolution: true, ie_activex: true});
$('bfprint').value = AEAT.rjust(""+bfp,10,'0');
//]]>
</script>
<noscript>
<!-- código para mostrar mensaje de javascript y/o cookies desactivadas -->
<div class="ui-dialog ui-widget ui-widget-content ui-corner-all" tabindex="-1" role="dialog" aria-labelledby="ui-dialog-title-avisoCookiesDesactivadas" style="display: block; z-index: 1002; outline: 0px; height: auto; width: 500px; top: 361.5px; left: 37%;">
<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">
<span class="ui-dialog-title" id="ui-dialog-title-avisoCookiesDesactivadas">Aviso</span>
<a href="#" class="ui-dialog-titlebar-close ui-corner-all" role="button"><span class="ui-icon ui-icon-closethick">close</span></a>
</div>
<div id="avisoCookiesDesactivadas" class="ui-dialog-content ui-widget-content" scrolltop="0" scrollleft="0" style="width: auto; min-height: 30.8px; height: auto;">
<div class="AEAT_bloque_errores">
<p>Para el correcto funcionamiento de la Sede Electrónica es necesario que su navegador permita la utilización de cookies y de javascript.</p>
<p>Si no sabe como hacerlo puede consultarlo en el siguiente enlace: </p>
<p>
<a class="enlace_no_decorado negrita" href="http://www.agenciatributaria.es/AEAT.internet/Ayuda/config_Sede.shtml" target="blank">
Requisitos técnicos para realizar trámites en la Sede Electrónica
</a>
</p>
<p>Para mas información sobre las cookies visite la <a class="enlace_no_decorado negrita"
href="https://www.agenciatributaria.gob.es/AEAT.sede/Inicio/_pie_/_Aviso_Legal_/_Aviso_Legal_.shtml" target="blank">
política de privacidad</a>.
</p>
<br/>
</div>
</div>
</div>
<div class="ui-widget-overlay" style="height: 955px; z-index: 1001;"></div>
</noscript>
</html>
I found the following code at https://community.softwaregrp.com/t5/UFT-Practitioners-Forum/xmlhttp-send-request-is-not-completing-for-soap-call/td-p/242616
And I made a few small modifications, specifically defining some variables that needed to be defined and placing a certificate name that I have installed on the machine.
They use many parameterization options however the ones that matter I think are:
And also:
In this case you can see that I have indicated
ALEXANDRU CATALIN TRANDAFIR - X4378072E
the name of the certificate, and it is that in Mozilla Firefox I have installed a certificate with that name.Screenshot 1:
And screenshot with answer:
And well, in the response you can see that the request has been made correctly, that is, it has been able to use the certificate and now it complains that the XML is not valid.
No es mi entorno preferido por lo que si estas familiarizado con PHP y con ese lenguaje te serviría para tu aplicación, te recomiendo este ebook técnico de implementación del SII donde hay ejemplos en php de todo el circuito de comunicación.
ACTUALIZACIÓN: Comunicación completa con el SII, con llamada y respuesta XML
Después de haber realizado la prueba del certificado, modifiqué el código para conseguir comunicar debidamente unas facturas de prueba y aquí coloco todos los ficheros:
El script
test.vbs
:El fichero con los datos de la llamada,
datos_xml.txt
:El fichero donde se ha escrito la respuesta recibida,
respuesta.txt
:I understand that the problem, as they say, is in the certificate, on occasion the MSXML2.ServerXMLHTTP also gave me problems, have you been able to try another one? Have you been able to contact someone in AEAT? It is possible that other users have the same consequences. We also recommend using postman or a similar application to test the solution without programming from the client computer, to rule out another issue.
have you seen this thread?:
link
Finally, I recommend that you try to ask on stackoverflow in English, from what little I have seen here, you are more concerned with how to answer than helping the question :)