Facturación Electrónica en Perú (I)

Hace algunos días me propuse como proyecto personal, crear mi propia librería de generar documentos de facturación electrónica, y claro enviarlos al servicio web de SUNAT (la entidad tributaria acá en Perú).

Cabe señalar que hace tiempo trabajé en una empresa que tenía un software de facturación electrónica, pero nunca me hice cargo del desarrollo de la funcionalidad de generar el XML o enviarlo a SUNAT. Esa parte ya lo había desarrollado una empresa de terceros, un compañero se encargaba del mantenimiento de dicha librería, y en ocasiones puntuales yo lo reemplacé, pero para ser coherentes yo no tenía idea de lo que estaba haciendo, gracias a mi compañero, que era el verdadero amo de ese código, que me dio indicaciones aunque estaba de vacaciones y seguramente me odió un poco por interrumpirle el merecido descanso.

Volviendo al presente, hace dos semanas, me puse la tarea de crear un programa que termine generando el XML de una factura y enviarlo al servicio web de SUNAT. No le he dedicado muchas horas pero uno o dos días si me pudo más el reto y acabé madrugando para resolver algunas cosas.

Seguramente hay muchos expertos por ahí, y aclaro que no he realizado un software de facturación electrónica, sólo son mis pruebas en C#, pero quería comentar mi experiencia y que es lo que me ha pasado y que he llegado a conocer.

Acá les comento.

 La documentación de SUNAT


Con la documentación publicada por SUNAT he tenido y tengo, una relación de amor y odio. En muchas ocasiones, mucho odio.  La página que debe ser la biblia de la facturación electrónica en Perú es cpe.sunat.gob.pe.

Hay una parte de esa página donde dice "Todo lo que necesitas saber" y entiendo que SUNAT dice que es lo que necesitas saber según ellos, si necesitas saber más, ya es tu problema, averigua.

Generalmente la documentación de SUNAT  se entiende, pero en muchas ocasiones me he encontrado con que la información está desactualizada, y que incluso sus ejemplos no pasan la validación que ellos mismos ponen.

Para la parte técnica, el enlace al que debes ir es cpe.sunat.gob.pe/node/88. Al momento que estoy escribiendo esta entrada, la fecha de actualización es del 10 de Octubre del 2020. Dentro de ese enlace podemos descargar las reglas de validación (un archivo Excel con bastante información, pero complicado de utilizar), el facturador SUNAT y lo más importante para empezar con el desarrollo: los archivos XSL y XSD. Luego están los anexos y las guías.

XML se vuelve sencillo cuando sabes que hacer y tienes las herramientas


Ahora leí y volví a leer el manual del programador y la guía de factura electrónica y creo un proyecto en C#, pero luego veo que crear el XML a mano va a ser escalar el Everest sin oxígeno. Les tengo pena y respeto a los que programan en PHP, porque si no encuentran una librería que les haga el trabajo de crear el XML lo hacen a mano, nodo por nodo.

Pero como soy un .NET lover, y uso C# lo tengo un poco más fácil. .NET Framework tiene ya incorporado las librerías de manejo de XML (System.Xml). Pero igual, según mi anterior experiencia de factura electrónica, había que crear clase por clase para representar cada nodo del Xml según la estructura que necesita SUNAT. Era una pesadilla, así que casi abandono, con mis responsabilidades en casa y en mi trabajo, pues ponerme un par de semanas a solo escribir clases para representar cada nodo necesario me volvería loco.

Pero buscando la alternativa me encuentro con varias páginas que indican que se pueden crear las clases necesarias en C# utilizando los XSD que publica SUNAT.

Yo seguí las indicaciones de la página de Jom Sistemas.

Les doy el ejemplo:
xsd CCTS_CCT_SchemaModule-2.1.xsd UBL-CommonAggregateComponents-2.1.xsd UBL-CommonBasicComponents-2.1.xsd UBL-CommonExtensionComponents-2.1.xsd UBL-CommonSignatureComponents-2.1.xsd UBL-CoreComponentParameters-2.1.xsd UBL-ExtensionContentDataType-2.1.xsd UBL-QualifiedDataTypes-2.1.xsd UBL-SignatureAggregateComponents-2.1.xsd UBL-SignatureBasicComponents-2.1.xsd UBL-UnqualifiedDataTypes-2.1.xsd UBL-XAdESv132-2.1.xsd UBL-XAdESv141-2.1.xsd UBL-xmldsig-core-schema-2.1.xsd ./UBL-Invoice-2.1.xsd /c

¿De dónde salieron esos archivos? Cuando descargas de la página de SUNAT los XSD, tienes dos carpetas: common y maindoc. En common están todos los XSD básicos y comunes que se van a utilizar en todos los documentos electrónicos. En maindoc encontramos los xsd correspondientes a la factura, la boleta, la nota de crédito o débito, etc. Combinando los xsd que encontramos, nos permite generar una clase con toda la estructura necesaria para posteriormente generar un Xml correcto sintáticamente.

Esa sentencia se ejecuta en la línea de comandos. La herramienta xsd (XML Schema Definition Tool) te permite generar clases a partir de esquemas XSD.

La sentencia anterior te genera un archivo en C# de casi 2 megas. Si, es una clase enorme, y cada vez que veo dentro de esa clase me imagino lo que me habría tomado escribirla toda. No hay forma, gracias a los creadores del comando xsd. Con la clase generada ya había solo que crear una instancia de esa clase y empezar a llenar la información.

No encuentras información sobre lo que necesitas en la forma en que la necesitas


Espero se entienda. Es decir, si buscas como enviar el Xml generado a SUNAT con C# te dicen que se hace de tal manera pero es información del 2015 o incluso anterior y ya no funciona con la versión actual.

En internet encontré mucha información (incluso open source) para hacer un sistema de facturación electrónica en PHP, muchos ejemplos, pero como no conozco PHP es como si no encontrara nada. Es mi culpa, debería conocer más de PHP.

También vi varios ejemplos y proyectos open source en java. Java es muy parecido a C# pero no es lo mismo. Sino se llamarían igual.

Encontré mucha información compartida para facturación electrónica en otros países, lo que sirve de algo pero que claramente no había mucho que aplicar para entendernos con SUNAT.

Ahora, no es que eso me desanime. Esto es algo que sucede y sucederá siempre que estés investigando algo que no conoces o conoces muy poco, la idea es utilizar lo que encuentres y filtrar o convertir algo de lo que encuentres para que te termine sirviendo. Para desarrollar software hay que ser una persona que se adapta rápidamente, y considero que hay que buscar y averiguar más.

Enviar a los servicios web de SUNAT


Cuando ya tienes el Xml generado, necesitas comprimirlo (formato zip) y proceder a enviarlo a los servicios web de SUNAT.

Tengo Visual Studio 2019 Community e intenté varias veces agregar la referencia al servicio de SUNAT para que se me generen las clases necesarias de forma automática.

Nunca me funcionó. Ya me había dado el trabajo de generar el XML, ahora nunca sabría lo que SUNAT me respondería cuando se lo enviara. Estaba contento y triste a la vez. Sin la retroalimentación me quedaría sin conocer si lo había elaborado correctamente.

Era un obstáculo muy grande para completar mi proyecto. No sabía si era mi Visual Studio o si era mi conexión a internet o que SUNAT me había bloqueado.

Ahora recordé que en mi anterior trabajo utilizaban SoapUI para hacer las pruebas. Así que lo descargué y lo instalé. Armé la solicitud según lo que indicaba el manual del programador y ¡pasó!. SUNAT decía que mi Xml estaba mal, pero había logrado comunicarme. Aunque me respondía mal, era una respuesta. Entonces el problema era Visual Studio. Por lo que seguía atascado en ese punto.

Hasta ahora no puedo agregar la referencia.

¿Se acabó ahí? No. Encontré la página de Diogo Nunes, donde tiene un artículo llamado "Calling Web Service without WSDL or Web Reference" publicado en el 2014. En resumen, te explica como llamar a un servicio web sin WSDL o agregar la referencia web. El código publicado lo mejora en "Calling a Web Method in C# without Service Reference" (2014).

Combinando ambos artículos y entendiendo lo que hizo el buen Diogo, pude enviar el Xml desde C# hacia SUNAT sin necesidad de agregar una referencia al servicio web.

Luego hay que interpretar la respuesta de SUNAT, pero esa es otra historia.

Certificado de prueba y firmar el XML


Yo generé mi propio certificado digital para realizar pruebas. Con openssl. Ahora, también puedes descargarte un certificado de prueba desde llama.pe. Para producción claramente tienes que comprar un certificado. En llama están publicados los precios.

El certificado para firmar tiene la extensión pfx.

El código para firmar lo obtuve de una página que ya no encuentro el enlace, creo recordar que está en Youtube, pero no estoy seguro. Ahora, el autor lo hizo como un tutorial y comentaba que la firma era para SUNAT, ahora, como dije al inicio, es mi proyecto personal, no está probado en producción, así que no lo publico hasta encontrar al autor y estar seguro que funciona en producción, me imagino que sí, pero SUNAT tiene formas misteriosas de trabajar y no puedo asegurar que esto funciona si o si.

Comprimir el XML


Ahora, según lo que vemos en el manual del programador de SUNAT, pensamos que necesitamos comprimir el XML y ya está preparado para ponerlo en el horno, es decir enviar al servicio web de SUNAT.

Técnicamente en C# tenemos las herramientas para generar un archivo zip, no es necesario recurrir a librerías de terceros.

Ahora, no se comprime directamente el XML y ya está. Al menos desde C# hay que convertir el contenido del Xml a una cadena Base64, y luego incluirlo en el zip.

Por experiencia recomiendo que el proceso de generar el Xml y luego el Zip se haga en memoria, en sí evita todo lo posible de trabajar con archivos. Y esto en general aplica en el caso de varias aplicaciones, no sólo de facturación electrónica, trabajar con archivos a veces nos pone en problemas de permisos de lectura, de escritura, bloqueo de los mismos, etc.

Las respuestas de SUNAT


He identificado al menos tres niveles de validación a tu envío de factura electrónica.

  • Si tu llamada es incorrecta, el servicio web de SUNAT te va a responder con un mensaje "Error interno", y te hace creer que es un error de ellos, pero en realidad "no eres tú SUNAT, soy yo".

  • Si la llamada es correcta, pero has armado mal el xml o el zip o no has puesto el nombre correcto, tienes que buscar el problema en el nodo fault de la respuesta.

  • Si la llamada es correcta y has armado bien tu Xml y tu Zip, ahora SUNAT te dirá o que está todo bien (del todo) o que está bien, pero tiene observaciones.


En conclusión, tienes que analizar cada respuesta que te envíe SUNAT. Para mí es más sencillo resolver los errores u observaciones que se refieren a la estructura de los nodos que a los cálculos, porque ahí hay que ir a la documentación y si no tienes un mínimo de conocimientos de contabilidad, vas a estar en problemas.

Recomendaciones en caso quieras perder el tiempo de la misma forma entrar en el mundo de la facturación electrónica



  • No te confíes de los ejemplos en la documentación. Me imagino que el equipo de facturación electrónica de SUNAT actualiza la documentación cada cierto tiempo, pero se olvidan de los ejemplos.

  • Hay que formatear los montos (casi siempre) con dos decimales.

  • En algunas partes, cuando el monto es 0, no se debe indicar.

  • Recuerda a los OSE, quienes son prácticamente los dueños del negocio de la facturación electrónica, sino los conoces, averigua sobre ellos.


Conclusión


Estoy contento con lo que he podido hacer. Envié una factura simple a SUNAT y me respondió que la factura fue aceptada, sin errores ni observaciones. La factura era gravada, sin descuentos ni otras complicaciones. Mi siguiente paso será generar facturas con distintos tipos de afectación de IGV.

Facturación Electrónica II - Arreglando errores.

 

Comentarios

  1. Buenas tardes, podrías compartir el código de como agregar el web service por código por favor

    ResponderBorrar

Publicar un comentario