VirtualXML® Librería de FuncionesVirtualXML

VirtualXML es una librería de funciones para facturación electrónica en formato DLL para Windows de 32 y 64 bits desarrollada por Cibernética y Tecnología, S.A. de C.V. desde el año 2013.

VirtualXML crea archivos XML 100% compatibles con las versiones 3.2 y 3.3 de Comprobantes Fiscales Digitales, de acuerdo a las especificaciones del Anexo 20 de la RMF, de una manera fácil y efectiva, simplemente llamando a un conjunto de funciones especificamente diseñadas para crear todos y cada uno de los nodos de un documento XML CFDI, por lo que los XMLs generados con ella pasan perfectamente todas las validaciones del SAT.

VirtualXML adicionamente firma digitalmente los XMLs generados, genera sello digital de la factura y envía a certificar digitalmente el documento (timbre fiscal digital) a nuestro servicio VirtualPAC.

VirtualXML es compatible con todos los lenguajes de programación que soporten el uso de DLLs para el sistema operativo Windows, desde la version XP Service pack 2 hasta Windows 10, pasando por Windows Server desde 2003 hasta 2016.

Para los lenguajes que no soporten el uso de DLLs, VirtualXML provee de un "ejecutable externo" y su propio lenguaje interpretado (scripting) que mediante la generación de un archivo de texto con la extensión VXML le permitirá hacer uso de todas y cada una de las funciones de la libreria externamente.

¿ Cómo funciona VirtualXML ?

Las funciones de VirtualXML van "construyendo" en la memoria de la computadora un archivo XML, de acuerdo a la versión de facturación electrónica que se desea certificar: 3.2 o 3.3

Cada función de  VirtualXML va creando determinados nodos del archivo XML, cuyos atributos son los valores pasados a la función como parámetros, si un parámetro no se manda, el atributo no se crea.

Usar VirtualXML es muy sencillo, comenzamos con la asignación a una variable del resultado de una llamada simple a la primer función:

          hXml := VirtualXML_New ( "3.3" )

Esta llamada a la primer función de VirtualXML hace 2 cosas:

  1. Crea un  "handle", un espacio en memoria donde se va a generar el archivo XML. Este "handle" es un valor numérico que será usado como primer parámetro en las llamadas subsecuentes a otras funciones de VirtualXML.
  2. Agrega al XML que se está creando en la memoria de la computadora la siguiente información, en este caso, hemos elegido crear un XML de la versión 3.3 de CFDI:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3"
                                                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                                       xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                                       Version="3.3"
                        </cfdi:Comprobante>

A partir de este punto, cada llamada a una función de VirtualXML creará un nodo y sus distintos atributos, por ejemplo, si deseamos agregar mas información al nodo <cfdi:Comprobante> haremos:


          VirtualXML_SetComprobanteInfo_cfdi33( hXml, "A", "1", "%cb_date", "99", "Contado Comercial", "1000.00", "50.00", "MXN", "", "1102.00", "I", "PPD", "53050", "" )

Lo cual complementará el nodo del XML del ejemplo anterior, el cual quedará (en la memoria de la computadora) asi:


                         <?xml version="1.0" encoding="UTF-8"?>
                         <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3"
                                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                                        xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                                        Version="3.3"
                                                        Serie="A"
                                                        Folio="1"
                                                        Fecha="%cb_date"                                            
                                                        Sello=""
                                                        FormaPago="99"
                                                        NoCertificado=""
                                                        Certificado=""
                                                        CondicionesDePago="Contado Comercial"
                                                        SubTotal="1000.00"
                                                        Descuento="50.00"
                                                        Moneda="MXN"
                                                        Total="1102.00"
                                                        TipoDeComprobante="I"
                                                        MetodoPago="PPD"
                                                        LugarExpedicion="53050">
                         </cfdi:Comprobante>


Podemos seguir llamando funciones, por ejemplo, para añadir la información de emisor y receptor del CFDI usaremos:


         VirtualXML_SetEmisorInfo_cfdi33 ( hXml, "AAA010101AAA", "Empresa de prueba SA de CV", "601" )
         VirtualXML_SetReceptorInfo_cfdi33 ( hXml, "CTE940531F58", "Cibernetica y Tecnología SA de CV", "", "", "G01" )

Y nuestro XML en memoria ahora quedaría así:

                         <?xml version="1.0" encoding="UTF-8"?>
                         <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3"
                                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                                        xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                                        Version="3.3"
                                                        Serie="A"
                                                        Folio="1"
                                                        Fecha="%cb_date"                                            
                                                        Sello=""
                                                        FormaPago="99"
                                                        NoCertificado=""
                                                        Certificado=""
                                                        CondicionesDePago="Contado Comercial"
                                                        SubTotal="1000.00"
                                                        Descuento="50.00"
                                                        Moneda="MXN"
                                                        Total="1102.00"
                                                        TipoDeComprobante="I"
                                                        MetodoPago="PPD"
                                                        LugarExpedicion="53050">
                                    <cfdi:Emisor Rfc="AAA010101AAA" Nombre="Empresa de prueba SA de CV" RegimenFiscal="601"/>
                                    <cfdi:Receptor Rfc="CTE940531F58" Nombre="Cibernetica y Tecnología SA de CV" UsoCFDI="G01"/>
                         </cfdi:Comprobante>

Ahora agreguemos un concepto y sus respectivos impuestos:

              VirtualXML_AddConcepto_cfdi33 ( hXml, "84111506", "SEF250", "2", "H87", "Timbre", "Paquete de 500 timbres fiscales", "250.00", "500.00", "50.00" )
              VirtualXML_AddConceptoTraslado_cfdi33 ( hXml, "450.00", "002", "Tasa", "0.160000", "72.00" )

Nuestro XML en memoria ahora está así:


                         <?xml version="1.0" encoding="UTF-8"?>
                         <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3"
                                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                                        xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                                        Version="3.3"
                                                        Serie="A"
                                                        Folio="1"
                                                        Fecha="%cb_date"                                            
                                                        Sello=""
                                                        FormaPago="99"
                                                        NoCertificado=""
                                                        Certificado=""
                                                        CondicionesDePago="Contado Comercial"
                                                        SubTotal="1000.00"
                                                        Descuento="50.00"
                                                        Moneda="MXN"
                                                        Total="1102.00"
                                                        TipoDeComprobante="I"
                                                        MetodoPago="PPD"
                                                        LugarExpedicion="53050">
                                    <cfdi:Emisor Rfc="AAA010101AAA" Nombre="Empresa de prueba SA de CV" RegimenFiscal="601"/>
                                    <cfdi:Receptor Rfc="CTE940531F58" Nombre="Cibernetica y Tecnología SA de CV" UsoCFDI="G01"/>
                                    <cfdi:Conceptos>
                                                     <cfdi:Concepto ClaveProdServ="84111506" NoIdentificacion="SEF500" Cantidad="1" ClaveUnidad="H87" Unidad="Timbre"
                                                                             Descripcion="Paquete de 500 timbres fiscales" ValorUnitario="500.00" Importe="500.00">
                                                             <cfdi:Impuestos>
                                                                     <cfdi:Traslados>
                                                                                 <cfdi:Traslado Base="500.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="80.00"/>
                                                                      </cfdi:Traslados>
                                                             </cfdi:Impuestos>
                                    </cfdi:Concepto>
                         </cfdi:Comprobante>

Finalmente, agregaremos información de los impuestos:

           VirtualXML_SetImpuestosInfo_cfdi33 ( hXml, "152.00", "" )
           VirtualXML_AddTraslado_cfdi33 ( hXml, "002", "Tasa", "0.160000", "152.00" )

Nuestro XML en memoria está listo !!!!!!:

                         <?xml version="1.0" encoding="UTF-8"?>
                         <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3"
                                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                                        xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"
                                                        Version="3.3"
                                                        Serie="A"
                                                        Folio="1"
                                                        Fecha="%cb_date"                                            
                                                        Sello=""
                                                        FormaPago="99"
                                                        NoCertificado=""
                                                        Certificado=""
                                                        CondicionesDePago="Contado Comercial"
                                                        SubTotal="1000.00"
                                                        Descuento="50.00"
                                                        Moneda="MXN"
                                                        Total="1102.00"
                                                        TipoDeComprobante="I"
                                                        MetodoPago="PPD"
                                                        LugarExpedicion="53050">
                                    <cfdi:Emisor Rfc="AAA010101AAA" Nombre="Empresa de prueba SA de CV" RegimenFiscal="601"/>
                                    <cfdi:Receptor Rfc="CTE940531F58" Nombre="Cibernetica y Tecnología SA de CV" UsoCFDI="G01"/>
                                    <cfdi:Conceptos>
                                                     <cfdi:Concepto ClaveProdServ="84111506" NoIdentificacion="SEF500" Cantidad="1" ClaveUnidad="H87" Unidad="Timbre"
                                                                             Descripcion="Paquete de 500 timbres fiscales" ValorUnitario="500.00" Importe="500.00">
                                                             <cfdi:Impuestos>
                                                                     <cfdi:Traslados>
                                                                                 <cfdi:Traslado Base="500.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="80.00"/>
                                                                      </cfdi:Traslados>
                                                             </cfdi:Impuestos>
                                    </cfdi:Concepto>
                                    <cfdi:Impuestos TotalImpuestosTrasladados="152.00">
                                             <cfdi:Traslados>
                                                   <cfdi:Traslado Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="152.00"/>
                                             </cfdi:Traslados>
                                    </cfdi:Impuestos>
                         </cfdi:Comprobante>

Ahora podemos "procesarlo". Este "procesamiento" realiza 4 operaciones:
  • Firma digitalmente el documento conviertiendo el archivo .CER a Base64 y complementa los atributos Certificado y NoCertificado.
  • Genera el Sello Digital del comprobante usando el archivo .KEY y su password (genera cadena original, digesto SHA-256 para CFDI 3.3 ó SHA-1 para CFDI 3.2 y encriptamiento RSA-Encrypt para ambos casos)
  • Envía a nuestro servicio VirtualPAC el comprobante para que sea firmado por alguno de nuestros Proveedores Autorizado de Certificacion
  • Recoge el resultado del proceso de timbrado, genera el CBB en formato BMP y PNG y escribe a disco el archivo XML final el cual se encuenta Firmado, Sellado y Timbrado digitalmente.
El procesamiento del XML en memoria se hace usando la función:

                          VirtualXML_ProcesaDocumento (hXml, "AAA010101AAA.cer", "AAA010101AAA.key", "12345678a", "EjemploCFDI33.xml")

Esta función devuelve un valor numérico, si este valor es "0" (cero) el procesamiento del XML ha sido exitoso, de lo contrario devuelve un valor numérico negativo, para conocer una descripción del código de error se puede consultar la tabla de Códigos de error.

Si el procesamiento fue exitoso, entoces podemos recuperar los valores que deberán ir en el documento impreso, estos valores se recuperan con uno o varios llamados a la función:

                          VirtualXML_GetValue (hXml, <valor a recuperar>)

Esta función devuelve una cadena de caracteres con el valor a recupera, estos valores  son 21 y se obtienen pasando un número del 1 al 21 en el parámetro <valor a recuperar>. Estos valores se pueden consultar en la tabla de Valores para recuperar información.

Por último liberamos el espacio en memoria ocupado por el XML porque ya no lo vamos a utilizar mas con la función:

                         VirtualXML_Free (hXml)

Classes

  ClassDescription
Public classVirtualXML
Libreria VirtualXML
Public classVirtualXML_Wrappers
Tablas de valores

  TablaDescripción
Public enumerationVirtualXML VirtualXML_Errors_Code
Codigos de Error devueltos por las funciones de procesamiento
Public enumerationVirtualXML VirtualXML_Values_Code
Codigos para obtener valores del procesamiento usadas en las funciones GetValue