我尝试连接到 AEAT (SII) 的 Web 服务以发送 XML 文件。我已经花费了大量时间进行研究和测试,但我非常接近放弃或推迟它,直到网络上有更多信息。
对于发送,我正在尝试使用 SERVERXMLHTTP 库这将是代码:
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)
请注意,strURL 是正确且经过验证的路径,而 strXML 是正确的 XML。
我可以看到的响应是:(我在查询末尾添加了完整的 TEXT 响应)
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'.
简而言之,我似乎缺少的是数字证书。也许我不知道如何调用证书,但我已经尝试了上千种方法,我无法弄清楚如何使用它:
选项 1:正如我所读到的,如果我们不指定证书,则选择存在的第一个证书(在我的情况下,我只认真安装了一个证书,但我可以理解其他东西正在带我
oWS.SetOption SXH_OPTION_SELECT_CLIENT_SSL_CERT, ""
选项2:很多人都说要找记录,比如:MY\这个信息对我来说很抽象。我设法看到证书位于以下路径的注册表中:
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>'
知道了这一点,我尝试了几种方法:
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"
选项 3:我还可以读到证书的 CN 名称应指定为 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"
无论如何......尝试找到并能够使用证书的一千种方法。但没有一个对我有用。答案总是一样的。
也许我错了?
证书可以通过多种方式定位
> MMC.exe
> Archivo > Agregar o quitar complementos...
> Certificados (Equipo local)
> FIREFOX
> Opciones > Avanzado... > Certificados > Ver Certificados...
> Sus Certificados:
> FNMT-RCM
> PEPITO GRILLO - 39301234P
在这两种情况下,我们都可以找到证书。找到后,如果我们双击证书,就会出现所有信息,例如我在选项 3 中尝试使用的 CN,或者我在注册表中找到的数字和字母序列(指纹 SHA1 的值)是 Windows 注册表中的内容)
留下一点vba,我有一个最后的说明:
由于我无法让它工作,我尝试使用 CURL.EXE。我现在不会详细说明我是如何发送数据的,但它给我的答案是相同的(答案转发到您必须输入 Cl@ve Pin 的表单”
简而言之,我没有做正确的事情,因为它没有捕获我的证书,但我不知道如何修复它。
附录 1:我添加了返回尝试发送到 AEAT 的 TEXT 响应:
<!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>
我在https://community.softwaregrp.com/t5/UFT-Practitioners-Forum/xmlhttp-send-request-is-not-completing-for-soap-call/td-p/242616找到了以下代码
并且我做了一些小的修改,特别是定义了一些需要定义的变量,并放置了一个我已经安装在机器上的证书名称。
他们使用许多参数化选项,但我认为重要的是:
并且:
在这种情况下,您可以看到我已经指明
ALEXANDRU CATALIN TRANDAFIR - X4378072E
了证书的名称,并且在 Mozilla Firefox 中我已经安装了具有该名称的证书。截图一:
并附有答案的截图:
好吧,在响应中,您可以看到请求已正确发出,也就是说,它已经能够使用证书,现在它抱怨 XML 无效。
这不是我的首选环境,所以如果您熟悉 PHP 并且使用该语言,它将对您的应用程序有用,我推荐这本关于 SII 实现的技术电子书,其中有整个通信电路的 php 示例。
更新:通过 XML 调用和响应完成与 SII 的通信
在测试了证书之后,我修改了代码以便能够正确地传达一些测试发票,我在这里放置了所有文件:
脚本
test.vbs
:带有通话数据的文件
datos_xml.txt
:已写入收到响应的文件
respuesta.txt
:正如他们所说,我知道问题出在证书中,有时 MSXML2.ServerXMLHTTP 也给我带来了问题,你能尝试另一个吗?你能联系到 AEAT 中的某个人吗?其他用户可能有同样的后果。我们还建议使用邮递员或类似的应用程序来测试解决方案,而无需从客户端计算机进行编程,以排除另一个问题。
你见过这个线程吗?:
关联
最后,我建议你尝试用英文在stackoverflow上提问,从我在这里看到的很少,你更关心如何回答而不是帮助问题:)