jueves, 20 de mayo de 2010

facturaE con .NET y C#

Si vas a implementar la facturación electrónica en tu aplicación .NET, y te has decidido por el formato facturaE, comprobarás que, a día de hoy, la documentación y las herramientas para trabajar con dicho lenguaje son muy escasas.

Si no sabes por donde empezar, estás leyendo las líneas que buscabas.

¿Por dónde empezamos? Bueno, la "facturaE" es un fichero XML firmado digitalmente. Por lo tanto lo primero que tenemos que hacer es generar ese XML. Como buen programador, lo primero que hay que hacer es leer la documentación oficial, así que en http://www.facturae.es/es-ES/Documentacion/EsquemaFormato/Paginas/Index.aspx encontramos la tabla de campos en PDF (guárdatela, te hará falta) y el esquema en formato XSD. A día de hoy existen 3 versiones de facturaE, la 3.0, 3.1 y 3.2. La más actual, 3.2, todavía no está lo suficientemente extendida, por lo que recomiendo trabajar (repito, a día de hoy, Mayo de 2010) con la versión 3.1.

El esquema XSD que encontramos nos facilitará mucho las cosas, ya que con él y con la herramienta xsd.exe vamos a generar una clase cuya instancia nos permitirá generar el XML de forma sencilla. Para generar el fichero *.cs necesitamos:
Con todo esto, podemos ejecutar el comando que nos dará el esperado fichero:

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\xsd" Facturaev31.xsd xmldsig-core-schema.xsd /c /n:FacturaElectronica

Ahora podemos importar ese fichero a nuestro proyecto y generar facturas electrónicas así de fácil:
//Crear objeto facturaE (obtenido a partir del XSD)
Facturae facturasE = new Facturae();

//Rellenar objeto facturaE con datos de tu factura
....

//Sacar datos a fichero
string fichero = "c:\\temp\\pruebas.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Facturae));
FileStream fs = new FileStream(fichero, FileMode.Create);
serializer.Serialize(fs, facturasE);
fs.Close();

Para rellenar el objeto facturaE correctamente, debes leer el PDF que contiene la tabla de campos; éste te indica qué campos son obligatorios, qué son, y el formato que deben tener. Y aquí es donde nos encontramos con un problema: hay algunos campos que han de tener 2, 4 ó 6 decimales, pero el tipo de datos es un "Double", ¿cómo especificamos que cuando se genere el XML salgan exactamente ese número de decimales? Bien, hay varias soluciones, la mía es la siguiente:

Generaremos 3 clases, de forma que cada clase contiene un atributo "Double". Al serializar en XML un objeto de estas clases, la representación numérica aparecerá con un número fijo de decimales. En realidad haremos 4 clases: crearemos un clase padre para no repetir el atributo en las 3 clases:
public abstract class DoubleFixedDecimalType
    {
        protected double value;

        public DoubleFixedDecimalType()
        {
            value = 0;
        }

        public DoubleFixedDecimalType(double value)
        {
            this.value = value;
        }

        [System.Xml.Serialization.XmlText()]
        public abstract string Value
        {
            get;
            set;
        }
    }

    public class DoubleTwoDecimalType : DoubleFixedDecimalType
    {
        public DoubleTwoDecimalType() : base() { }

        public DoubleTwoDecimalType(double value) : base(value) { }

        public static implicit operator double(DoubleTwoDecimalType o)
        {
            return o.value;
        }

        public static implicit operator DoubleTwoDecimalType(double value)
        {
            return new DoubleTwoDecimalType(value);
        }

        [System.Xml.Serialization.XmlText()]
        public override string Value
        {
            get { return value.ToString("F2", System.Globalization.CultureInfo.InvariantCulture); }
            set { this.value = System.Convert.ToDouble(value); }
        }
    }

    public class DoubleFourDecimalType : DoubleFixedDecimalType
    {
        public DoubleFourDecimalType() : base() { }

        public DoubleFourDecimalType(double value) : base(value) { }

        public static implicit operator double(DoubleFourDecimalType o)
        {
            return o.value;
        }

        public static implicit operator DoubleFourDecimalType(double value)
        {
            return new DoubleFourDecimalType(value);
        }

        [System.Xml.Serialization.XmlText()]
        public override string Value
        {
            get { return value.ToString("F4", System.Globalization.CultureInfo.InvariantCulture); }
            set { this.value = System.Convert.ToDouble(value); }
        }
    }

    public class DoubleSixDecimalType : DoubleFixedDecimalType
    {
        public DoubleSixDecimalType() : base() { }

        public DoubleSixDecimalType(double value) : base(value) { }

        public static implicit operator double(DoubleSixDecimalType o)
        {
            return o.value;
        }

        public static implicit operator DoubleSixDecimalType(double value)
        {
            return new DoubleSixDecimalType(value);
        }

        [System.Xml.Serialization.XmlText()]
        public override string Value
        {
            get { return value.ToString("F6", System.Globalization.CultureInfo.InvariantCulture); }
            set { this.value = System.Convert.ToDouble(value); }
        }
    }
Como se puede apreciar en las declaraciones, se puede convertir implícitamente un objeto "Double" a cualquier instancia de estas clases, lo cual nos facilita el trabajo ya que podemos asignar directamente un valor numérico.

Ahora queda reemplazar, en el fichero *.cs generado, el tipo de datos "Double" de las propiedades que deben tener un número fijo de decimales (ver tabla de campos) por alguno de estos 3.

Para ahorrarte algo de trabajo, aquí tienes para descargar dos ficheros, generados con xsd.exe y modificados para sacar correctamente el número de decimales, correspondientes a las versiones 3.1 y 3.2 de la facturaE: Haz click aquí para descargar.

Llegados a este punto ya puedes generar tu facturaE. Puedes comprobar la validez de tu XML en la web del ministerio de industria, turismo y comercio. Tu fichero debe pasar correctamente la validación de formato y, si has leído bien la tabla de campos y los importes de tu factura son correctos, también debe pasar con éxito la validación contable. Pero nos falta una cosa importante, la firma.

Para poder firmar el XML, necesitas un certificado digital expedido por una entidad certificadora reconocida. Puedes pedirlo en la web de la fábrica nacional de moneda y timbre.

Una vez tengas el certificado (fichero en formato *.cer, *.pfx...) te podrás hacer uso de la clase X509Certificate2 para cargarlo en memoria y realizar la firma. Llegados a este punto hay varias formas de cargar el certificado: a partir del fichero físico, buscando un certificado instalado en el equipo, presentando una lista de certificados y dando al usuario la posibilidad de elegir uno... En este ejemplo vamos a leer un certificado instalado en el equipo, usando asp.net. El usuario sobre el que se ejecuta asp.net no tiene suficientes permisos para leer la clave privada (necesaria para firmar) del certificado si lo importamos con el asistente de importación (importará la clave privada en el almacén del usuario con el que hemos iniciado sesión).

Para importar un certificado y poder usarlo con asp.net, lo haremos siguiendo estos pasos (repito que esto sólo es necesario para usar certificados con asp.net):

  1. Entra al sistema como administrador
  2. Haz click en Inicio -> Ejecutar. Escribe mmc y pulsa intro
  3. Pulsa en Archivo -> Agregar o quitar complemento, y haz click en "Agregar"
  4. Busca en la lista "Certificados" y haz doble click sobre él. Elige "cuenta de equipo" y pulsa siguiente
  5. Elige la opción en función de donde se encuentre el certificado (equipo local o remoto)
  6. Pulsa finalizar (aparece "Certificados" en la lista de complementos agregados)
  7. Pulsa "Aceptar"
  8. Despliega el nodo "Certificados"
  9. Haz click con el botón DERECHO en la carpeta "Personal" y elige "Todas las tareas -> Importar"
  10. Pulsa siguiente, busca y elige el certificado
  11. Elige el almacén "Personal" para guardar el certificado y finaliza
Ahora vamos a dar permisos al directorio MachineKeys:
  1. Navega hasta el directorio donde se almacenan las claves: C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
  2. Asegúrate de NO estar usando el modo compartido simple de archivos (herramientas -> opciones de carpeta... -> Pestaña ver, al final del todo)
  3. Pulsa con el botón derecho en el directorio MachineKeys. Elige "Propiedades" y luego la pestaña "Seguridad"
  4. Añade el usuario IUSR_*** y dale permisos para todo (control total)
Una vez tenemos ya el certificado almacenado, podemos usarlo para firmar el XML generado. Vamos a firmarlo con XAdES. Pero , ¿cómo? Bien, todavía no he dado con la forma correcta. Pero puedo decirte cómo hacerlo para que veas cómo queda el fichero, pero sólo a modo de prueba. ¿Por qué? Porque lo haremos con una librería licenciada para usarla con factOffice (es un plugin para trabajar con facturas electrónicas desde MsOffice) y no se permite usarla fuera del complemento.

Desde la web de factOffice encontramos un enlace a dicha librería (Descargar) que podemos incluir en nuestro proyecto, repito, para pruebas sólamente. También necesitaremos el archivo BouncyCastle.Crypto.dll que podemos encontrar en el código fuente de factOffice. Una vez importadas estas dos librerías, firmar el xml es tan sencillo como esto:
XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = true;
    doc.Load("c:\\temp\\pruebas.xml");

    //Obtener certificado
    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certCollection = store.Certificates.Find(X509FindType.FindBySubjectName, "NOMBRE DE LA ENTIDAD", false);

    if (certCollection.Count == 1)
    {
        //Firmar con XAdES-EPES (formato básico con la mínima información)
        XadesSignature xadesSignature = new XadesSignature();
        xadesSignature.XadesEpes(doc, "Nombre Entidad", certCollection[0], "Nombre Aplicación");
        //Guardar versión firmada
        doc.Save("c:\\temp\\pruebas_firmado.xml");
    }

    //Cerrar almacén de certificados
    store.Close();

Llegados a este punto tenemos generado el fichero XML de forma que pasaría la validación de formato, la validación contable y la validación del certificado.

Pronto postearé la forma de realizar la firma sin usar la librería cedida por BackTrust y así poder incluir tranquilamente el firmado de XAdES en tu aplicación.

Actualización 20/05/2010
Lo prometido es deuda (aunque esto sólo se dice cuando se cumple la promesa) y aquí os ofrezco una forma de firmar facturas electrónicas con XAdES usando librerías que se pueden distribuir tranquilamente en vuestra aplicación.

Lo que he hecho es usar IKVM.NET para convertir las librerías Java, ofrecidas por el ministerio de industria, turismo y comercio, a librerías dll. Usando jar2ikvmc podemos crear un script para usar con ikvmc, de forma que tendrá en cuenta las dependencias de cada fichero jar.
Una vez convertidos los jar a dll, tal cual, intenté hacer una firma XAdES-EPES, tal y como se explica en los ejemplos del ministerio,  pero no funcionó debido a que el programa no reconocía la política de firma. El programa estaba intentando acceder a un fichero para cargar dinámicamente los distintos tipos de políticas de firma, para luego crear una instancia de la clase encargada de gestionar dicha política. Pero todo este proceso no funcionó con las librerías convertidas a dll. Así que tuve que modificar los fuentes java para permitir especificar las clases para la política de firma en tiempo de compilación (no es tan dinámico, pero ¡funciona en .net!), compilar y crear los ficheros jar, y volver a crear las dll's. Toda la información para usar/modificar/recompilar los fuentes se encuentra aquí.

Una vez hecho esto he conseguido firmar facturas en formato facturaE, con XAdES-EPES, a partir de un certificado almacenado en un fichero pfx. Para hacerlo tú también sigue estos pasos:
    • Incluye las siguientes dll's en tu proyecto C# (las encuentras en la descarga anterior): 
      • commons-logging-1.1 
      • facturaE_adittional
      • IKVM.OpenJDK.Core
      • IKVM.OpenJDK.Security
      • IKVM.OpenJDK.Text
      • IKVM.OpenJDK.Util
      • IKVM.OpenJDK.XML.API
      • IKVM.OpenJDK.XML.Parse
      • IKVM.Runtime
      • MITyCLibAPI-1.0.4
      • MITyCLibCert-1.0.4
      • MITyCLibPolicy-1.0.4
      • MITyCLibTrust-1.0.4
      • MITyCLibTSA-1.0.4
      • MITyCLibXADES-1.0.4
      • xmlsec-1.4.2-ADSI-1.0
      Nota: Algunos usuarios me han informado de que la dll IKVM.OpenJDK.XML.Parse no se copia automáticamente al directorio del resultado de la solución. Llevadlo en cuenta por si es vuestro caso.
      • Incluye los siguientes "using" en el código:
      • using java.security;
        using java.io;
        using java.util;
        using java.security.cert;
        using javax.xml.parsers;
        using es.mityc.javasign.pkstore;
        using es.mityc.javasign.pkstore.keystore;
        using es.mityc.javasign.trust;
        using es.mityc.javasign.xml.xades.policy;
        using es.mityc.firmaJava.libreria.xades;
        using es.mityc.javasign.xml.refs;
        using es.mityc.firmaJava.libreria.utilidades;
        using org.w3c.dom;
        using sviudes.blogspot.com; 
      • Usa este código para firmar facturas:
      • private Document LoadXML(string path)
        {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         dbf.setNamespaceAware(true);
         return dbf.newDocumentBuilder().parse(new BufferedInputStream(new FileInputStream(path)));
        }
        
        private X509Certificate LoadCertificate(string path, string password, out PrivateKey privateKey, out Provider provider)
        {
         X509Certificate certificate = null;
         provider = null;
         privateKey = null;
        
         //Cargar certificado de fichero PFX
         KeyStore ks = KeyStore.getInstance("PKCS12");
         ks.load(new BufferedInputStream(new FileInputStream(path)), password.ToCharArray());
         IPKStoreManager storeManager = new KSStore(ks, new PassStoreKS(password));
         List certificates = storeManager.getSignCertificates();
        
         //Si encontramos el certificado...
         if (certificates.size() == 1)
         {
          certificate = (X509Certificate)certificates.get(0);
        
          // Obtención de la clave privada asociada al certificado
          privateKey = storeManager.getPrivateKey(certificate);
        
          // Obtención del provider encargado de las labores criptográficas
          provider = storeManager.getProvider(certificate);
         }
        
         return certificate;
        }
        
        private void btnFirmar_Click(object sender, EventArgs e)
        {
         PrivateKey privateKey;
         Provider provider;
         X509Certificate certificate = LoadCertificate("c:\\temp\\certificado.pfx", "contraseña", out privateKey, out provider);
        
         //Si encontramos el certificado...
         if (certificate != null)
         {
          //Política de firma (Con las librerías JAVA, esto se define en tiempo de ejecución)
          TrustFactory.instance = es.mityc.javasign.trust.TrustExtendFactory.newInstance();
          TrustFactory.truster = es.mityc.javasign.trust.MyPropsTruster.getInstance();
          PoliciesManager.POLICY_SIGN = new es.mityc.javasign.xml.xades.policy.facturae.Facturae31Manager();
          PoliciesManager.POLICY_VALIDATION = new es.mityc.javasign.xml.xades.policy.facturae.Facturae31Manager();
        
          //Crear datos a firmar
          DataToSign dataToSign = new DataToSign();
          dataToSign.setXadesFormat(EnumFormatoFirma.XAdES_BES); //XAdES-EPES
          dataToSign.setEsquema(XAdESSchemas.XAdES_132);
          dataToSign.setPolicyKey("facturae31"); //Da igual lo que pongamos aquí, la política de firma se define arriba
          dataToSign.setAddPolicy(true);
          dataToSign.setXMLEncoding("UTF-8");
          dataToSign.setEnveloped(true);
          dataToSign.addObject(new ObjectToSign(new AllXMLToSign(), "Descripcion del documento", null, "text/xml", null));
          dataToSign.setDocument(LoadXML("c:\\temp\\unsigned.xml"));
        
          //Firmar
          Object[] res = new FirmaXML().signFile(certificate, dataToSign, privateKey, provider);
        
          // Guardamos la firma a un fichero en el home del usuario
          UtilidadTratarNodo.saveDocumentToOutputStream((Document)res[0], new FileOutputStream("c:\\temp\\signed.xml"), true);
         }
        }
        

      Si ejecutas este código (cambiando las rutas del certificado, y los xml) se generará un xml que puedes validar aquí y comprobar que la firma es correcta. Este ejemplo usa la política de firma del formato 3.1 de facturaE, si quieres cambiar la política de firma tendrás que cambiar la asignación de las variables PoliciesManager.POLICY_SIGN y PoliciesManager.POLICY_VALIDATION.

      No he probado a firmar facturas con otro tipo de firma, igual funciona, igual no. En el fichero que puedes descargar más arriba incluyo todas las librerías del ministerio convertidas a dll, así como los fuentes modificados por si quieres hacer más modificaciones. Si necesitas más librerías de IKVM.NET las puedes descargar desde su web oficial.

      Espero que este post haya sido de ayuda.

      258 comentarios:

      1. Saludos cordiales, tengo la siguiente pregunta, todo esto es aplicable hoy en día???

        ResponderEliminar
      2. Este artículo tiene ya más de 4 años. En su día lo implementé y funcionó perfectamente. Puede que hoy en día existan otras soluciones para .NET, pero como ya no trabajo con .NET, no lo sé.

        ResponderEliminar
        Respuestas
        1. Sergio he intentado introducir estas clases en vb.net y me da errores, soy nulo en cs. alguien las ha podido utilizar, puede indicar como.
          no soy capaz de formatear los campos double a los decimales correspondiente. si alguien puede ayudarme
          Saludos

          Eliminar
      3. En que framework realizaste el desarrollo, estoy probando el código y tengo un error con el
        using es.mityc.javasign.pkstore.keystore;

        ResponderEliminar
      4. salvo estos comentarios dentro de la firma: http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdfPolítica de Firma FacturaE v3.1. el proceso funciona...

        ResponderEliminar
      5. Saludos, tengo problemas al ejecutar este codigo
        C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\xsd" Facturaev31.xsd xmldsig-core-schema.xsd /c /n:FacturaElectronica
        estoy haciendo en windows 8, c#

        ResponderEliminar
      6. Estoy intentando actualizar a la última versión del ministerio. Al intentar generar xalan-2.7.1.dll obtengo el warning IKVMC0100: Class "org.apache.xerces.parsers.SAXParser" not found (entre otros).

        ResponderEliminar
      7. una pregunta tendre problemas en algun momento con las librerias que usa el proyecto es decir que se caduquen o algo asi alguien me podria sacar de esa duda

        ResponderEliminar
      8. porque a mi me funciona correctamente no tengo ningun problema solo quiero sacarme la duda sobre las librerias si fueran tan amables de contestarme

        ResponderEliminar
      9. Hola Ricardo. Las librerías no tienen caducidad. De hecho este post tiene ya 4 años y medio y sigue funcionando ;)

        ResponderEliminar
      10. muchas gracias ahora si me siento mas tranquilo

        ResponderEliminar
      11. una pregunta el ejemplo mostrado sirve con un certificado con extensión .p12 ya que el ejemplo usa un .pfx

        ResponderEliminar
      12. Favor me podrian ayudar como cargar un certificado p12.. mil gracias

        ResponderEliminar
      13. Compilo y funciono correctamente. Gracias

        ResponderEliminar
      14. Hola Sergio! Mi solución me indica que los DLL que pasaste a .NET no tienen un String Name Key. Podrías por favor si es posible compartir las soluciones que generan los DLL para poder firmarlos mediante mi SNK o si es posible y tienes alguno firmarlos mediante esto. Sería de gran utilidad y me ahorraría mucho tiempo ya que tu solución es la única que me funciona en .NET. Muchas gracias!

        ResponderEliminar
      15. Hola,

        Al intentar enviar una factura por la plataforma FACE en la version 3.2 cuando estoy indicando el campo lo seleccion de la siguiente manera:

        Items[1].RoleTypeCode = RoleTypeCodeType.Item02;

        Pero luego al pasarlo a XML no me pasa el campo... ¿Puedo indicar a piñon que quiero en ese campo el texo 02?

        Un saludo, Javi

        ResponderEliminar
      16. Me respondo yo mismo...
        hay que añadir la linea

        Items[1].RoleTypeCodeSpecified = true;

        ResponderEliminar
      17. Hola buenas tardes
        Se puede cargar un certificado ya instalado? sin necesidad de tener el fichero

        Gracias

        ResponderEliminar
      18. Hola Icu:

        échale una ojeada a:
        http://forums.asp.net/t/1195166.aspx?Show+programmatically+Choose+a+digital+certificate+
        http://stackoverflow.com/questions/6304773/how-to-get-x509certificate-from-certificate-store-and-generate-xml-signature-dat

        ResponderEliminar
      19. Sergio eres brutal, llevo todo el día más liado que moño de vieja y por fin he dado con tu código y zas, a la primera.
        Como soy un negado en C# os paso el proyecto en VB que seguro que hay más de uno como yo.
        https://mega.co.nz/#!8ctylCII!0HaBl6iLz76jwL6jJweu4xZnuJdVwajfVqgDMFfyBmI

        Y bueno, aprovecho que el 15 se nos acaba el tiempo, tenemos el xml firmado y ahora como lo subimos, desde https://face.gob.es/es/remitir-factura sólo admite ficheros .xsig
        Voy por fases, primero XML, luego firmado con eCoFirma, y enviado con https://face.gob.es/es/remitir-factura con esto cubro el 15 de enero de 2015. Ahora sin prisas me gustaría implementarlo todo y me gustaría saber si se puede subir sólo firmado o hay que hacer el xsig.
        Saludos y otra vez gracias al que lo ha hecho posible.

        ResponderEliminar
        Respuestas
        1. Sergio y Jaime Mambiela GRACIAS. Es justo lo que buscaba.
          He adaptado el método LoadCertificate para que admita un certificado de NET, así, con NET me ha resultado mucho más fácil abrir el selector de certificados de Windows. Con Java no he encontrado la manera, ni con las librerías de mityc.
          El método para mostrar el selector y que el usuario elija está en MSDN: https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2ui%28v=vs.110%29.aspx
          Adaptadlo para que el método devuelva el certificado seleccionado.

          Y en LoadCertificate (de este post), en lugar de cargarlo de un archivo (es engorroso pedirle a un cliente que exporte su certificado a un archivo), se puede convertir el certificado de NET a Java con .Export. Así (VB NET):

          Dim cert_NET As System.Security.Cryptography.X509Certificates.X509Certificate = Buscador.seleccionarCertNET()
          ks.load(New ByteArrayInputStream(cert_NET.Export(X509Certificates.X509ContentType.Pkcs12, password)), password.ToCharArray)

          el resto del método queda igual.
          En Buscador.seleccionarCertNET() tengo el método citado de MSDN que devuelve un X509Certificate de NET.
          Lo tengo metido en un módulo para que no choquen los espacios de nombres NET y Java.
          Ojo con ese choque, que puede dar quebraderos de cabeza, pues el tipo X509Certificate se llama igual.
          ¡Gracias otra vez a ambos!

          Eliminar
        2. por cierto, obviamente mi ks.load(...) sustituye al del código original. En lugar de leer de un archivo lee del array de bytes entregado por NET.

          Eliminar
        3. Aquí paso el enlace al proyecto de VB NET con selector de certificados nativo.
          Para aliviar el "deployment" he quitado algunas referencias a DLLs que al parecer no se usan (siguen estando en la carpeta raíz).
          Espero que sea de utilidad.
          https://mega.co.nz/#!UNFDnZzL!gJFRzg5zzVfglXQFkk8IxDlbGygD1AhzZuTaaiDyDkE
          De nuevo agradecimientos a Sergio por publicar este post y a Jaime Mombiela por traducir el proyecto a VB.
          Saludos.

          Eliminar
        4. Buenas Ivan,
          Muchas gracias por preparar el proyecto para obtener los certificados del equipo.
          Estoy firmando una factura, directamente con tu proyecto y me encuentro con un problema, en el TAG: me esta poniendo un caracter NULL delante de cada caracter del nombre, esto hace que el validador de facturas directamente ni sepa leer el xml.
          El programa de FacturaE de escritorio, al firmar con el mismo certificado me pone los caracteres \00 en substitución del null. He probado a substituir a mano, entonces carga el xml, pero me dice que la firma no es valida, no se si es por haberlo modificado a mano.

          No has tenido este problema al firmar con tu código?

          Muchas gracias tambien a Sergio por publicar este gran artículo.

          Eliminar
        5. Buenas Ivan,
          Muchas gracias por preparar el proyecto para obtener los certificados del equipo.
          Estoy firmando una factura, directamente con tu proyecto y me encuentro con un problema, en el TAG: me esta poniendo un caracter NULL delante de cada caracter del nombre, esto hace que el validador de facturas directamente ni sepa leer el xml.
          El programa de FacturaE de escritorio, al firmar con el mismo certificado me pone los caracteres \00 en substitución del null. He probado a substituir a mano, entonces carga el xml, pero me dice que la firma no es valida, no se si es por haberlo modificado a mano.

          No has tenido este problema al firmar con tu código?

          Muchas gracias tambien a Sergio por publicar este gran artículo.

          Eliminar
        6. Hola.
          Pues no me ocurre lo que dices. A mi me va perfecto, puedo importarlas como Emitidas en la aplicación FacturaE y validarlas con tres Ok en la web oficial.
          No entiendo a qué te refieres con el TAG. El único Tag que uso en el proyecto es el del botón de 'explorar archivo' para guardar la ruta del xml firmado.
          Por lo que sé, un carácter null siempre es \00, pero pienso que no debería haberlos en un archivo de texto, pues a menudo indica final de cadena.
          Quizá todo venga de la aplicación que uses para generar la factura en xml.
          O quizá sea el tipo de codificación con que se graba el xml (UTF-8, etc).
          ¿Con lo de "un caracter NULL delante de cada caracter del nombre" te refieres al nombre del archivo? Porque eso sí que me suena todavía más raro.

          Yo uso Windows 7 32bits, no sé si eso puede afectar al funcionamiento de las librerías de IKVM.
          En CPU destino del proyecto NET está puesto x86.
          No se me ocurre nada más.
          Saludos.

          Eliminar
        7. bueno, creo que con \00 te refieres a que te escribe esos caracteres "\00" en lugar del null. Rarísimo, la verdad.
          Pero insisto, me parece raro que un archivo de texto contenga nulls. Nunca me ha pasado.

          Eliminar
        8. Ivan, en primer lugar muchisimas gracias por tu aportación.
          He estado probando el codigo del proyecto VB y me parece que me pasa algo muy raro.
          En el pc tengo instalados dos certificados (ambos son correctos y opertativos. funcionan perfectamente en la web de FACE y de la AEAT).
          Si desde el proyecto VB elijo el primero de los dos certificados que me aparece en el almacén me da una exepción en la linea
          ks.load(New ByteArrayInputStream(cert_NET.Export(X509Certificates.X509ContentType.Pkcs12, "1234")), "1234".ToCharArray)
          En concreto el mensaje de error es:
          No se controló system.Security.Cryptography.CryptographicException
          Message=Clave no válida para utilizar en el estado especificado.
          En cambio si elijo el segundo certificado funciona de maravilla.
          Alguna idea?

          Eliminar
        9. Hola Francesc. Pues no sé qué puede ser, y miedo me da que me pase a mi también, pues aún no he mandado esto a producción ni he probado con otro certificado que no sea el mío, de persona física 'pelao'.
          En esa línea meto la contraseña "1234" por poner algo, pues parece que la pide para exportar a array de bytes, y que a continuación se usa en el lado Java.

          La verdad es que nunca antes había tratado con certificados, y lo que hice aquí no sé siquiera si es una chapuza para pasarlo de NET a Java. O igual es la forma correcta.
          Tampoco sé si un certificado que hayamos usado o cargado, luego hay que "cerrarlo" de alguna forma. Es decir, igual que se hace Load, que luego haya un "unload". Quizá se refiera a eso lo que dice el error de "en el estado especificado".
          O viendo la ayuda de NET del Export, puede que el certificado no sea exportable. Yo probaría de exportarlo manualmente desde Windows, a ver si lo permite.
          O quizá tenga que ver con los permisos de la aplicación (KeyContainerPermission).

          Si das con una solución coméntalo, porfa.
          Suerte.

          Eliminar
        10. por cierto, aviso de que en el código que muestra la ventana para elegir certificados, usé el filtro de texto "FNMT". Si usamos otros certificados (DNIe, CatCert, etc) seguramente habrá que cambiar esto.
          Lo hice así porque tengo una lista enorme de certificados (¿?¿) y es un agobio tener que buscar cada vez.
          Suerte!

          Eliminar
        11. Francesc, veo que el objeto X509Certificate2 tiene un método Reset. Igual sirve de algo.
          Según la ayuda: "Este método se puede utilizar para restablecer el estado del certificado. También libera todos los recursos asociados al certificado."

          Eliminar
        12. Ivan, ya he resuelto el misterio. El problema es que el certificado que no me funcionaba esta marcado como "no exportable" en el almacén de certificados. Lo he desinstalado y vuelto a instalar marcandolo como exportable y tema resuelto

          Eliminar
        13. Fantástico! Me consuela saber que no era nada más 'dramático'. Tomo nota. Gracias.

          Eliminar
      20. Parece mentira pero la solición estaba delante y yo no la veía, el archivo de salida del proyecto de nuestro bloger es el .xsig, basta cambiar la extención, lo he puesto en un portal de acceso y perfecto.
        Por otra parte por si llega alguno haciendo el XLM y ya que en la red no hay casi nada, aprovecho este mágnífico Blog para poneros uno donde podréis ver:
        https://mega.co.nz/#!QdcSRZpJ!iWBAFSDB_zLqL18kc2ASksUnGa00K5fJIy2ccpJx9Lw
        Etiqueta Modality donde vemos si es de una varias facturas
        La estructura basica de un Vendedor Etiqueta SellerParty y la del Comprador Etiqueta BuyerParty con sus Centros.
        Y la estructura de una Factura con 3 detalles uno con Impuesto, otra con Impuesto a 0 y otra exenta.
        Notar que en las Etiquetas TaxesOutputs totalizamos todas menos las exentas.
        Notar que en las Etiquetas InvoiceLine es requerido el precio unitario Etiqueta UnitPriceWithoutTax, por lo que en caso de precios por tramos no queda mas remedio que sacar la media o el precio total en caso de ser algo no medible.
        En el caso de no sujetos tendréis que poner el bloque Etiqueta SpecialTaxableEvent
        En cuanto a identificar la factura la solución que me han dado en FACe es poner los datos en Etiqueta ReceiverContractReference de todas las líneas, en mi ejemplo pongo la ciudad, la póliza y el cargo Año/Mes.
        Saludos

        ResponderEliminar
      21. ¿Tenéis algún ejemplo de como rellenar el objeto facturaE?

        ResponderEliminar
      22. La administración por lo que tengo entendido requiere facturaE 3.2 y el ejemplo de firma utiliza dll que sólo firma 3.0 y 3.1, podria alguien decirme como solucionarlo

        Gracias

        ResponderEliminar
        Respuestas
        1. ¿Has encontrado la solución?

          Eliminar
        2. A mí me funcionó, bajándome el esquema xsd de la 3.2 (¡¡ojo¡¡ ,la 3.2, si te bajas el 3.2.1 , el validador no te dejará) en http://www.facturae.gob.es/formato/Paginas/version-3-2.aspx

          el validador es la url --> http://sedeaplicaciones2.minetur.gob.es/FacturaE/

          Siguiendo el ejemplo, me valido los 3 modos (formato, contable y firma)

          Saludos.

          Eliminar
        3. Cierto. No hay validador para 3.2.1 y me lo confirmaron también en el Soporte. Y las facturas 3.2.1 firmadas, según me comentaron, se pueden validar sus firmas en https://valide.redsara.es/valide/

          No obstante he vuelto al formato 3.2 con política de firma 3.1 (presente en este artículo). ya que es mejor tener la certeza que pasa también la validación contable y de formato, por si las moscas.

          Eliminar
      23. Hola, ¿podríais indicarme el código para poder leer el almacén de certificados?

        ResponderEliminar
      24. Buenas,
        Estoy trabajando en un proyecto y el código me funciona todo bien en local, me genera el archivo firmado y me pasa la validación en [ http://sedeaplicaciones2.minetur.gob.es/FacturaE/index.jsp ] , pero al subir la publicación al servidor me falla y me da el siguiente error:
        Error de código fuente:

        Se ha generado una excepción no controlada durante la ejecución de la solicitud Web actual. La información sobre el origen y la ubicación de la excepción pueden identificarse utilizando la excepción del seguimiento de la pila siguiente.

        Seguimiento de la pila:


        [SecurityException: Error de solicitud de permiso de tipo 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.]
        java.io.FileDescriptor.open(String , Int32 , Int32 ) +430
        java.io.FileDescriptor.openReadOnly(String ) +21
        java.io.FileInputStream.open(String ) +16
        java.io.FileInputStream..ctor(File file) +201
        java.io.FileInputStream..ctor(String name) +67
        Bridge.Web.Controllers.FacturasController.LoadCertificate(String path, String password, PrivateKey& privateKey, Provider& provider) in C:\Users\jsoler\Desktop\bridgee\Bridge\Bridge.Web\Controllers\FacturasController.cs:669
        Bridge.Web.Controllers.FacturasController.Firmar(String certificateURI, String xmlPath, String numero) in C:\Users\jsoler\Desktop\bridgee\Bridge\Bridge.Web\Controllers\FacturasController.cs:704
        Bridge.Web.Controllers.FacturasController.Preview2(Factura factura, EditMode modo) in C:\Users\jsoler\Desktop\bridgee\Bridge\Bridge.Web\Controllers\FacturasController.cs:608
        lambda_method(ExecutionScope , ControllerBase , Object[] ) +107
        System.Web.Mvc.<>c__DisplayClass1.b__0(ControllerBase controller, Object[] parameters) +15
        System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +251
        System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +31
        System.Web.Mvc.<>c__DisplayClassd.b__a() +88
        System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +534
        System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312
        System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +694
        System.Web.Mvc.Controller.ExecuteCore() +136
        System.Web.Mvc.<>c__DisplayClass8.b__4() +51
        System.Web.Mvc.Async.<>c__DisplayClass1.b__0() +21
        System.Web.Mvc.Async.<>c__DisplayClass8`1.b__7(IAsyncResult _) +15
        System.Web.Mvc.Async.WrappedAsyncResult`1.End() +77
        System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +39
        System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +454
        System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +263

        esto me sucede en la linea: KeyStore ks = KeyStore.getInstance("PKCS12"); y por el error e probado en dar permisos máximos al IIS en la carpeta donde se encuentra el certificado, instalar el certificado en el servidor, etc... pero no encuentro que puede ser ya que sigue dándome el mismo error. Podría ser algo de permisos que me faltan al web.config??? o bien algún complemento que me falte en el servidor para los certificados? o simplemente que no tengo acceso al keystore??

        Agradecería cualquier ayuda ya que es bastante urgente.

        Mi aplicación usa: c# + asp.net + MVC...
        La tengo en un servidor: Windows Server 2008 R2 Standard


        Gracias de antemano.

        ResponderEliminar
      25. ¿Como firmáis para el formato 3.2? Estoy probando el ejemplo y sólo aparece para 3.0 y 3.1 y NO es válido para las AAPP.

        ResponderEliminar
      26. Buenas, ¿Hay alguna forma de cargar el certificado del almacén? Es decir: ¿de NO precisar el certificado exportado en un archivo (con clave privada y contraseña)?

        ResponderEliminar
      27. Buenos días !!!

        Yo también tengo otro problema, pero es a la hora de subir la factura electrónica, os cuento:

        Tengo hecha la factura electrónica de pruebas (datos no reales) y ya he comprobado que estaba correcta a través del servicio de validación en http://sedeaplicaciones2.minetur.gob.es/FacturaE/ dándonos ok tanto en validación del formato, contable y firma.
        Quiero enviar la factura de pruebas en el entorno STAGING https://se-face-webservice.redsara.es/sspp?wsdl , que es el entorno destinado para pruebas.

        Desde .Net y con c# hago lo siguiente.

        -Añado referencia web a servicio web
        - Ejecuto el código siguiente

        proveedores.SSPPWebServiceProxyService servicioProveedores = new proveedores.SSPPWebServiceProxyService();

        servicioProveedores.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(url_Certificado, pwd));


        proveedores.SSPPFactura factura = new proveedores.SSPPFactura();

        factura.correo = "correo@correo.es";

        factura.fichero_factura = new proveedores.SSPPFicheroFactura();
        factura.fichero_factura.factura = facturaEnBase64 ;
        factura.fichero_factura.nombre = "Factura_Firmada.xsig";
        factura.fichero_factura.mime = "application/xml";

        //Llamo al método del webService para enviar la factura

        proveedores.SSPPResultadoEnviarFactura resultadoEnvioFactura = servicioProveedores.enviarFactura(factura);

        Me aparece el siguiente error:

        en System.Web.Services.Protocols.SoapHeaderHandling.SetHeaderMembers(SoapHeaderCollection headers, Object target, SoapHeaderMapping[] mappings, SoapHeaderDirection direction, Boolean client)
        en System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
        en System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
        en FACe.proveedores.SSPPWebServiceProxyService.enviarFactura(SSPPFactura facturaWS)

        No se entendió el encabezado SOAP Security.

        ¿Algún colega de profesión en la misma situación?

        Gracias anticipadas.

        ResponderEliminar
        Respuestas
        1. Buenos días!

          Cuando añado el Web service de proveedores al proyecto en Visual studio, se me carga, pero el fichero References.cs aparece vacío

          Es como si no se me cargaran los métodos que me permiten lllamar a la libreria, sin embargo con los wsdl de Organismos y Gestion de unidades no me pasa, me va perfecto.

          Alguién tiene la solución?? a alguién mas le ha apsado?

          Eliminar
        2. Buenos días!!

          Al añadir el Web service de proveedores a visual studio, no se completa el fichero References.cs
          Lo que hace que no pueda ver los métodos ni clases para llamar al WebService

          No entiendo que estoy haciendo mal. Alguién puede ayudarme??

          Eliminar
        3. Creo que muchos estamos en la misma situación. Voy a seguir investigando a ver si doy como evitar ese error.

          Eliminar
      28. Hoy por fin he presentado mi primera factura del Ministerio de Defensa en FACe, con lo que igual puedo aclarar algunos puntos.
        La presentación la he hecho en FACe a través del portal de remisión de facturas en https://face.gob.es/es/remitir-factura, el fichero se ha cargado sin problemas y se ha enviado y recibido de la misma forma, una vez terminado me ha dado un justificante en PDF y he podido consular la factura en la base de datos de FACe.
        El fichero está hecho con el formato 3.2 y firmado con las lógicas de Sergio (con la política de firmas de 3.1) y no me ha dado problemas por lo que eso que dicen de que sólo sirve la política de firmas de 3.2 no es correcto, al menos en la entrada del portal.
        En cuanto a la carga del certificado, a mí me parece muy cómoda la forma usada por Sergio de usar un archivo, la he usado en escritorio y ASP sin mayores problemas y agradecería que me dijerais porque no os gusta, igual me dejo algo atrás.
        Por otro lado he visto que ya los organismos oficiales en muchos casos sólo quieren las facturas de más 5000 (no sé por qué) lo que hace que el volumen de facturas a enviar sea mucho menor, también he podido constatar que muchos no entrarán en FACe y tendrán sus entradas propias (en muchos casos subcontratadas).
        Después de estudiar el WebService de FACe y lo complicado de su implementación, visto lo que habrá infinidad de puertas de entrada y que van a ser pocas las facturas de más de 5000 euros he decidido esperar acontecimientos, pues el esfuerzo de implementar infinidad de Webservice me parece poco rentable por el momento, de todas formas supongo que como todos los que estamos en esto agradecería toda la información y mejor código sobre como enviar directamente por el o los posible Webservice.

        Saludos Jaime

        ResponderEliminar
        Respuestas
        1. En mi opinión creo que es más cómodo seleccionarlo del almacén de certificados, así evitas tener más configuraciones extras en el software. A nivel de empresas, al menos con los clientes que trabajo, la mayoría lo tienen en el almacén, el fichero exportado no lo tienen el pc de trabajo.

          Eliminar
        2. Gracias por la información, Jaime Mombiela (y Sergio, por supuesto)
          Como ya has mandado alguna factura quisiera preguntarte acerca de los AdministrativeCentres. Estoy atascadísimo con esto.
          Se me ocurren al menos tres formas de manejarlo, a ver si puedes recomendarme:
          1.Crear un mantenimiento propio donde mi cliente cree los centros que necesite, con dirección, nombres, código, etc.
          2.Conectar con el servicio web para obtener la lista, pero entonces mi cliente deberá filtrar/buscar cada vez.
          3. Descargar la lista en csv (está super mal formateada) y manejarla en local. Aunque me faltarían las direcciones, etc.

          Al parecer no basta sólo con el código de centro sino que hay que indicar todos los campos para los tres centros (contable, gestor y tramit.): dirección, población, etc. ¿Sabes si esto es así?

          Y otra duda que tengo es acerca de los certificados digitales. Imagino que nuestros clientes, siendo empresas, necesitan certificados de persona jurídica. Un engorro para ellos, pues deben presentar varios documentos para obtenerlo.
          ¿Es así?, o puede usarse certificado de persona física para firmar y enviar facturas de la empresa.
          Veo que existe incluso un certificado específico para facturas electrónicas, pero tengo dudas de si permite firmar documentos, así como conectar al servicio web.

          Siento abusar así pero no acabo de aclarar esta información en los manuales (soy muy poco de preguntar en foros, pero esto me supera).
          Me da miedo pedirle al cliente que se saque un certificado y que luego se necesite otro.
          Por ahí listan los certificados válidos para FacE pero no mencionan en qué caso se necesita uno u otro (pers. física/jurídica) o para qué tarea (firmar/enviar/servicio web).

          Si no es molestia, ¿podrías contarme por encima cómo has gestionado tú todo esto?

          Muchas gracias de antemano.
          Saludos.

          Eliminar
        3. Te puedo confirmar que todos los datos relativos a los AdministrativeCentres son obligatórios, aunque puedas validar la factura, al intentar subirla a un punto de entrada de la administración, no te lo permite mostrando un mensaje de que la factura no es una factura electrónica.
          Gracias a todos por el trabajo, especialmente a Sergio.
          Saludos
          José M.

          Eliminar
        4. pues vaya. Parecía que no iba a ser necesario existiendo un código único para cada centro. Veo que no.
          Esto obliga a crear un mantenimiento extra.
          Muchas gracias Jose.

          Eliminar
        5. ¿de dónde se puede sacar la lista de AdministrativeCentres con sus direcciones, códigos, etc.?

          Eliminar
        6. https://face.gob.es/es/directorio

          Aquí se pueden encontrar los códigos requeridos para los tres campos.
          Saludos
          José M.

          Eliminar
        7. ups, he respondido con el mismo enlace. Disculpas.
          Jose, por cierto, ¿Sabes si hay que rellenar los TRES centros Contable, Gestor y Tramitador? Creo haber leído por ahí que con el primero es suficiente.
          Estoy con todo hecho pero dudando de si obligar al usuario a rellenar los tres. Encima con el engorro de que al parecer, el segundo y el tercero pueden ser el mismo que el primero.
          Saludos

          Eliminar
        8. buenooo. Ahora leo en un pdf de la Xunta de Galicia que los campos de dirección de los AdministrativeCentre hay que añadirlos obligatoriamente (como dice Jose) pero ¡pueden estar vacíos!
          Me cachis en la mar que yo me vuelvo loco con esto.
          Enlace al PDF: https://factura.conselleriadefacenda.es/eFactura_web/descargarManualB2B.do
          Perdonad si soy cansino con los mensajes, pero esto hay que acabarlo para ¡hace un mes!

          Eliminar
        9. Al usar el programa de FACe se pueden ver los campos necesarios, que no son más que el nombre del receptor, si no me equivoco corporatename, su dirección y los 3 Dir con su nombre. En mi caso he puesto nombres muchas veces inventados pues los centros oficiales son un desastre para suministrar información y a veces cuando los consultas son de más carácteres que los admitidos por el XML, pero al pasar la validación el se encarga de detectar perfectamente los datos. Para mi entender es más cómodo mantenerlos nosotros pues un mismo NIF puede tener diversos receptores con DIRs distintos y visto el desmadre que tiene face y la poca importancia de que el nombre del Dir no sea exacto opto por mantener los datos completos de mis receptores.
          En cuanto al certificado, me ha comentado el departamento de sistemas que deberíamos sacar un ceritificado de empresa específico pero por lo pronto dado el engorro, estamos usando un certificado de la empresa de un empleado, no será lo más correcto pero por ahora nuestras facturas se han tramitado sin problemas en FACe y PeFAC del gobierno de Canarias,

          Eliminar
        10. Muchas gracias Jaime.
          Al final he optado por lo mismo. Que el usuario pueda entrar los datos de los DIRs y se guarden en la bd en el proceso de firmar el xml. Así a la próxima podrán elegirlos en tres comboboxes.
          Como mi cliente factura poco a la administración, no relaciono los DIRs con clientes. Los muestro todos en los tres combos, filtrados por RoleTypeCode y que se apañen.
          Aún no lo tenemos en producción, pero siguiendo lo que leí en el pdf de la Xunta que menciono arriba, quiero intentar con los campos vacíos. No estilo   sino  , es decir, existe el campo pero es null.
          Ya contaré si se me queja el cliente!
          Por cierto, aparte de estos tres centros DIR, también mando la info de BuyerParty: TaxIdentification, CorporateName, etc. que son los datos que actualmente tengo en la bd por cada cliente para las facturas clásicas.
          Saludos.

          Eliminar
      29. Hola Jorge, según la documentación los servicios WEB han de ir firmados con oasis-wss-x509-token y no veo nada de eso en tu código, precisamente fue en ese punto en el que dejé de trabajar en el tema, pues incluso con una herramienta de prueba de WebServices SoapUI 5.0.0 me daba errores, soapui se supone que firma y me fallaba dando unos mensajes de error genéricos imposibles de interpretar por lo que decidí dedicarme a otra cosa. Ojalá lo consigas y nos ayudes a los demás.
        Saludos

        ResponderEliminar
      30. Buenos días,

        Ante todo, muchas gracias Sergio por compartir tu trabajo, funciona a la perfección.

        Estamos ahora en la fase de la integración con el Web Service y tenemos problemas, ante cualquier llamada que hagamos obtenemos la siguiente respuesta:

        "WSE3003: The certificate's trust chain could not be verified"

        Tenemos el certificado raíz de la FNMT instalado, por lo que no conseguimos averiguar que está pasando. ¿Alguien ha sufrido el mismo problema?

        Saludos.

        ResponderEliminar
      31. Hola,

        Tenemos varios clientes que quieren automatizar el envío de facturas por web service. Me encuentro con este problema al firmar la petición SOAP. El error es "No se entendió el encabezado SOAP security". Aquí ya no se por donde tirar... alguien se ha encontrado con esto?

        //Firma Petición Soap

        X509Certificate2 certificadoCliente = new X509Certificate2(@"C:\Temp\MiCertificado.pfx", "MiPassword", X509KeyStorageFlags.MachineKeySet);

        PoliticaCliente assert = new PoliticaCliente(certificadoCliente);
        Policy politica = new Policy();
        politica.Assertions.Add(assert);

        InstanciaFace.SetPolicy(politica);

        //Llamo al método del webService para enviar la factura
        ServiceFace.SSPPResultadoEnviarFactura resultadoEnvioFactura = InstanciaFace.enviarFactura(factura);

        ResponderEliminar
        Respuestas
        1. Yo las firmo así: Primero instala el paquete de Microsoft.Web.Services3.dll (vía nuget lo puedes hacer).
          Una vez echo, genera el .cs con la utilidad :
          wsdl.exe https://webservice.face.gob.es/sspp2?wsdl
          Una vez engas el CS cambia el inherits por:
          public partial class SSPPWebServiceProxyService : Microsoft.Web.Services3.WebServicesClientProtocol
          Para firmar uso este código (nota, yo uso un ASHX para hacer las peticiones):


          <%@ WebHandler Language="C#" Class="Handler" %>


          using System;
          using System.Web;
          using System.Web.Security;
          using System.Security.Cryptography.X509Certificates;
          using Microsoft.Web.Services3.Security;
          using Microsoft.Web.Services3.Security.Tokens;
          using Microsoft.Web.Services3.Security.X509;

          public class Handler : IHttpHandler {

          public void ProcessRequest (HttpContext context) {
          //.cs Generado
          SSPPWebServiceProxyService FacturaEServicio = new SSPPWebServiceProxyService();


          try
          {

          X509Certificate2Collection Certificado = X509Util.FindCertificateBySubjectName("CN=TUENTIDAD OU=FNMT Clase 2 CA, O=FNMT, C=ES", System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, "My");
          SecurityToken Token = GetSecurityToken(Certificado[0].SubjectName.Name);
          FacturaEServicio.RequestSoapContext.Security.Tokens.Add(Token);
          MessageSignature sig = new MessageSignature(Token);
          FacturaEServicio.RequestSoapContext.Security.Elements.Add(sig);



          //ArrayOfSSPPUnidadDir Unidades = o.consultarAdministraciones();//-->Funciona

          SSPPResultadoConsultarFactura EstadoFactura = FacturaEServicio.consultarFactura("XXXXXXX"); //--> error El sistema de Gestion de proveedor no puede consultar la factura

          context.Response.Write(EstadoFactura.tramitacion);
          }
          catch (Exception Ex)
          {


          context.Response.Write(Ex.Message +"
          " + Ex.InnerException);
          }

          }

          public X509SecurityToken GetSecurityToken(string subjectName)
          {
          X509SecurityToken securityToken = null;
          X509Store store = new X509Store(StoreName.TrustedPeople,
          StoreLocation.CurrentUser);
          store.Open(OpenFlags.ReadOnly);
          try
          {
          X509Certificate2Collection certs =
          store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName,
          subjectName, false);

          X509Certificate2 cert;
          if (certs.Count == 1)
          {
          cert = certs[0];
          securityToken = new X509SecurityToken(cert);
          }
          else
          securityToken = null;
          }
          catch (Exception ex)
          {
          Console.WriteLine(ex.ToString());
          }
          finally
          {
          if (store != null)
          store.Close();
          }


          return securityToken;
          }



          public bool IsReusable {
          get {
          return false;
          }
          }

          }




          Eliminar
      32. Hola, soy nuevo en este Blog y primero quiero agradecer de antemano por todos la buena info que he sacado de este artículo. Estoy intentando actualizar mi programa de facturación que hice ya hacer un par de años, para poder emitir facturas electrónicas, ya que le suministro producto al ayuntamiento de mi localidad. Llevo desde diciembre investigando y a la fecha sigo bloqueado y no avanzo, y como sabreis, tengo que presentar la factura de Enero y no me resigno a usar la web www.hazteunafacturae.com
        Soy programador de VB y no se nada de C#, pero he logrado ir pasando a VB. Y estoy parado en la generación de XML, ya que no puedo hacer lo de los decimales en las tipos double, en el archivo siempre sale
        .....TaxRate>21</TaxRate....

        Si alguien me puede ayudar..... ya que aún me falta el tema de firmarlo y ya no tengo mucho tiempo mas.

        Agradecería mucho si alguno suberia parte de fuente pero en VB.

        Muchas Gracias.

        ResponderEliminar
        Respuestas
        1. De los decimales no sé, pues genero el XML desde Cobol (sí, lo sé).
          Pero en cuanto a VB NET, busca
          Sergio eres brutal
          en esta misma página y verás la luz (como la vi yo, jeje).

          Eliminar
      33. alguien ha pasado por ikvm.net las nuevas librerías del ministerio? yo lo he intentado pero me lanza un montón de errores... me gustaría si alguien las tiene convertidas para probar el mismo proyecto que ya tengo funcionando con las nuevas librerías e intentar usar la política de firma 3.2

        ResponderEliminar
      34. Buenas, ¿nadie sabe si existe alguna dll para generar el XML?

        Veo que en Mexico el tema esta bastante avanzado, hay dos o tres empresas que venden una dll para generar la factura electronica.

        Aqui he visto una gratuita de Carlos Mendible: https://github.com/cmendible/nFacturae

        Pero no se usarla, me cuesta entender las expresiones lambda.

        ResponderEliminar
      35. Hola.
        Yo el xml lo hago a pelo. No uso libreria ni nada por el estilo. Genero el texto que necesito respetando el schema una vez tengo todo lo traspaso a fichero. Es una chapuza, pero es lo que mejor me funciona cuando he de hacer xml, y me va perfecto.

        Luego par hacer la firma, hice un programa en .net que me costo la hostia, sudé tinta. pero bueno ahi lo tengo y a mis clientes les va de coña.

        ResponderEliminar
      36. Ok, gracias.

        Ya le desarrolle. Ahora empiezo con la firma.

        Un saludo.

        ResponderEliminar
        Respuestas
        1. puede pasarme como generas el XML la verdad que estoy verde
          garcias

          Eliminar
        2. por favor, puedes decirme como has generado el XML. te lo agradecería
          saludos

          Eliminar
        3. despues de mucho trabajo estoy empezando a crear la factura. pero tengo un problema con el formateo de los decimales de los campos double. he intentado aplicar las clases de sergio pero me dan error, podrias indicar como lo puedo hacer
          gracias
          saludos

          Eliminar
      37. Hola amigos de la factura-e :)
        Yo en mi caso soy receptor de facturas-e. El problema, es que debo validarlas, y validaciones OCSP aparte, que lo tengo controlado... con esta librería, y en general con ninguna salvo algunas de pago que no he probado .... todos los Xsig que he probado no pasan la validación de la firma XADES-EPES.
        ¿Esta librería tal y como está ahora debería funcionar con las factura-e actuales?
        Gracias!

        ResponderEliminar
      38. Respuestas
        1. si puedieras me prodrias indicar como cargar los datos de la clave fecturae
          estoy empezando y la verdad estoy verde en el tema xml

          gracias

          Eliminar
        2. Perdona pero hacía dias que no entraba, en mi caso uso un archivo de texto, en un post anterior publiqué un ejemplo de estructura, donde basta cambiar los contenidos. La he usado en muchos tipos de factura. Saludos.

          Eliminar
      39. Este comentario ha sido eliminado por el autor.

        ResponderEliminar
      40. Hola amigos,

        Yo tengo el .xsig fenomenal, y ahora estoy intentando integrar la subida por los WebServices (VB .net). Me estoy dando de cabezazos con los X.509, que de nuevo hay que usarlos para firmar la petición SOAP.

        Para ello he tenido que usar los WSE 3.0 y usar la información de este post)
        https://msdn.microsoft.com/en-us/library/aa529277.aspx (ojo que lleva a otro en el paso 2 donde tienes que crear un Policy Assertion personalizado), además he tenido que hacer el servicio web (da igual preproducción que producción de la AEAT) heredada de (ver https://msdn.microsoft.com/en-us/library/ms824684.aspx) Microsoft.Web.Services3.WebServicesClientProtocol.

        Bien, en este punto y con la información de esos enlaces a la MSDN ya tenemos una buena base de partida, tenemos un método fenomenal para asegurar el mensaje de la petición (CustomSecurityClientOutputFilter) y tenemos acceso a la colección security del WebService... así que le enchufamos (tal y como indican los ejemplos de la MSDN) el securitytoken del certificado con clave y la firma del mismo (según la apestosa documentación de la AEAT no hay que encriptarlo, así que no os agobiéis con los servertokens)... y a llamar al método para enviar la factura.

        Pero desgraciadamente da el error "the security token could not be authenticated or authorized". Sin embargo, usando Fiddle que viene fenomenal para auditar tu tráfico de red hasta el último nivel, veo que el xm generado tiene muy buena pinta (la clave del PEM y la firma referenciada para desencriptar junto a su digestvalue referenciado en el body)... obviamente el certificado es perfecto y está dado de alta en el sistema... si alguien arroja luz sería de agradecer.... gracias...

        ResponderEliminar
      41. Jaime, podrías enviarme marzo.1111@gmail.com como rellenar la clase facturae con los datos y así generar el xml
        la verdad es que estoy empezando y estoy verde con el tema xml
        gracias

        ResponderEliminar
      42. Aquí os pongo la incidencia que estoy actualmente tratando por el tema de los web services, por si a alguien le sirve... además, si alguien se encuentra en este punto y hallado la solución a la firma del mensaje SOAP le estaría muy agradecido si la diese a conocer.

        Hola,

        A la att de su departamento de informática.

        Estamos integrando con nuestro sistema de gestión las peticiones a sus servicios web para la entrega de facturas electrónicas firmadas correctamente (.xsig).

        Esta integración se ha realizado en base su documento .pdf "Servicios para sistema automatizados de proveedores".

        Primeramente hemos dado de alta la clave pública de nuestro certificado en su su plataforma según página 7 del documento.

        Mediante vb .net (se han probado diferentes frameworks) se realiza una llamada a su servicio web (tanto "staging" como "prod"), en concreto al método "Enviarfactura". El xmp generado para la petición SOAP está firmado según su ejemplo válido (pag. 33 del documento .pdf), conteniendo la información de la firma y la clave pública para su correcta validación. Sin embargo, tanto en "staging" como en "prod" la llamada al servicio me devuelve siempre el mismo error: "WSE910: An error happened during the processing of a response message. The security token could not be authenticated or authorized".

        No entendemos la causa de este error porque la firma del mensaje SOAP se acoge tanto a los estándares "OASIS WS-Security 1.0 X509 Token Profile" como al ejemplo suministrado de petición firmada.

        Adjunto .xml capturado de la petición SOAP para que comprueben la correcta petición al servicio. Entonces, ¿existe algún problema de construcción o está fallando su validación? Porque la firma es correctamente validada mediante el algoritmo rsa-sha1.

        ResponderEliminar
      43. Hola Bob Rock,

        Aquí seguimos con el mismo error que tu. Estamos esperando respuestas a algunas consultas (llevamos esperando más de dos semanas). Suerte!

        ResponderEliminar
        Respuestas
        1. Tengo poca fe de que me respondan, pero lo que no entiendo es que mi petición SOAP (capturada mediante fiddler - gran soft -) está clavada estructuralmente a la suya, el certificado y sus formas validados, etc... no sé, he usado WSE3 porque no he encontrado otra forma añadir políticas de seguridad personalizadas.... si veo la luz os aviso

          Eliminar
        2. Bob Rock, a mi no me ha funcionado el entorno de TEST de red.sara en condiciones. Haciendo peticiones al entorno de producción al menos me han servidor las unidades DIR3. Lo que no consigo es ver el estado de las facturas. Me da el mensaje " El sistema de Gestion de proveedor no puede consultar la factura". Haz pruebas directamente en el entorno de producción y me dices.

          Eliminar
        3. Gracias Jaime, pero en real me sigue dando el error "WSE910: An error happened during the processing of a response message. The security token could not be authenticated or authorized" y la cuestión es que mi petición soap tiene el encabezado con los elementos de seguridad tal y como se indica en docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0.pdf Además estamos dados de alta como proveedores con la clave pública. Una preguntilla: como BinarySecurityToken, ¿sólo hay que pasar la clave pública? No es necesario pasar en el keyinfo de la firma el modulus ni el exponent, ¿verdad? Porque se supone que se valida la firma con el BinarySecurityToken referenciado (y el certificado asociado en el sistema del ministerio). El error me lo devuelve consulte administraciones, suba una factura, haga lo que haga (en real o test)... estoy desarrollando en VS2005 Visual Basic y los runtimes WCE3 (he usado el framework 2.0 porque es el que mejor compatibilidad ofrece para los WCE3). ¿Tu has subido facturas? ¿Te devuelve las unidades del directorio siquiera? Lo único raro que veo raro en mi petición SOAP generada es que tiene varios digestvalues dentro de references en lugar de solo uno como el ejemplo que presenta e ministerio. Pero la verdad que no puedo manipular mucho la petición SOAP, la genero de forma seudo automática con los WCE3... Muchísimas gracias, a ver si conseguimos hacer un hilo donde aportemos las guías para sincronizar con los web services (porque los de la administración ni me han contestado ni creo que lo hagan - por teléfono han sido bastante lamentables las contestaciones -).

          Un saludo

          Eliminar
        4. Sí me devuelve las unidades y los estados. En mi caso por ahora no necesito subir facturas (las van a subir manualmente por ahora) pero sí necesito saber los estados de las facturas subidas: por ahora no he conseguido que me devuelva ningún estado.
          Voy a cambiar, tal y como dice Capitán Cavernicula, el proxy. No voy a usar WCE3 para firmar, voy a usar otras librerías y te digo como me va.
          Nota: he puesto también el custom binding que indicó capitan cavernicola. Me sigue dando el error en la respuesta que me mandan.

          WSE910: An error happened during the processing of a response message, and you can find the error in the inner exception. You can also find the response message in the Response property.
          Microsoft.Web.Services3.Security.SecurityFault: The security token could not be authenticated or authorized ---> System.Security.SecurityException: WSE3003: The certificate's trust chain could not be verified. Please check if the certificate has been properly installed in the Trusted People Certificate store. Or you might want to set allowTestRoot configuration section to true if this is a test certificate. en Microsoft.Web.Services3.Security.

          Haber si logro conseguirlo de otra manera.
          Un saludo.

          Eliminar
        5. "The certificate's trust chain could not be verified"
          ¿Has metido el sumidero de certificados?
          Por otro lado, la credenciales del proxy.
          oCredProxy.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None
          oCredProxy.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck

          Si creas un proxy dinámicamente, con ese binding, y esas opciones, deberías poder conectarte.

          Eliminar
        6. Justo lo acabo de poner y va todo correctamente. Eso sí, siguen sin dejarme ver el estado de las facturas:
          301 - El sistema de Gestion de proveedor no puede consultar la factura
          Puedo consultar unidades, administraciones, estados, etc pero de consultar la factura nada de nada.
          El problema que tenemos bob y yo es que seguimos con Microsoft.Web.Services3.dll donde no hay custom bindings. Para poder aplicar lo que nos ponías hay que hacerlo vía web.config.
          Tambíen se puede hacer vía codigo (no he investigado como).
          Un saludo y gracias Capitán!

          Eliminar
        7. MM el sumidero de certificados tengo que ver como hacerlo. Microsoft.Web.Services3 no he encontrado la manera.

          Eliminar
        8. A ver. Yo tengo varios proyectos y en algunos hago el proxy con wsdl.exe, otros con el visual studio, etc. Y trabajo con F4. En realidad todo lo que puedes hacer via .Config lo puedes hacer vía código, con un mayor control, además.
          Dicho esto, si metes esto digamos "en el arranque",
          ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf AcceptAllCertifications)

          Donde AcceptAllCertifications es un método de esta pinta:
          public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
          {
          return true;
          }

          pues podrás aceptar el ceritficado aunque sea sin validación. Esto debe hacerse con cautela o entornos controlados.

          Eliminar
        9. Parece que con oCredProxy.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None
          oCredProxy.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck

          ha sido suficiente. No me da ningún error procesar la respuesta!!

          No veía la manera de poner ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf AcceptAllCertifications)
          en el proxy que tengo generado.

          Ahora el problema es el de antes: no me dejan consultar facturas

          (SOAP-ENV:Fault)
          (faultcode>500(/faultcode)
          (faultstring>14934XXXXXXXX - 301 - El sistema de Gestion de proveedor no puede consultar la factura
          (/faultstring)
          (/SOAP-ENV:Fault)

          (y creo que es porque sólo dejan consultar aquellas que se han presentado vía webservice y no manualmente). He enviado un mail haber si me dan alguna respuesta. Gracias capitán.

          Eliminar
      44. Pues a mi esta librería no me valida bien las Factura-e que recibo, así que por ahora valido el XMLDSIG por una lado y el estado OCSP por otro.
        Sobre Face: hoy por ejemplo los servicios de FACe devuelven Ok para varios métodos, pero para la descarga en sí de facturas devuelven SOAP-ENV:Server ... devolviendo lo que parece ser un error interno, tal vez de Oracle.
        He dejado una incidencia ... y "ya me llamarán". Más: las anulaciones las devuelven con saltos de línea distintos a los de las facturas, lo que sumado a la Canonización C14N distinta entre Java-.Net, imposibilita la validación automática de mensajes, y he tenido que meter unos "interceptores" en mi proxy para procesar los SOAP-Message a mano .... Tampoco se pueden subir facturas al entorno de preproducción al que tenemos acceso....
        Es decir, ojito que FACe falla más que una escopeta de feria.
        Dicho esto, os diré que aunque vuestros mensajes esté correctamente firmados, podeis seguir obteniendo esos mensajes de error, porque una cosa es el mensaje y otra la seguridad del canal. al igual que una cosa es preproduccion y otra producción. Yo no grabo facturas pero entiendo que será similar.... Cuando creeis el proxy, debeis aplicar los parámetros adecuados. messageVersion="Soap11", habilitar canal inseguro de vuelta, messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10", etc etc.
        Luego le poneis una vela a la virgen de Valvanera o a Krom o a lo que profeseis fe y esperais a ver si FAce está operativo.

        ResponderEliminar
        Respuestas
        1. Pues mira, soy muy de Crom, pero el dios cimmerio subiría las facturas a espadazos y se dejaría de pamplinas... no hay manera. No soy un experto en seguridad SOAP ni encriptación (ojo que no mando las peticiones encriptadas), pero en todas las referencias consultadas no dicen que conceptualmente sea tan bizarro siempre que el webservice esté bien preparado y publicado... voy a seguir probando y rezando... cualquier avance os comento...

          Eliminar

        2. A ver, con la referencia web automática de visual Studio lo veo complicado, porque así no lo he hecho yo. Yo me he creado la clase proxy, pero siempre puedes intentar cambiar cosas en el binding a través del app.Config
          Prueba esto en el Binding de tu proxy:





          Y luego mete un "sumidero" de Certificados al crear el proxy, como esto: http://stackoverflow.com/questions/5998004/vb-net-accept-self-signed-ssl-certificate"
          A ver si te sirve de algo.

          Eliminar
        3. Espera, que me ha cepillado el XML.. (cambia los paréntesis por símbolo menor-mayor.)
          (customBinding)
          (binding name="myCustomBinding")
          (security allowSerializedSigningTokenOnReply="true"
          includeTimestamp="false"
          enableUnsecuredResponse="true"
          securityHeaderLayout="Lax"
          authenticationMode="MutualCertificate"
          messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" /)
          (textMessageEncoding messageVersion="Soap11" maxReadPoolSize="2147483647" )
          (readerQuotas maxArrayLength ="2147483647" maxBytesPerRead ="2147483647" maxNameTableCharCount ="2147483647" maxStringContentLength ="2147483647" maxDepth ="32"/)
          (/textMessageEncoding)
          (httpsTransport maxBufferPoolSize="2097152" maxReceivedMessageSize="524288" maxBufferSize="524288" requireClientCertificate="true" /)

          (/binding)
          (/customBinding)

          Eliminar
        4. Gracias Capitán, me meto al lío y os digo. A ver cuando puedo sacar tiempo (trabajo en consultora y llevo un retraso atroz en otros proyectos... ya tu sabes...)

          Eliminar
        5. Este comentario ha sido eliminado por el autor.

          Eliminar
      45. Bob, prueba esto en el webconfig:
        (microsoft.web.services3)
        (security)
        (x509 allowTestRoot="true" storeLocation="CurrentUser" revocationMode="NoCheck" /)
        (securityTokenManager)
        (add type="Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken" /)
        (/securityTokenManager)
        (/security)
        (diagnostics)
        (trace enabled="true" input="InputTrace.webinfo" output="OutputTrace.webinfo" /)
        (detailedErrors enabled="true" /)
        (/diagnostics)
        (messaging)
        (mtom clientMode="Off" /)
        (/messaging)
        (/microsoft.web.services3)

        ResponderEliminar
      46. Alguien sabe si hay "alguien" detrás de soporteface@red.es?

        ResponderEliminar
      47. Si alguien se ha dado de bruces con este problema "301 - El sistema de Gestion de proveedor no puede consultar la factura " y lo ha solucionado por favor que ponga por aquí como lo ha echo.. Esto pasa al consultar el estado de una Factura en el FACE (producción). EN el de pruebas no he logrado que me den de alta.
        Un saludo

        ResponderEliminar
      48. Hola Amigos!

        Por Crom!! Ya he podido acceder a los servicios... VS 2005, VB y WCE3 -> Aplicación de escritorio: La solución está (además de la custompolicy para firmar el mensaje) en configurar por app.config lo que ha indicado Jaime García Pérez (PHX). Por supuesto el Capitán Cavernícola también ha dado bien con la tecla, solo que el WC3 tiene sus limitaciones... muchísimas gracias. Ya puedo consultar las oficinas contables y demás...

        Eso sí: en el stagin parece que no dan de alta el certificado... muy bien, cojonudo para hacer pruebas!!

        Ahora viene lo malo: yo estoy con el método de enviar factura; estoy intentando mandar una factura como piden (base64 del xsig) y el error es "Formato de la factura incorrecto, no se puede determinar la versión de la factura"

        Eso sí, de momento estoy mandando la de prueba que ellos ofrecen (tiene datos de chichinabo)... claro, mando esa porque los webservices son de producción... vamos a ver que posibilidad hay de subir algo real y os comento, en ese caso intentaría hacer la consulta que indica Jaime (pq de momento no tenemos ninguna subida por formulario web)

        Gracias de nuevo, este hilo es el verdadero soporteface@red.es

        ResponderEliminar
        Respuestas
        1. Acabo de hablar por teléfono con el 900 555 555. No os lo vais a creer.
          No se pueden Presentar/Consultar facturas vía web service, el servicio no está activo.
          Tienen una incidencia GENERALIZADA.
          Sólo queda el canal WEB.
          Lo increíble es que con la persona que he hablado 30 minutos no tenía ni idea de la existencia de los servicios web. Solo dan soporte para el programa que genera facturas y a la web del FACE. Insistiendo.. al final si os pasan con algún técnico (pero cuesta).
          Molesta bastante que no informen en la página que el servicio no funciona, o que funciona. Otro caso más de desastre tecnológico que pagamos todos de nuestros bolsillos.
          A esperar toca.


          Eliminar
        2. Podemos afirmar que el Martes 17 FACe tomo conciencia de sí mismo y los funcionarios aterrados trataron de apagarlo, y etc etc, Yo tengo varias incidencias abiertas, porque como os decía, llevan unos días devolviendo el error "SOAP-ENV:Server ...class DTIException not found". Además de otros temas que os comentaba.
          El entorno de preproduccion tampoco admite el envio de facturas, así que veremos a ver si no están haciendo cambios de cierta envergadura ... que puedan afectar a lo que ya tenemos hecho / instalado.
          Lo mejor es esperar.

          Eliminar
        3. La verdad es que esto del FACe parece perpetrado por los hermanos Marx puestos de algo. Yo he llegado al punto muerto de recibir en mi envío de factura el mensaje: "Se ha producido un error, consulte con el administrador"... claro, llamas y te encuentras con una respuesta inservible y ni contestan al formulario de incidencias... en fin, llorar no sirve de nada, seguiremos bregando...

          Eliminar
        4. Ahora sí que sí, a poner velas para que no hagan cambios demasiado... "grandes".
          Un saludo y ánimo!

          Eliminar
        5. Confirmado: no funciona "enviarfactura", aunque la forma de decírmelo ha sido bastante triste y no he conseguido que me lo pasasen por escrito... eso sí, me confirman que están teniendo infinidad de problemas (en general) y están totalmente desbordados...

          En fin, a ver si tenemos noticias. Una vergüenza tecnológica...

          Eliminar
      49. Han parado los servicios, directamente devuelven un error 500.
        HTTP/1.1 500 Internal Server Error

        ResponderEliminar
        Respuestas
        1. Jaime, yo accedo vía navegador (y por programación accediendo al directorio): https://webservice.face.gob.es/sspp?wsdl

          Eliminar
        2. El https://webservice.face.gob.es/sspp?wsdl si devuelve la definición, ¿pero cuando haces una petición no te devuelve el error 500?

          Eliminar
        3. SSPPResultadoConsultarUnidades me devuelve resultados. Eso sí, no he actualizado los servicios desde las 9 aprox... El resto sigue fallando, yo voy a dejar esto en barbecho a ver si se ponen las pilas y apañan los servicios. Porque realmente lo útil es automatizar la subida, consulta, anulación, etc...

          Un abrazo!!!

          Eliminar
        4. Efectivamente actualizaron el webService.... ya lo he solucionado...

          Eliminar
      50. Si entras directamente en https://webservice.face.gob.es/sspp2 (donde se hace la comunicacion) a mí me devuelve error 500.
        Quizás te lo esté devolviendo algo cacheado... voy a revisar el código. Estoy probando en Producción lógicamente... no puedo hacerlo en el de preproducción.

        ResponderEliminar
        Respuestas
        1. Ummm, por lo que veo en el fiddler yo no tengo problemas... he actualizado los WS y sigue devolviendo estados/unidades... pre-producción???? tiene narices que no se pueda usar!!!

          Eliminar
      51. Buenos dias a todos,

        En nuestro departamento estamos realizando el desarrollo para el envio de las facturas mediante el WEBServices "https://se-face-webservice.redsara.es/sspp?wsdl" que como indican en su documentación sirve para realizar las pruebas de envio.
        El problema que tenemos es el siguiente:
        El XML esta correctamente firmado y comprobado en la web de validaciones de envio.
        En el proyecto .NET, realizamos toda la configuración del WEBServices y lo enviamos, pero siempre nos devuelve el mismo mensaje.

        "No se entendió el encabezado SOAP Security."

        Es un poco desesperante, hemos realizado una lectura total de este hilo en el foro, pero allí donde se hace referencia a este error, indican que es debido a la firma del archivo, cosa que no es nuestro caso, ya que como hemos comentado con anterioridad, este mismo archivo esta firmado y validado correctamente por la WEB de hacienda.

        A alguien le ha ocurrido esta incidencia?,
        De ser así, lo han solucionado, y como?.

        Muchas gracias de antemano a todos los que estais colaborando a llegar donde la falta de documentación y comunicación de hacienda no llegan

        ResponderEliminar
        Respuestas
        1. Revisa bien el webconfig. Te aconsejo no usar ese webservice, usa mejor el de producción.

          http://sourcedevnet.blogspot.com.es/2015/02/usar-servicios-web-de-facturae-con-c-y.html

          Eliminar
        2. Hola,
          Estás haciendo la petición SOAP sin indicar un encabezado, y sin añadir la seguridad en el mismo. Es necesario que firmes con el certificado que has dado de alta en proveedores de FACe (sí, necesitas la clave privada en el equipo que emita la factura) y que además configures correctamente el canal de comunicación.
          Te lo esquematizo porque tiene miga (y muchas formas de abordarlo). He usado WSE3

          1.- Instalar Runtimes WSE3: https://www.google.es/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCMQFjAA&url=http%3A%2F%2Fwww.microsoft.com%2Fen-us%2Fdownload%2Fdetails.aspx%3Fid%3D14089&ei=-83lVMvFNca1Ufy4hJAM&usg=AFQjCNE52fHOKKVeEFQBsyJJGTode8oobQ&sig2=e2HZxgoouvQslaHMQCn28w

          2.- Seguir los pasos de este enlace (https://msdn.microsoft.com/en-us/library/aa529277.aspx): ojo al paso 2.

          3.- Cambiar la herencia del servicio en reference.vb (si no lo ves es por configuración de VS): Public Class SERVICIOMINISTERIO
          Inherits Microsoft.Web.Services2.WebServicesClientProtocol
          (más info en: https://msdn.microsoft.com/en-us/library/ms819963.aspx 5.b.)

          NOTA: En este punto ya tienes las herramientas para firmar la petición: debes usar el método SecureMessage que has creado en el paso 2 (con respecto a los certificados que añadir al token, más o menos es fácil: busca en el almacén que necesites por los valores que necesites, tienes un montón de información en www)

          4.- Añadir el genial código de Jaime Garcia al appconfig...

          (microsoft.web.services3)
          (security)
          (x509 allowTestRoot="true" storeLocation="CurrentUser" revocationMode="NoCheck" /)
          (securityTokenManager)
          (add type="Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken" /)
          (/securityTokenManager)
          (/security)
          (diagnostics)
          (trace enabled="true" input="InputTrace.webinfo" output="OutputTrace.webinfo" /)
          (detailedErrors enabled="true" /)
          (/diagnostics)
          (messaging)
          (mtom clientMode="Off" /)
          (/messaging)
          (/microsoft.web.services3)

          5.- Observar como no funciona el servicio :(

          PD: No usar el stagin, tampoco funciona...

          Eliminar
        3. Hola Jaime,

          He seguido tus consejos y he cargado la referencia al web service de producción (en mi caso es un proyecto .net con una clase para intergarla con interop en Microsoft Dynamic NAV 2015). Entiendo que en mi caso se debería revisar el app.config, pero no sé exactamente a que te refieres.

          Tengo esto actualmente:











          https://webservice.face.gob.es/sspp?wsdl


















          Gracias y Saludos

          Eliminar
        4. Se me olvidaba: VS2005 y VB, aplicación de escritorio....

          Eliminar
        5. Sergio Carbajo / David Navais, no se puede pegar el XML aquí, si queréis enviarme un email phx255#gmail
          Un saludo.

          Eliminar
      52. Hola Alex,

        Creo que somos varios que estamos en tu misma situación. Yo estoy probando de hacer un custom binding según han comentado por aquí (en el app.config).

        Ahora lo desconcertante hoy es leer que por mucho que solucionemos esto, los web service tampoco funcionan...

        Ánimos a todos!

        ResponderEliminar
      53. Alex voy a poner una entrada en mi blog porque este comienza a ser demasiado grande. Ahí te explico paso por paso lo que me funciona a mi. UN saludo.

        ResponderEliminar
      54. Os dejo un resumen para atacar los servicios Web. Críticas serán bienvenidas.
        Ánimo a todos!
        http://sourcedevnet.blogspot.com.es/2015/02/usar-servicios-web-de-facturae-con-c-y.html

        ResponderEliminar
        Respuestas
        1. Brutal, gracias!! Un buen resumen que sacará a muchos de apuros! Pero recordad que a día de hoy han confirmado que no se pueden subir facturas vía WS... paciencia!

          Eliminar
      55. gracias por las entradas Sergio y Jaime, mi granito de arena https://github.com/miamon/Face-Web-Service, he subido una aplicación VB.NET Vs2013 que conecta con Servicio Web de Face de producción y podemos enviar facturas firmadas

        ResponderEliminar
        Respuestas
        1. Josep, ¿os funciona el envío de facturas? no lo he probado, pero el método de ConsultarFactura si te que no funciona,
          Un saludo.

          Eliminar
        2. Vale, una vez pasado en base64 me vuelve a decir lo mismo: "Se ha producido un error, consulte con el administrador"... ojo, estoy pasando la factura de prueba que proporciona el ministerio en formato 3.2...
          Josep: ¿tú has subido alguna válida/real? ¿has probado la de prueba? (que por cierto se valida sin problemas....)

          Jaime: en cuanto a consultar me lanza el mismo error que a tí. Yo creo que si a ambos nos han dicho que no funciona por algo será...

          No sé, seguimos....

          Eliminar
        3. Buenas

          No he subido ninguna factura real, ya que al ser en entorno de producción no la he enviado. Pero he probado con una factura con un error para ver si respondía correctamente y me saltaba el error "algún parámetro obligatorio se pasó vacio". Era por que no he puesto el código postal en los dir3. Por lo tanto conectaba con el servicio web validaba el formato de factura y devolvía el error.

          Si que que probado recuperando las Unidades y respondía correctamente.

          Mañana intentaré subir una factura correcta y os cuento.

          Eliminar
        4. Ah, vale, Pues tamos en el mismo punto Josep... cuando ya lo tienes todo preparado te devuelve error :( Seguimos ahí, ya nos cuentas!!

          Eliminar
        5. Buenos días, he probado con la factura de ejemplo y me salta el error 310 - Algún parametro obligatorio aparece vacío

          Eliminar
        6. ¿Podrías probar a consultar el estado de una factura? Lógicamente para esto tienes que tener subida alguna. Yo he subido algunas manualmente (facturas Reales) pero me da el error:
          301 - El sistema de Gestion de proveedor no puede consultar la factura
          Un saludo

          Eliminar
        7. No tengo ninguna subida de factura con el certificao que estoy trabajando, pero he probado un número de registro cualquiera y devuelve el mismo error: 301 - El sistema de Gestion de proveedor no puede consultar la factura

          Eliminar
        8. Ok, estamos en el mismo sitio entonces. Gracias Josep.

          Eliminar
        9. Josep.- Yo creo que eso es porque no estás pasando los datos del xsig en base64... yo he usado la factura de prueba (en base64) y no me da ese error, llego al error "Consulte con el Administrador".

          No puedes pasar tal cual el contenido del xsig.

          Un saludo.

          Eliminar
        10. Bob Rock, te diría que no, ya que si las paso en Base64 no ve ni la firma, salta un error de: 100 - La firma no es válida

          Eliminar
        11. Josep.- Si usas un xsig que esté validado por la web del ministerio verás que sólo pasándolo en base64 llegas al punto final donde ya no sube. Vamos, en la documentación del ministerio es de lo poco que explica claramente. Además, es algo normal, piensa que en tu petición estas componiendo un xml, pues si compones dentro de ese xml de petición otro xml descojonas todas el esquema. Puede que la firma no sea correcta, yo he intento hacer pruebas y cuando manipulas el xsig a mano no valida la firma.
          Url para validaar xsig: http://sedeaplicaciones2.minetur.gob.es/FacturaE/

          Un saludo, a ver si conseguimos a avanzar, hoy salía Rajoy por la tele diciendo el éxito que iba a suponer esto del FACe XD XD XD XD XD

          Eliminar
        12. Si la factura la tengo validada, y como bien dices tu en base64. Pensaba que te refererias a convertirto con System.Convert.ToBase64String.

          El link al validador solo soporta hasta 3.2 y estoy generando 3.2.1, otro desastre más de FacturaE por mucho que salga Rajoy a decir de las bondades.

          Eliminar
      56. Gracias por las entradas Sergio y Jaime, mi granito de arena al tema. He subido una aplicación VB.NET Vs2013 que conecta con Servicio Web de Face de producción y podemos enviar facturas firmadas. https://github.com/miamon/Face-Web-Service

        ResponderEliminar
      57. Sin querer he borrado un comentario de Bob Rock (se me ha ido el dedo al link incorrecto...). Este era su comentario:

        1o:la solución me da el siguiente error: Error 1 'RequestSoapContext' no es un miembro de 'waServicioWebFace.facewebservice.SSPPWebServiceProxyService'.
        Necesario: Partial Public Class SSPPWebServiceProxyService
        Inherits Microsoft.Web.Services3.WebServicesClientProtocol
        2o: el WS devuelve el error "algún parámetro obligatorio se pasó vacio"
        3o: El contenido del xsig ha de pasarse en base64 (eso seguro, pero vamos, que no llegamos a este punto)

        voy a echarle un vistazo más en profundidad... Josep, ¿has podido enviar facturas con el proyecto tal cual?

        Gracias a todos

        ResponderEliminar
        Respuestas
        1. Hola Sergio, bajé el proyecto de Josep y te agradecería me indicarás donde pongo el Partial Public Class SSPPWebServiceProxyService y Inherits Microsoft.Web.Services3.WebServicesClientProtocol. Se lo he visto también a Jaime García en su solución y estoy perdido, al menos para seguir avanzando aunque no funcione. Muchas Gracias.

          Eliminar
        2. Hola, ponlo en el reference.vb que te genera cuando agregas la referencia web. Con la referencia en el proyecto a los WSE3 cambia del reference.vb "Inherits Microsoft.Web.Services.Protocols.SoapHttpClientProtocol" por "Inherits Microsoft.Web.Services3.WebServicesClientProtocol"

          Eliminar
        3. Se lo tienes que poner a la clase que has generado vía WSDL
          Mira este post, te indica como hacerlo:
          http://sourcedevnet.blogspot.com.es/2015/02/usar-servicios-web-de-facturae-con-c-y.html

          Eliminar
        4. Muchas gracias por vuestra ayuda. Solucionado.

          Eliminar
      58. Seguimos sin noticias! esta vez no he visto cambios en el webService. Supongo que muchas empresas y clientes tienen que estar muy nerviosos. Haber si lo solucionan pronto.
        Un saludo.

        ResponderEliminar
      59. Perdonadme el atrevimiento pero me gustaría resumir nuestra situación actual y que alguien me corrija si me equivoco.
        1º Tenemos solucionado la generación del .xsig tanto con el certificado en un archivo como desde el almacén de certificados.
        2º El envío de facturas a FACe con el webservice no lo hemos conseguido pues da errores y no sabemos si somos nosotros o el propio Webservice de FACe.
        3º El portal de remisión de facturas de FACe no funciona desde el día 17, por tanto todas la empresas Españolas llevamos varios días sin poder tramitar nuestras facturas. Por ende dentro de este despropósito tampoco funciona el webservice.
        4º Dentro de este guirigay hay que hacer notar que no sólo existe FACe, si no que cada cual se ha montado su propia entrada para locura de los que nos dedicamos a esto.

        ResponderEliminar
        Respuestas
        1. Alguien podría echarme una mano.
          El xml que genero al validarlo me dice que no la factura no tiene formato correcto

          empieza por:


          -
          -

          cuando el que por ejemplo pone Jaime Mombiela empieza por:


          -
          -

          me podríais decir donde reside el problema. por favor
          Gracias

          Eliminar
        2. Este comentario ha sido eliminado por el autor.

          Eliminar
        3. Vuelvo a poner el encabezamiento:

          ()
          (-)
          (-)

          el de Jaime empieza por:

          ()
          (-)
          (-)

          El xml lo genero a partir de la clase creado por Sergio al comienzo.
          Gracias

          Eliminar
        4. Cuando hice el segundo caso de facturas me resultó de entrada complicado hacer las validaciones, pues fallaba más que una escopeta de feria, pero al final cuando lo pillé fue una chorrada pues cualquier signito idiota estropeaba el formato.
          Para validar hice algo tan simple como coger uno que funcionaba, por ejemplo el que te pasé e ir cambiando trozos de código por el nuevo. Primero cabeceras, buyer, Seller y factura y pasarlos por el validador de FACe http://sedeaplicaciones2.minetur.gob.es/FacturaE/.
          Parece una chorrada pero en un rato ya tenía todos los fallos localizados. Los fallos pueden ser tan tontos como no usar los decimales adecuados, campos demasiado grandes cierres duplicados.

          Suerte

          Eliminar
        5. Creo que el problema está en el comienzo del xml, pero que como es automático
          el que genero tiene esto ( que no soy capaz de visualizarlo en el post ) ( voy a quitar <> a ver )

          *?xml version="1.0" encoding="UTF-8"?
          *-Facturae xmlns="http://www.facturae.es/Facturae/2009/v3.2/Facturae" *xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
          *instance"
          *FileHeader xmlns=""
          *Parties xmlns=""
          *Invoices xmlns=""
          */Facturae

          No entiendo porqué sale xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          y despues de cada etiqueta xmlns=""
          y el que tu envias empieza por fe:factura, igual que al terminar

          Eliminar
      60. Jaime M.- Yo te confirmo hasta el punto 2 y diría, porque fue el servicio de soporte de FACe quien me lo afirmó, que los problemas en los webservices de enviarfactura y consultarfactura son de la propia plataforma.

        Un saludo y paciencia.

        ResponderEliminar
      61. Las descargas de facturas funcionan desde el jueves aproximadamente. Aunque a veces las facturas que nos llegan llegan con formatos algo extraños, y con personalizaciones increíbles del factura-e. Si nos llegan es que se están registrando. Eso si, es penoso porque si me llegan 350 facturas, me las tengo que descargar una a una (llegan en base64, si), y se supone que tengo que validar de nuevo su firma, formato y certificado.... Si está firmada con un certificado clase 2 FNMT, y la entidad no tiene convenio FNMT no puede validarlo. Es un fraude que en si mismo da para otro hilo,
        No es que exista sólo FACe, es que la legislación actual permite que cada entidad cree su propio punto de entrada de registro de facturas electrónicas, es decir, que puedes estar adherido a FACe o no. Es decir, si la Sede Electrónica de la entidad admite Facturas-e por registro telemático, la validez es la misma. Al igual que la entidad puede determinar la obligatoriedad en función del importe.

        ResponderEliminar
        Respuestas
        1. Capitán , sí se registran facturas pero manualmente desde la web. Presentarlas vía webservice a mí al menos aún no me funciona.
          Un saludo.

          Eliminar
        2. Eso debe ser. Poner incidencias ya veis que no tiene mucho futuro, porque para mi que tienen tantas que ya ni las leen. Han sacado una lista de correo para avisar de notificaciones.... no se si sacarán algun aviso. Apuntaos a ver si dicen algo
          http://listas-ctt.administracionelectronica.gob.es/mailman/listinfo/face-notificacion

          Eliminar
        3. No sabía lo del listado y tampoco me lo comentaron. Gracias Cavernícola!

          Eliminar
        4. Apuntado, gracias Capitán!!!

          Yo he vuelto a llamar para volver a preguntar por los web services y lo mismo: Use la pasarela web...

          Un saludo.

          Eliminar
      62. No hay cambios en los webservices para proveedores (siguen sin funcionar correctamente).
        Ni enviar, ni consultar ni nada de nada. Creo que están tardando demasiado y perjudicando a muchas empresas.
        Un saludo.

        ResponderEliminar
      63. Por favor a ver si alguien me puede echar una mano.
        Al validar el xml generador a partir de las clases implementadas por Sergio al principio
        me dice que el formato es incorrecto
        me he dado cuenta que el comienzo es:

        ()
        (-)
        (-)

        y el generado por el programa facturae es: ( y el archivo que muestra Jaime es )

        ()
        (-)
        (-)

        por favor agradezco le ayuda. gracias

        ResponderEliminar
        Respuestas
        1. Es dificil saber lo que te pasa, llevas varios dias peléandote con esas clases, y cuando publicas no se ve nada, no crees que ya es hora de cambiar el rumbo y hacer un sencillo archivo plano, seguro que en un día lo tienes montado y ya no dependes de lo que te ponga la dichosa clase. Se que no es la forma más elegante ni tecnológica pero desde luego es la más rápida y fácil.

          Un saludo

          Eliminar
      64. Me han cerrado todas las incidencias. Han puesto "Resuelto" y realmente no se ha resuelto ni uno :)

        ResponderEliminar
        Respuestas
        1. Pues yo sigo en el mismo punto... "Ha ocurrido un error, consulte con el administrador". No ha llegado nada especialmente prospero a la lista de correo con respecto a los webservices...

          ¿Y la subida vía web? Funciona más o menos decente, porque nuestra necesidad es subir cientos de facturas :(

          Un saludo, gracias...

          Eliminar
        2. Exactamente en el mismo punto que yo. Ni enviar ni consultar facturas enviadas manualmente.
          Creo que están tardando mas de la cuenta. Lo que si me han comentado es que las CCAA y organismos están teniendo los mismos problemas y ahí están poniendo mas prioridad. Porque se les obliga a la mayoría a unirse al Face pero claro, si no funciona, poco van a poder adherirse :)

          Eliminar
        3. A mi me cerraron también la consulta sin solventar nada :( Encallado con el error "310 - Algún parámetro obligatorio aparece vacío" al enviar la factura.

          Eliminar
        4. El problema es grave pues los organismos no están tramitando las facturas si no las reciben por face, pero las personas de contacto son incapaces de darnos siquiera los datos de sus receptores apenas tengo una décima parte de los que debería tener y para colmo los receptores locales están tan liados como FACe.
          Esto es un completo caos y no sé donde vamos a llegar. Al paso que vamos se nos va a disparar la morosidad.
          El teléfono de FACe siempre dice: Nuestros operadores están ocupados...
          Menos mal que tenemos este sitio gracias a Sergio para ayudarnos e ir dando pasitos. Un Saludo a todos.

          Eliminar
        5. ¿Alguien ha podido resolver el problema del error "310 - Algún parámetro obligatorio aparece vacío" al enviar la factura?

          Un saludo.

          Eliminar
      65. Hola he comenzado con el tema de la Factura Electrónica. Tengo un proyecto .Net con la clase FacturaElectronica32.cs incluida.
        He creado el objeto factura.
        Facturae facturasE = new Facturae();
        Pero no se como rellenar la factura. Alguien me puede ayudar?
        facturasE.FileHeader.SchemaVersion = SchemaVersionType.Item32;
        Un saludo.

        ResponderEliminar
      66. buenas familia de facturae. En LinkedIn algunas personas insisten en que ya está funcionando. Puede que tengamos algún problema con la verificación de los certificados raíces o bien tengamos problemas con el certificado que usamos para firmar. Voy a investigar un poco y os digo. Un saludo.

        ResponderEliminar
        Respuestas
        1. Yo todos los días actualizo los servicios y nada: "1494253717803083 - Se ha producido un error, por favor consulte con el administrador". Eso subiendo facturas... Santa paciencia!!!

          Eliminar
        2. servicios actualizados y continuo con el error "310 - Algún parámetro obligatorio aparece vacío"

          Eliminar
      67. ¿Alguna novedad al respecto? Alguien ha podido enviar alguna factura o consultarla?
        Un saludo.

        ResponderEliminar
        Respuestas
        1. ¿Qué tal Jaime? Pues yo estoy en punto sugerente: intento subir una factura que ya ha sido subida vía portal web y el web service me dice que ya existe... eso pinta bien, ahora mismo pruebo con una que no esté subida... lo voy haciendo con tiento por aquello de ser un entorno de producción real... por la parte de la consulta, si consulto la factura subida a mano me dice lo mismo que a ti: "El sistema de Gestión de Proveedor no puede consultar la factura"

          Eliminar
        2. Hola,

          Factura subida OK!!!! Sin embargo, la consulta de la misma me devuelve "El sistema de Gestión de Proveedor no puede consultar la factura"

          Ahora estamos intentando acceder al portal...

          Eliminar
        3. a mi me da el mismo error "310 - Algún parámetro obligatorio aparece vacío" al enviar la factura. Explica tu solución como lo hace por favor Bob Rock. En que version .net estás compilando? a que servicio apuntas?.. cualquier detalle será bienvenido. Gracias

          Eliminar
        4. Para nosotros es tan importante el subir la factura como el saber el estado. Espero que lo solucionen pronto..

          Eliminar
        5. Josep.- He probado con tu mismo proyecto y todo ok. Pero he tenido que cambiar los siguiente:

          Dim fichero64 As String
          Dim byt As Byte() = System.Text.Encoding.UTF8.GetBytes(contenidoFichero)
          fichero64 = Convert.ToBase64String(byt)
          ssppFicheroFactura.factura = fichero64

          El contenidofichero es el xsig entero y verdadero. Si no lo codificas da el mensaje que te da a ti.

          Lo que tengo claro es que la factura está bien construida y firmada (primero he probado a subir una manualmente y luego a volver a subirla por el WS, entonces te tiene que decir que ya existe, en ese caso parece que ya ha pasado otras validaciones).

          Una vez enviada por WS te llegará un correo de traza al correo que le has indicado.

          A ver si hay suerte...

          Eliminar
        6. Gracias Bob Rock, ya me funciona correctamente.

          Un saludo.

          Eliminar
        7. Bob Rock: añadido ese código, pero ahora me da el error: {"1494546399054805 - Se ha producido un error, por favor consulte con el administrador"} . Estoy probando con la factura de ejemplo de Face, ¿puede ser por eso el error?

          Eliminar
        8. Josep.- Sí, esa factura no cuela al parecer. Lo que he intentado (para no subir facturas a real a tontas y a locas) es subir una ya procesada de forma manual, así al final me ha dicho que ya existía en su sistema... y finalmente he subido una que no existía y todo correcto!

          Un saludo

          Eliminar
      68. He probado de subir la factura de prueba manualmente y da error, así que creo que por eso me da el error. Mañana intentaré subir una factura real a ver si tengo suerte como vosotros, ya os contaré. Saludos.

        ResponderEliminar
        Respuestas
        1. Josep.- La de prueba es imposible subirla. Prueba una real, o mejor: una que ya hayas subido manualmente; verás que te da error pero uno coherente... salu2

          Eliminar
        2. Después de que ayer fue para varios un día de éxitos, hoy he intentado subir una factura (ya subida por el portal web) por primera vez con el web Service y me da el dichoso WSE910, sabéis si hay otra vez algún problema con el servicio, o hay algo más a hacer sobre el código de Josep:
          He cambiado la herencia
          'Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
          Inherits Microsoft.Web.Services3.WebServicesClientProtocol
          Y convertido la factura a Base64
          Dim fichero64 As String
          Dim byt As Byte() = System.Text.Encoding.UTF8.GetBytes(line)
          fichero64 = Convert.ToBase64String(byt)
          fra.factura = fichero64

          Saludos

          Eliminar
        3. Jaime, ese es tema de la firma del mensaje. Si usas el código de Josep o las indicaciones del blog de Jaime G.deberías de poder firmar la petición sin problema (siempre que tengas un certificado válido y demás)... luego está el tema de la canalización... pero insisto: el código de Josep y Jaime es correcto... tienes que tirar por ahí...

          Eliminar
        4. Haciendo pruebas, de repente me llegó un correo indicándome que mi factura había sido registrada, por tanto el camino es bueno, sólo falta saber cual fue el camino. El caso es que ya no me quedan facturas que probar y tendré que dejarlo para otro día, Gracias a todos.

          Eliminar
        5. He probado de subir una factura ya subida manualmente y efectivamente ahora el error que da es coherente, ya que dice que ya existe la misma en Face. :)

          Eliminar
        6. Subida una nueva factura correctamente. Saludos

          Eliminar
        7. Al final todo funcionando, no me funcionaba pues no había cambiado los servicios del app.config de mi proyecto, que sirva de aviso a los que tengan el dichoso WSE910.
          Gracias a todos y en especial a Sergio, Bob rock, Josep y a Jaime García que como decía en su página casi morimos en el intento.
          Supongo que nos volveremos a ver por aquí cuando estos linces cambien la firma, el webservice o se les ocurra cualquier otra chorrada a nuestros gobernantes.
          Un saludo.

          Eliminar
        8. Un placer Jaime! haber si solucionan poder consultar el estado de las facturasQue feliz me harían!

          Eliminar
        9. Jaime. No entiendo tu problema, la consulta puntual de una factura con SSPPResultadoConsultarFactura dando el número de registro devuelve perfectamente el estado en tramitacion.codigo_estado.
          ¿Qué estado estas buscando?
          Saludos

          Eliminar

      69. en esta línea me da este error:
        Excepción no controlada del tipo 'es.mityc.javasign.pkstore.CertStoreException' en MITyCLibCert-1.0.4.dll

        y no tengo ni idea de programación.... :(

        ResponderEliminar
      70. Este comentario ha sido eliminado por el autor.

        ResponderEliminar
      71. Perdona Conchi por contestar aquí otra pregunta de Jaime, fue una confusión

        En cuanto a lo tuyo es difícil ayudarte pues das pocos datos.
        Lo que si te puedo decir es que eso me pasó al mezclar el proyecto de Sergio y el de Josep y lo solucioné poniendo partes del App.config de Josep en mi proyecto de escritorio, pues al integrar el webservice de face dio un error parecido al tuyo.
        Saludos

        ResponderEliminar
        Respuestas
        1. Dándole más vueltas también cambié los imports que estaban mezclando librería, creo que fue esto mñas que el config, poniendo sólo en el envío las siguientes:
          Imports Microsoft.Web.Services3
          Imports Microsoft.Web.Services3.Security
          Imports Microsoft.Web.Services3.Security.Tokens
          Imports Microsoft.Web.Services3.Security.X509
          Imports Microsoft.Web.Services3.Design
          Imports System.Security.Cryptography

          Saludos

          Eliminar
      72. Pues me devuelve este error Jaime: 1494897971006307 - 301 - El sistema de Gestion de proveedor no puede consultar la factura
        No se si es porque estoy intentando consultar facturas presentadas manualmente (es decir, que solo dejen consultar las presentadas via webservice, lo cual, no tiene mucho sentido).

        ResponderEliminar
      73. Te confirmo tu intuición, he probado las manuales y dan ese error, en cambio las dos que he presentado vía webservice me responden bien y yo que estaba tan contento. Con esta gente todo es posible. Habrá que reportarlo.
        Y para colmo han quitado el 900 y han puesto un 902 que después de la alocución se pasa minutos y minutos diciendo que sus operadores están ocupados.
        Saludos

        ResponderEliminar
      74. Ya no me da ese error, creo que era el certificado de pruebas que estaba seleccionando. Ahora tengo otro problema, uso un certificado original de persona física, lo selecciono y no me da error, simplemente no me sale nada, ni me firma el fichero ni da ningún tipo de mensaje... porque puede ser??? ejecuto el FirmaFacturaE.exe directamente

        ResponderEliminar
      75. Este comentario ha sido eliminado por el autor.

        ResponderEliminar
      76. Hola, entro en https://github.com/miamon/Face-Web-Service me descargo el proyecto y no lo puedo abrir con VS 2010. ¿Sabeis porque?

        ResponderEliminar
      77. Hola, estoy enviando una factura manualmente con formato .xsig y me salta el siguiente 1494919195818857 - No se han especificado correctamente el Pagador, Receptor o Fiscal

        En la factura he incluido los campos de organo gestor, organo contable y unidad tramitadora. ¿Alguien sabe que puede estar pasando?

        ResponderEliminar
      78. Pues eso que no debes de tener bien hecho el buyer. al principio de los tiempos dejé un ejemplo que funciona compra lo que Seguro que es cualquier chorrada.

        ResponderEliminar
      79. Antes de nada, Sergio, Jaime Mombiela, Iván Ferrer y a cuantos habéis contribuido a hacerme la vida más fácil con vuestras aportaciones, muchas gracias!!!.
        Después de implementar vuestra solución, me surge una duda. Todo funciona perfectamente (en http://sedeaplicaciones2.minetur.gob.es/FacturaE/index.jsp valida correctamente la factura firmada), pero sin embargo, en la ejecución del código arroja una serie de errores java que no controlo: Todo este mogollón ¿Me ayudarías a indicarme cuál puede ser el problema? ¿Hasta qué punto es importante si valida correctamente?


        26-feb-2015 8:09:46 es.mityc.javasign.i18n.I18nFactory instantiateManager
        GRAVE: Error en la inicializaci¾n del manager con el diccionario MITyCLibCert
        es.mityc.javasign.i18n.DictionaryUnknownException: java.util.MissingResourceException: Can't find bundle for base name i18n/dictionaries/MITyCLibCert, locale es_ES
        at es.mityc.javasign.i18n.I18nDefaultManager.init(I18nDefaultManager.java:83)
        at es.mityc.javasign.i18n.I18nFactory.instantiateManager(I18nFactory.java:362)
        at es.mityc.javasign.i18n.I18nFactory.getI18nManager(I18nFactory.java:316)
        at es.mityc.javasign.i18n.I18nFactory.getI18nManager(I18nFactory.java:297)
        at es.mityc.javasign.pkstore.keystore.KeyTool.(KeyTool.java:52)
        at es.mityc.javasign.pkstore.keystore.KSStore.(KSStore.java:49)
        at cli.wpfexades.Firma.LoadCertificate(Firma.vb:37)
        at cli.wpfexades.Main.Firmalo(Main.vb:83)
        at cli.wpfexades.Main.Main(Main.vb:53)
        Caused by: java.util.MissingResourceException: Can't find bundle for base name i18n/dictionaries/MITyCLibCert, locale es_ES
        at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1539)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1278)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:804)
        at es.mityc.javasign.i18n.I18nDefaultManager.init(I18nDefaultManager.java:81)
        ... 8 more
        26-feb-2015 8:09:46 es.mityc.javasign.i18n.I18nFactory instantiateManager
        GRAVE: Error en la inicializaci¾n del manager con el diccionario MITyCLibTrust
        es.mityc.javasign.i18n.DictionaryUnknownException: java.util.MissingResourceException: Can't find bundle for base name i18n/dictionaries/MITyCLibTrust, locale es_ES
        at es.mityc.javasign.i18n.I18nDefaultManager.init(I18nDefaultManager.java:83)
        at es.mityc.javasign.i18n.I18nFactory.instantiateManager(I18nFactory.java:362)
        at es.mityc.javasign.i18n.I18nFactory.getI18nManager(I18nFactory.java:316)
        at es.mityc.javasign.i18n.I18nFactory.getI18nManager(I18nFactory.java:297)
        at es.mityc.javasign.trust.PropsTruster.(PropsTruster.java:106)
        at es.mityc.javasign.trust.PropsTruster.getInstance(PropsTruster.java)
        at cli.wpfexades.Main.Firmalo(Main.vb:92)
        at cli.wpfexades.Main.Main(Main.vb:53)
        Caused by: java.util.MissingResourceException: Can't find bundle for base name i18n/dictionaries/MITyCLibTrust, locale es_ES
        at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1539)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1278)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:804)
        at es.mityc.javasign.i18n.I18nDefaultManager.init(I18nDefaultManager.java:81)
        ... 7 more

        [Continúa en siguiente post por superar límite máximo]

        ResponderEliminar