﻿# virtualxml-cfdi

[![MIT License][license-image]][license-url]
[![NPM version][npm-version-image]][npm-url]
[![NODE version][node-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]

[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat
[license-url]: LICENSE
[npm-version-image]: https://img.shields.io/npm/v/virtualxml-cfdi.svg?style=flat
[npm-url]: https://www.npmjs.com/package/virtualxml-cfdi
[npm-downloads-image]: http://img.shields.io/npm/dt/virtualxml-cfdi.svg?style=flat
[node-version-image]: https://img.shields.io/node/v/virtualxml-cfdi.svg?style=flat

## Librería para firmar, sellar y timbrar CFDI v4.0

<!-- toc -->
- [Introducción](#introducción)
- [Características](#características)
- [Instalación](#instalación)
- [Requisitos](#requisitos)
- [Información DEMO](#información-demo)
- [Contacto](#contacto)
- [Métodos](#métodos)
  - [cancelaCFDI2022](#cancelacfdi2022)
  - [addFunctionCall](#addfunctioncall)
  - [emiteCFDI40](#emitecfdi40)
- [Métodos Administrativos](#métodos-administrativos)
  - [adminEmisorAdd](#adminemisoradd)
  - [adminEmisorUpd](#adminemisorupd)
  - [adminEmisorAsigna](#adminemisorasigna)
  - [adminEmisorAutoasignacion](#adminemisorautoasignacion)
  - [adminUsuarioAdd](#adminusuarioadd)
  - [adminUsuarioUpd](#adminusuarioupd)
  - [adminUsuarioAsigna](#adminusuarioasigna)
- [Proceso de Timbrado](#proceso-de-timbrado)
- [Sitio Demo](#demo)
  - [Uso del demo](#usodemo)
- [Funciones Referenciadas CFDI40 para Timbrado](#funciones-referenciadas-para-timbrado "Funciones Referenciadas para Timbrado")
  - [Básicas CFDI v40](#cfdi40básicas)
  - [Conceptos CFDI v40](#cfdi40conceptos)
  - [Complemento Concepto Instituciones Educativas v1.0 ](#cfdiconceptoscomplementoconceptoiedu10)
  - [Complemento Concepto Venta Vehiculos v1.1 ](#cfdiconceptoscomplementoconceptoventavehiculos11)
  - [Complementos](#cfdicomplementos)
    - [Carta Porte v3.0 ](#cfdicomplementocartaporte30)  
    - [Nómina v1.2 ](#cfdicomplementonomina12)  
    - [Comercio Exterior v2.0 ](#cfdicomplementocce20)
    - [Pagos v2.0](#cfdicomplementopagos20)          
    - [Impuestos Locales v1.0](#cfdicomplementoimpuestoslocales10)
    - [Donatarias v1.1](#cfdicomplementodonatarias11)
    - [INE v1.1](#cfdicomplementoine11)
    - [Divisas v1.0](#cfdicomplementodivisas10)
    - [Aerolíneas v1.0](#cfdicomplementoaerolineas10)
    - [Notarios Públicos v1.0](#cfdicomplementonotariospublicos10)
    - [Renovacion y Sustitución Vehicular v1.0](#cfdicomplementovehiculorenovacionsustitucionvehiculo10)
    - [Leyendas Fiscales v1.0](#cfdicomplementoleyendasfiscales10)
    - [Vehículo Usado v1.0](#cfdicomplementovehiculousado10)
    - [Servicios Parciales de Construción v1.0](#cfdicomplementoservicioparcial10)
    - [Spei de Tercero a Tercero v1.0](#cfdicomplementospei10)
    - [Estado de cuenta de combustibles de monederos electrónicos v1.2](#cfdicomplementoestadocuentacombustible12)
    - [Consumo de Combustibles v1.1](#cfdicomplementoconsumodecombustibles11)
    - [Pago en Especie v1.0](#cfdicomplementopagoenespecie10)
    - [Persona Fisica Integrante Coordinado v1.0](#cfdicomplementopfintegrantecoordinado10)
    - [Turista Pasajero Extranjero v1.0](#cfdicomplementoturistapasajeroextranjero10)
    - [Vales de Despensa v1.0](#cfdicomplementovalesdedespensa10)
    - [Detallista v1.0](#cfdicomplementodetallista10)
  - [Especiales](#cfdiespeciales) 
- [Ejemplos](#ejemplos)
- [Changelog](#changelog)
<!-- tocstop -->


### Introducción
Librería para la generación y cancelación de **CFDI 4.0** y **CFDI 3.3**, incluidos todos los complementos vigentes. Incluye el proceso de firmado, Sellado y tambien el Timbrado por medio del servicio de **[VirtualPAC](http://virtual-pac.mx)**, de acuerdo a la especificación del **[SAT](http://www.sat.gob.mx)**. 


### Características
* Generación de CFDI 4.0
* Generación de CFDI 3.3
* Generación de todos los complementos vigentes:
  * [Complementos y Complementos Concepto]
* Generación de representacion impresa simple (PDF)
* Generación de Codigo de Barras Bidimensional en formatos: png, jpg y bmp
* Sellado local (tu llave privada y clave son usadas localmente)
* Soporta la solicitud de **Cancelación** de CFDI con el formato vigente a 2022 (tu llave privada y clave son usadas localmente)

### Instalación
NPM:

    $ npm install --save virtualxml-cfdi

### Requisitos
* Contar con un CSD vigente (Certificado de Sello Digital). 
* Contar con los archivos .cer, .key 
* Contar con la clave del archivo .key
* En caso de desear timbrar con credenciales diferentes al demo; haber contratado un plan de timbres con **[VirtualPAC](http://virtual-pac.mx)** 

**NOTA:** Los archivos .cer/.key de la FIEL no funcionan para el proceso de timbrado, deberan usarse los del CSD

### Información DEMO
Estas credenciales pueden usarse sin necesidad de ningun tipo de registro
 * usuario: **demo_nodejs**
 * rfcemisor: **EKU9003173C9**
 * Certificado Emisor: **CSD_EKU9003173C9.cer** *(archivo ubicado dentro de la carpeta "test" del paquete)*
 * Llave Privada Emisor: **CSD_EKU9003173C9.key** *(archivo ubicado dentro de la carpeta "test" del paquete)*
 * Clave Llave Privada: **12345678a**


### Contacto
 * Correo electronico: soporte@ciber-tec.com

### Métodos

###### **cancelaCFDI2022**
Procesa la solicitud de cancelación y devuelve el Acuse de solicitud/estatus Cancelación en caso de ser exitoso.
> Esta funcion implementa los nuevos requisitos de cancelacion aplicables a partir de 2022.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **uuid**                | Cadena                | Sí        | FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
   **motivo**              | Cadena                | Sí        | 02
   **foliosust**           | Cadena                | Sí        | Texto en blanco si no se usa
   **certificado**         | Cadena                | Sí        | ./MisCertificados/EKU9003173C9.cer o Base64 (MIIF+TCCA+GgAwIBAgI...)
   **llaveprivada**        | Cadena                | Sí        | ./MisCertificados/EKU9003173C9.key o Base64 (MIIFDjBABgkqhkiG9w0...)
   **clave**               | Cadena                | Sí        | 12345678a
   **outbasepath**         | Cadena                | No        | ../../salida/
   **outprefix**           | Cadena                | No        | prefijo
   **outsuffix**           | Cadena                | No        | sufijo

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un **exitcode = 201** o **exitcode = 202**, un **uuid** y un **acuse**. Cualquier otro valor sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 201, 
    "message": "201 - Solicitud de cancelación recibida."
    "uuid": "025357315-4D60-4E56-A056-7AA0B1D8D95F", 
    "acuse": "XML del acuse en base64"
    }
    ```
  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 202, 
    "message": "202 - UUID Previamente cancelado."
    "uuid": "025357315-4D60-4E56-A056-7AA0B1D8D95F", 
    "acuse": "XML del acuse en base64"
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": 205, 
    "message": "CA205 - El UUID no existe => Error al cancelar el UUID de la factura"
    }
    ```


###### **addFunctionCall**
Agrega al Stack FIFO una llamada referenciada a la funcion **funcName** con los parámetros especificados.  
* **Parametros**
   Nombre              | Tipo                  | Requerido | Ejemplo 
   ------------------- | -------------------   | --------  | --------
   **funcName**        | Cadena                | Sí        | VirtualXML_SetEmisorInfo_cfdi40
   **...args**         | Multi parámetros      | Sí        | 'EKU9003173C9', 'NombreDelEmisorRazónSocial', '601'

**NOTA:** Dependiendo de la funcion referenciada (**funcName**), el numero de parámetros varía. Ver las funciones disponibles y numero de argumentos en la sección [funciones referenciadas para timbrado](#funciones-referenciadas-para-timbrado)

* **Retorno**
La instancia de la clase, para usarse con llamadas secuenciales en 1 sola linea si se desea.


##### emiteCFDI40
Procesa Stack de funciones e intenta timbrar el documento generado.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **certificado**         | Cadena                | Sí        | ./MisCertificados/EKU9003173C9.cer o Base64 (MIIF+TCCA+GgAwIBAgI...)
   **llaveprivada**        | Cadena                | Sí        | ./MisCertificados/EKU9003173C9.key o Base64 (MIIFDjBABgkqhkiG9w0...)
   **clave**               | Cadena                | Sí        | 12345678a
   **outbasepath**         | Cadena                | No        | ../../salida/
   **outprefix**           | Cadena                | No        | prefijo
   **outsuffix**           | Cadena                | No        | sufijo
   **qrpng**               | Bool                  | No        | true
   **qrbmp**               | Bool                  | No        | false
   **qrjpg**               | Bool                  | No        | false
   **pdf**                 | Bool                  | No        | true

* **Retorno**
Regresa una promesa. Un timbrado exitoso resolvera la promesa (resolve/then) y la respuesta contendra un **exitcode = 0**, un **uuid** y un **xmltimbrado**. Cualquier otro valor sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    "uuid": "025357315-4D60-4E56-A056-7AA0B1D8D95F", 
    "xmltimbrado": "XML en base64", 
	"cadenasat": "Cadena Original del complemento de certificación digital del SAT", 
    "qrpng": "QR.png en base64",
    "qrjpg": "QR.jpg en base64",
    "qrbmp": "QR.bmp en base64",
    "pdf": "Representacion impresa PDF en base64",
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -5, 
    "message": "Algunas funciones no son validas: VirtualXML_NoExiste"
    }
    ```


### Métodos Administrativos
Métodos útiles para la gestion y mantenimiento de RFC emisores, usuarios (distribuidores) y la asignación de timbres manual o automática; posibilitando una administracion por medio del este paquete sin necesidad de hacer uso del portal administrativo.
Para el uso de todos estos métodos, es requerida una **APIKEY**

###### **adminEmisorAdd**
Alta de un nuevo RFC emisor.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **pwdconsulta**         | Cadena                | Sí        | SomeSecret. Usar texto en blanco para no establecer el valor
   **razonsocial**         | Cadena                | Sí        | Some Company AC.
   **email**               | Cadena                | Sí        | email@soporte.com. Texto en blanco si no se usa
   **contacto**            | Cadena                | Sí        | IT guy. Texto en blanco si no se usa
   **asignacion**          | Int                   | Sí        | 100
   **suspendido**          | Bool                  | Sí        | false
   **notificacion**        | Bool                  | Sí        | true
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "RFC previamente agregado"
    }
    ```

###### **adminEmisorUpd**
Actualizacion de la informacion general de un RFC emisor asociado a la cuenta del usuario.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **pwdconsulta**         | Cadena                | Sí        | SomeSecret. Usar texto en blanco para no establecer o alterar el valor actual
   **razonsocial**         | Cadena                | Sí        | Some Company AC.
   **email**               | Cadena                | Sí        | email@soporte.com. Texto en blanco si no se usa
   **contacto**            | Cadena                | Sí        | IT guy. Texto en blanco si no se usa
   **suspendido**          | Bool                  | Sí        | false
   **notificacion**        | Bool                  | Sí        | true
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -3, 
    "message": "Usuario/APIKEY invalida"
    }
    ```

###### **adminEmisorAsigna**
Realiza una asignacion de timbres al RFC emisor.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **asignacion**          | Int                   | Sí        | 100
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "No se permiten asignaciones en 0 o negativas"
    }
    ```

###### **adminEmisorAutoasignacion**
Crea o modifica la regla de autoasignación de timbres al RFC emisor. Cuando el total de timbres disponibles del emisor alcance el valor **threshold**, se asignaran el numero de timbres **asignacion** siempre que la regla se encuentre **activa** y el número de timbres totales asignados historicamente al emisor no supere el valor **limite**.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **rfcemisor**           | Cadena                | Sí        | EKU9003173C9
   **asignacion**          | Int                   | Sí        | 100
   **threshold**           | Int                   | Sí        | 20
   **limit**               | Int                   | Sí        | 5000
   **active**              | Bool                  | Sí        | false
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "Los timbres para asignar no debe ser mayor al total de tus timbres disponibles"
    }
    ```

###### **adminUsuarioAdd**
Alta de un usuario-hijo (**distribuidor**) relacionado al usuario actual. Este usuario podrá gestionar sus propios emisores y timbres de forma independiente pero podra recibir asignacion de timbres directamente del **usuario padre**.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **distribuidor**        | Cadena                | Sí        | childUserName
   **pwd**                 | Cadena                | Sí        | SomeSecret. Usar texto en blanco para no establecer el valor
   **razonsocial**         | Cadena                | Sí        | Some Company AC.
   **email**               | Cadena                | Sí        | email@soporte.com. Texto en blanco si no se usa
   **contacto**            | Cadena                | Sí        | IT guy. Texto en blanco si no se usa
   **asignacion**          | Int                   | Sí        | 100
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "Ya existe un usuario con este nombre"
    }
    ```

###### **adminUsuarioUpd**
Actualizacion de la informacion general de un usuario-hijo (**distribuidor**) RFC emisor asociado a la cuenta del usuario actual.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **distribuidor**        | Cadena                | Sí        | childUserName
   **pwd**                 | Cadena                | Sí        | SomeSecret. Usar texto en blanco para no establecer o alterar el valor actual
   **razonsocial**         | Cadena                | Sí        | Some Company AC.
   **email**               | Cadena                | Sí        | email@soporte.com. Texto en blanco si no se usa
   **contacto**            | Cadena                | Sí        | IT guy. Texto en blanco si no se usa
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "Nombre de usuario en blanco"
    }
    ```

###### **adminUsuarioAsigna**
Realiza una asignacion de timbres al usuario-hijo (**distribuidor**) tomando los timbres disponibles del usuario actual.

* **Parametros**
   Nombre                  | Tipo                  | Requerido | Ejemplo 
   -------------------     | -------------------   | --------  | --------
   **apikey**              | Cadena                | Sí        | 1pIp-j-ZVVff2H2-Y54yTtYpW-Uhdffw8Pb3pJGRt7o
   **usuario**             | Cadena                | Sí        | demo_nodejs
   **distribuidor**        | Cadena                | Sí        | childUserName
   **asignacion**          | Int                   | Sí        | 100
   **reserved**            | Cadena                | No        | 

* **Retorno**
Regresa una promesa. Una solicitud exitosa resolvera la promesa (resolve/then) y la respuesta contendra un campo **exitcode** y **message**. Cualquier valor de exitcode diferente a 0 sera un error en el proceso y debera referirse al mensaje **message = ...** normalmente en el rechazo (reject/catch) de la promesa<br/><br/>

  * **Resolve (Then)**
    ```javascript
    { 
    "exitcode": 0, 
    "message": ""
    }
    ```
  
  * **Reject (Catch)**
    ```javascript
    { 
    "exitcode": -2, 
    "message": "Nombre de usuario en blanco"
    }
    ```


### Proceso de Timbrado
El siguiente diagrama muestra el proceso de timbrado completo:
# ![virtualxml-cfdi](http://virtual-pac.mx/images/VirtualXML-NodeJS.png)

### Demo
En el siguiente enlace se podra descargar un demo que incluye:
- **Cliente Web**: Contiene un formulario simple que sirve de interface para llenar la informacion del CFDI asi como observar la respuesta obtenida por el uso de **virtualxml-cfdi** por parte del servidor.
- **Servidor**: Sirve como capa de negocio exponiendo un servicio REST que procesa las solicitudes del cliente y hace uso de este paquete (**virtualxml-cfdi**) para la firma, sellado y timbrado del CFDI. 

**NOTA:** El paquete virtualxml-cfdi puede ejecutarse en cualquier version Node 4+. Este demo utiliza la version minima de Node 12+

[**Descarga aqui - version minima NodeJS v12+**](http://virtual-pac.mx/virtualxml-server-client-demo-nodev12.zip)

##### UsoDemo

Abrir linea de comandos en folder server y ejecutar:

    $ npm install
    $ npm start

Abrir linea de comandos en folder client

    $ npm install
    $ npm start

Abrir browser en direccion http://localhost:3000 y probar el demo.

### Funciones Referenciadas para Timbrado
Estas funciones son añadidas a una pila FIFO (FirstIn-FirstOut) para ser enviadas y ejecutadas remotamente. Constan de un nombre **funcName** y de 1 o mas parámetros. <br/>
Las funciones se agregan a la pila mediante el metodo [addFunctionCall](#addfunctioncall) una vez que la clase VirtualXML ha sido instanciada. El siguiente ejemplo ilustra el modo de uso:

Los parámetros de **funcName** deberan ser de tipo cadena independientemente del tipo de dato que representen, y deberan tener el formato que corresponda de acuerdo a los lineamientos del **SAT**.

Los parámetros de **funcName** deberan ser una cadena vacia si no contiene informacion, y debera respetarse la posicion de los mismos.

```javascript
const VirtualXML = require('virtualxml-cfdi');
const vxml = new VirtualXML(); // Nueva Instancia
vxml.addFunctionCall( 'VirtualXML_SetComprobanteInfo_cfdi40', // **funcName**
                      'NOM',                                  // param01 = Serie
                      '1',                                    // param02 = Folio
                      '2018-01-30T05:24:30',                  // param03 = Fecha
                      '01',                                   // param04 = FormaPago
                      'CondiciónDePago',                      // param05 = CondicionesDePago
                      '5000.00',                              // param06 = SubTotal
                      '',                                     // param07 = Descuento
                      'MXN',                                  // param08 = Moneda
                      '',                                     // param09 = TipoCambio
                      '5000.00',                              // param10 = Total
                      'I',                                    // param11 = TipoDeComprobante
                      'PUE',                                  // param12 = MetodoPago
                      '68025',                                // param13 = LugarExpedicion
                      '',                                     // param14 = Confirmacion
                      '01');                                  // param15 = Exportacion 
```
Se pueden agregar tantas llamadas como se necesiten para el correcto llenado del CFDI, teniendo en cuenta que algunos elementos que pueden aparecer varias veces (ej. cfdi.Conceptos), a su vez podran contener un detalle y las funciones del detalle afectaran al ultimo elemento padre al que pertenece. Por ejemplo:

```javascript
const VirtualXML = require('virtualxml-cfdi');
const vxml = new VirtualXML(); // Nueva Instancia
vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'A', '1', FechaCFDI, '99', 'Contado Comercial', '1000.00', '50.00', 'MXN', '', '1102.00', 'I', 'PPD', '53050', '', '01'); 
vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'MAG041126GT8', 'NombreDelReceptorRazónSocial', '', '', 'G01', '53050', '601');
vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', 'SEFXXX', '1', 'H87', 'Unidad', 'Paquete X - ObjetoImp1', '500.00', '500.00', '', '02');
vmlx.addFunctionCall('VirtualXML_AddConceptoCuentaPredial_cfdi40','5678901');
vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', 'SEFXXX', '2', 'H87', 'Unidad', 'Paquete X - ObjetoImp2', '250.00', '500.00', '50.00', '02');
vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', 'SEFXXX', '2', 'H87', 'Unidad', 'Paquete X - ObjetoImp3', '250.00', '500.00', '50.00', '02');
vxml.addFunctionCall('VirtualXML_AddConceptoTraslado_cfdi40', '450.00', '002', 'Tasa', '0.160000', '72.00');
// Para funciones que afectan informacion unica, NO importa el momento en que se llamen
vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'NombreDelEmisorRazónSocial', '601',''); 
// Esta funcion afectara al ultimo CONCEPTO agregado
vmlx.addFunctionCall('VirtualXML_AddConceptoRetencion_cfdi40','3000.00','003','Tasa','0.300000','900.00');
```

El resultado seria un CFDI con la siguiente estructura:

```
CFDI
|--Emisor
|--Receptor
|--Conceptos
      |--Concepto01
            |--CuentaPredial
      |--Concepto02
      |--Concepto03
            |--Impuestos
                  |--Traslado
                  |--Retencion
```

##### CFDI40.Básicas
* **VirtualXML_SetComprobanteInfo_cfdi40**
   * [01] Serie
   * [02] Folio
   * [03] Fecha
   * [04] FormaPago
   * [05] CondicionesDePago
   * [06] SubTotal
   * [07] Descuento
   * [08] Moneda
   * [09] TipoCambio
   * [10] Total
   * [11] TipoDeComprobante
   * [12] MetodoPago
   * [13] LugarExpedicion
   * [14] Confirmacion
   * [15] Exportacion

* **VirtualXML_SetInformacionGlobal_cfdi40**
   * [01] Periodicidad
   * [02] Meses
   * [03] Año


* **VirtualXML_AddCfdiRelacionados_cfdi40**
   * [01] TipoRelacion
   * [02] UUID1
   * [03] UUID2
   * [04] UUID3
   * [05] UUID4
   * [06] UUID5
   * [07] UUID6
   * [08] UUID7
   * [09] UUID8
   * [10] UUID9
   * [11] UUID10

* **VirtualXML_AddCfdiRelacionado_cfdi40** *(Usar antes AddCfdiRelacionados_cfdi40)*
   * [01] UUID

* **VirtualXML_SetEmisorInfo_cfdi40**
   * [01] Rfc
   * [02] Nombre
   * [03] RegimenFiscal
   * [04] FacAtrAdquirente

* **VirtualXML_SetReceptorInfo_cfdi40**
   * [01] Rfc
   * [02] Nombre
   * [03] ResidenciaFiscal
   * [04] NumRegIdTrib
   * [05] UsoCFDI
   * [06] DomicilioFiscalReceptor
   * [07] RegimenFiscalReceptor

* **VirtualXML_SetImpuestosInfo_cfdi40**
   * [01] TotalImpuestosTrasladados
   * [02] TotalImpuestosRetenidos

* **VirtualXML_AddTraslado_cfdi40** *(Usar antes SetImpuestosInfo_cfdi40)*
   * [01] Impuesto
   * [02] TipoFactor
   * [03] TasaOCuota
   * [04] Importe
   * [05] Base

* **VirtualXML_AddRetencion_cfdi40** *(Usar antes SetImpuestosInfo_cfdi40)*
   * [01] Impuesto
   * [02] Importe

* **VirtualXML_SetAddenda**
   * [01] FragmentoXML *(Debe ser válido e incluir los namespaces que no sean parte de un CFDI)*

* **VirtualXML_SetAddendaText**
   * [01] TextoAddenda

##### CFDI40.Conceptos
* **VirtualXML_AddConcepto_cfdi40**
   * [01] ClaveProdServ
   * [02] NoIdentificacion
   * [03] Cantidad
   * [04] ClaveUnidad
   * [05] Unidad
   * [06] Descripcion
   * [07] ValorUnitario
   * [08] Importe
   * [09] Descuento
   * [10] ObjetoImp

* **VirtualXML_AddConceptoTraslado_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] Base
   * [02] Impuesto
   * [03] TipoFactor
   * [04] TasaOCuota
   * [05] Importe

* **VirtualXML_AddConceptoRetencion_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] Base
   * [02] Impuesto
   * [03] TipoFactor
   * [04] TasaOCuota
   * [05] Importe

* **VirtualXML_AddConceptoInformacionAduanera_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] NumeroPedimento

* **VirtualXML_AddConceptoCuentaPredial_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] Numero

* **VirtualXML_AddConceptoParte_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] ClaveProdServ
   * [02] NoIdentificacion
   * [03] Cantidad
   * [04] Unidad
   * [05] Descripcion
   * [06] ValorUnitario
   * [07] Importe
   * [08] NumeroPedimento1
   * [09] NumeroPedimento2
   * [10] NumeroPedimento3
   * [11] NumeroPedimento4
   * [12] NumeroPedimento5

* **VirtualXML_SetConceptoACuentaTerceros_cfdi40** *(Usar antes AddConcepto_cfdi40)*
   * [01] RfcACuentaTerceros
   * [02] NombreACuentaTerceros
   * [03] RegimenFiscalACuentaTerceros
   * [04] DomicilioFiscalACuentaTerceros


##### CFDI.Conceptos.ComplementoConcepto.iedu10

* **VirtualXML_AddConceptoComplementoIedu10** *(Usar antes AddConcepto)*
   * [01] nombreAlumno
   * [02] CURP
   * [03] nivelEducativo
   * [04] autRVOE
   * [05] rfcPago

##### CFDI.Conceptos.ComplementoConcepto.ventavehiculos11

* **VirtualXML_AddConceptoComplementoVentaVehiculos11_cfdi40** *(Usar antes AddConcepto)*
   * [01] ClaveVehicular
   * [02] Niv
   * [03] numero
   * [04] fecha
   * [05] aduana);

##### CFDI.Complemento.CartaPorte30

La respuesta de este complemento incluye la URL usada para el QR especifico CCP30, y de solicitarse las imagenes de QR, tambien el QRCCP30

* **VirtualXML_SetCartaPorte30**
   * [01] IdCCP
   * [02] TranspInternac
   * [03] RegimenAduanero
   * [04] EntradaSalidaMerc
   * [05] PaisOrigenDestino
   * [06] ViaEntradaSalida
   * [07] TotalDistRec
   * [08] RegistroISTMO
   * [09] UbicacionPoloOrigen
   * [10] UbicacionPoloDestino

* **VirtualXML_CartaPorte30AddUbicacion** *(Usar antes SetCartaPorte30)*
   * [01] TipoUbicacion
   * [02] IDUbicacion
   * [03] RFCRemitenteDestinatario
   * [04] NombreRemitenteDestinatario
   * [05] NumRegIdTrib
   * [06] ResidenciaFiscal
   * [07] NumEstacion
   * [08] NombreEstacion
   * [09] NavegacionTrafico
   * [10] FechaHoraSalidaLlegada
   * [11] TipoEstacion
   * [12] DistanciaRecorrida
   * [13] Calle
   * [14] NumeroExterior
   * [15] NumeroInterior
   * [16] Colonia
   * [17] Localidad
   * [18] Referencia
   * [19] Municipio
   * [20] Estado
   * [21] Pais
   * [22] CodigoPostal

* **VirtualXML_CartaPorte30SetMercancias**
   * [01] PesoBrutoTotal
   * [02] UnidadPeso
   * [03] PesoNetoTotal
   * [04] NumTotalMercancias
   * [05] CargoPorTasacion
   * [06] LogisticaInversaRecoleccionDevolucion

* **VirtualXML_CartaPorte30AddMercancia** *(Usar antes CartaPorte30SetMercancias)*
   * [01] BienesTransp
   * [02] ClaveSTCC
   * [03] Descripcion
   * [04] Cantidad
   * [05] ClaveUnidad
   * [06] Unidad
   * [07] Dimensiones
   * [08] MaterialPeligroso
   * [09] CveMaterialPeligroso
   * [10] Embalaje
   * [11] DescripEmbalaje
   * [12] SectorCOFEPRIS
   * [13] NombreIngredienteActivo
   * [14] NomQuimico
   * [15] DenominacionGenericaProd
   * [16] DenominacionDistintivaProd
   * [17] Fabricante
   * [18] FechaCaducidad
   * [19] LoteMedicamento
   * [20] FormaFarmaceutica
   * [21] CondicionesEspTransp
   * [22] RegistroSanitarioFolioAutorizacion
   * [23] PermisoImportacion
   * [24] FolioImpoVUCEM
   * [25] NumCAS
   * [26] RazonSocialEmpImp
   * [27] NumRegSanPlagCOFEPRIS
   * [28] DatosFabricante
   * [29] DatosFormulador
   * [30] DatosMaquilador
   * [31] UsoAutorizado
   * [32] PesoEnKg
   * [33] ValorMercancia
   * [34] Moneda
   * [35] FraccionArancelaria
   * [36] UUIDComercioExt
   * [37] TipoMateria
   * [38] DescripcionMateria

* **VirtualXML_CartaPorte30SetDetalleMercancia** *(Usar antes CartaPorte30AddMercancia)*
   * [01] UnidadPesoMerc
   * [02] PesoBruto
   * [03] PesoNeto
   * [04] PesoTara
   * [05] NumPiezas

* **VirtualXML_CartaPorte30AddMercanciaDocumentacionAduanera** *(Usar antes CartaPorte30AddMercancia)*
   * [01] TipoDocumento
   * [02] NumPedimento
   * [03] IdentDocAduanero
   * [04] RFCImpo

* **VirtualXML_CartaPorte30AddMercanciaGuiasIdentificacion** *(Usar antes CartaPorte30AddMercancia)*
   * [01] NumeroGuiaIdentificacion
   * [02] DescripGuiaIdentificacion
   * [03] PesoGuiaIdentificacion

* **VirtualXML_CartaPorte30AddMercanciaCantidadTransporta** *(Usar antes CartaPorte30AddMercancia)*
   * [01] Cantidad
   * [02] IDOrigen
   * [03] IDDestino
   * [04] CvesTransporte

* **VirtualXML_CartaPorte30SetMercanciasAutotransporte** *(Usar antes CartaPorte30AddMercancia)*
   * [01] PermSCT
   * [02] NumPermisoSCT
   * [03] ConfigVehicular
   * [04] PesoBrutoVehicular
   * [05] PlacaVM
   * [06] AnioModeloVM
   * [07] AseguraRespCivil
   * [08] PolizaRespCivil
   * [09] AseguraMedAmbiente
   * [10] PolizaMedAmbiente
   * [11] AseguraCarga
   * [12] PolizaCarga
   * [13] PrimaSeguro
   * [14] SubTipoRem1
   * [15] Placa1
   * [16] SubTipoRem2
   * [17] Placa2

* **VirtualXML_CartaPorte30SetMercanciasTransporteMaritimo** *(Usar antes CartaPorte30AddMercancia)*
   * [01] PermSCT
   * [02] NumPermisoSCT
   * [03] NombreAseg
   * [04] NumPolizaSeguro
   * [05] TipoEmbarcacion
   * [06] Matricula
   * [07] NumeroOMI
   * [08] AnioEmbarcacion
   * [09] NombreEmbarc
   * [10] NacionalidadEmbarc
   * [11] UnidadesDeArqBruto
   * [12] TipoCarga
   * [13] Eslora
   * [14] Manga
   * [15] Calado
   * [16] Puntal
   * [17] LineaNaviera
   * [18] NombreAgenteNaviero
   * [19] NumAutorizacionNaviero
   * [20] NumViaje
   * [21] NumConocEmbarc
   * [22] PermisoTempNavegacion

* **VirtualXML_CartaPorte30SetMercanciasTransporteMaritimoRemolquesCCP** *(Usar antes CartaPorte30SetMercanciasTransporteMaritimo)*
   * [01] SubTipoRemCCP1
   * [02] PlacaCCP1
   * [03] SubTipoRemCCP2
   * [04] PlacaCCP2

* **VirtualXML_CartaPorte30AddMercanciasTransporteMaritimoContenedor** *(Usar antes CartaPorte30SetMercanciasTransporteMaritimo)*
   * [01] TipoContenedor
   * [02] MatriculaContenedor
   * [03] NumPrecinto
   * [04] IdCCPRelacionado
   * [05] PlacaVMCCP
   * [06] FechaCertificacionCCP

* **VirtualXML_CartaPorte30SetMercanciasTransporteAereo** *(Usar antes CartaPorte30AddMercancia)*
   * [01] PermSCT
   * [02] NumPermisoSCT
   * [03] MatriculaAeronave
   * [04] NombreAseg
   * [05] NumPolizaSeguro
   * [06] NumeroGuia
   * [07] LugarContrato
   * [08] CodigoTransportista
   * [09] RFCEmbarcador
   * [10] NumRegIdTribEmbarc
   * [11] ResidenciaFiscalEmbarc
   * [12] NombreEmbarcador

* **VirtualXML_CartaPorte30SetMercanciasTransporteFerroviario** *(Usar antes CartaPorte30AddMercancia)*
   * [01] TipoDeServicio
   * [02] TipoDeTrafico
   * [03] NombreAseg
   * [04] NumPolizaSeguro
   * [05] TipoDerechoDePaso
   * [06] KilometrajePagado
   * [07] TipoCarro
   * [08] MatriculaCarro
   * [09] GuiaCarro
   * [10] ToneladasNetasCarro
   * [11] TipoContenedor
   * [12] PesoContenedorVacio
   * [13] PesoNetoMercancia

* **VirtualXML_CartaPorte30AddMercanciasTransporteFerroviarioDerechosDePaso** *(Usar antes CartaPorte30SetMercanciasTransporteFerroviario)*
   * [01] TipoDerechoDePaso
   * [02] KilometrajePagado

* **VirtualXML_CartaPorte30AddMercanciasTransporteFerroviarioCarro** *(Usar antes CartaPorte30SetMercanciasTransporteFerroviario)*
   * [01] TipoCarro
   * [02] MatriculaCarro
   * [03] GuiaCarro
   * [04] ToneladasNetasCarro
   * [05] TipoContenedor
   * [06] PesoContenedorVacio
   * [07] PesoNetoMercancia

* **VirtualXML_CartaPorte30AddMercanciasTransporteFerroviarioCarroContenedor** *(Usar antes CartaPorte30SetMercanciasTransporteFerroviario)*
   * [01] TipoContenedor
   * [02] PesoContenedorVacio
   * [03] PesoNetoMercancia

* **VirtualXML_CartaPorte30AddFiguraTransporteTiposFigura**
   * [01] TipoFigura
   * [02] RFCFigura
   * [03] NumLicencia
   * [04] NombreFigura
   * [05] NumRegIdTribFigura
   * [06] ResidenciaFiscalFigura
   * [07] ParteTransporte
   * [08] Calle
   * [09] NumeroExterior
   * [10] NumeroInterior
   * [11] Colonia
   * [12] Localidad
   * [13] Referencia
   * [14] Municipio
   * [15] Estado
   * [16] Pais
   * [17] CodigoPostal

* **VirtualXML_CartaPorte30AddFiguraTransporteTiposFiguraPartesTransporte** *(Usar antes CartaPorte30AddFiguraTransporteTiposFigura)*
   * [01] ParteTransporte


##### CFDI.Complemento.Nomina12

* **VirtualXML_SetNomina12**
   * [01] TipoNomina
   * [02] FechaPago
   * [03] FechaInicialPago
   * [04] FechaFinalPago
   * [05] NumDiasPagados
   * [06] TotalPercepciones
   * [07] TotalDeducciones
   * [08] TotalOtrosPagos 

* **VirtualXML_Nomina12SetEmisor** *(Usar antes SetNomina12)*
   * [01] Curp
   * [02] RegistroPatronal
   * [03] RfcPatronOrigen
   * [04] OrigenRecurso
   * [05] MontoRecursoPropio 

* **VirtualXML_Nomina12SetReceptor** *(Usar antes SetNomina12)*
   * [01] Curp
   * [02] NumSeguridadSocial
   * [03] FechaInicioRelLaboral
   * [04] Antigüedad
   * [05] TipoContrato
   * [06] Sindicalizado
   * [07] TipoJornada
   * [08] TipoRegimen
   * [09] NumEmpleado
   * [10] Departamento
   * [11] Puesto
   * [12] RiesgoPuesto
   * [13] PeriodicidadPago
   * [14] Banco
   * [15] CuentaBancaria
   * [16] SalarioBaseCotApor
   * [17] SalarioDiarioIntegrado
   * [18] ClaveEntFed 

* **VirtualXML_Nomina12AddSubContratacion** *(Usar antes Nomina12SetReceptor)*
   * [01] RfcLabora
   * [02] PorcentajeTiempo 

* **VirtualXML_Nomina12SetPercepciones** *(Usar antes SetNomina12)*
   * [01] TotalSueldos
   * [02] TotalSeparacionIndemnizacion
   * [03] TotalJubilacionPensionRetiro
   * [04] TotalGravado
   * [05] TotalExento 

* **VirtualXML_Nomina12AddPercepcion** *(Usar antes Nomina12SetPercepciones)*
   * [01] TipoPercepcion
   * [02] Clave
   * [03] Concepto
   * [04] ImporteGravado
   * [05] ImporteExento
   * [06] Dias
   * [07] TipoHoras
   * [08] HorasExtra
   * [09] ImportePagado
   * [10] ValorMercado
   * [11] PrecioAlOtorgarse 


* **VirtualXML_Nomina12SetJubilacionPensionRetiro** *(Usar antes Nomina12SetPercepciones)*
   * [01] TotalUnaExhibicion
   * [02] TotalParcialidad
   * [03] MontoDiario
   * [04] IngresoAcumulable
   * [05] IngresoNoAcumulable 

* **VirtualXML_Nomina12SetSeparacionIndemnizacion** *(Usar antes Nomina12SetPercepciones)*
   * [01] TotalPagado
   * [02] NumAñosServicio
   * [03] UltimoSueldoMensOrd
   * [04] IngresoAcumulable
   * [05] IngresoNoAcumulable 

* **VirtualXML_Nomina12SetDeducciones** *(Usar antes SetNomina12)*
   * [01] TotalOtrasDeducciones
   * [02] TotalImpuestosRetenidos 

* **VirtualXML_Nomina12AddDeduccion** *(Usar antes Nomina12SetDeducciones)*
   * [01] TipoDeduccion
   * [02] Clave
   * [03] Concepto
   * [04] Importe 

* **VirtualXML_Nomina12AddOtroPago** *(Usar antes SetNomina12)*
   * [01] TipoOtroPago
   * [02] Clave
   * [03] Concepto
   * [04] Importe
   * [05] SaldoAFavor
   * [06] Año
   * [07] RemanenteSalFav
   * [08] SubsidioCausado 

* **VirtualXML_Nomina12AddIncapacidad** *(Usar antes SetNomina12)*
   * [01] DiasIncapacidad
   * [02] TipoIncapacidad
   * [03] ImporteMonetario 

##### CFDI.Complemento.cce20


* **VirtualXML_SetComercioExterior20**
   * [01] MotivoTraslado
   * [02] ClaveDePedimento
   * [03] CertificadoOrigen
   * [04] NumCertificadoOrigen
   * [05] NumeroExportadorConfiable
   * [06] Incoterm
   * [07] Observaciones
   * [08] TipoCambioUSD
   * [09] TotalUSD

* **VirtualXML_CCE20SetEmisor** *(Usar antes SetComercioExterior20)*
   * [01] Curp
   * [02] Calle
   * [03] NumeroExterior
   * [04] NumeroInterior
   * [05] Colonia
   * [06] Localidad
   * [07] Referencia
   * [08] Municipio
   * [09] Estado
   * [10] Pais
   * [11] CodigoPostal

* **VirtualXML_CCE20SetReceptor** *(Usar antes SetComercioExterior20)*
   * [01] NumRegIdTrib
   * [02] Calle
   * [03] NumeroExterior
   * [04] NumeroInterior
   * [05] Colonia
   * [06] Localidad
   * [07] Referencia
   * [08] Municipio
   * [09] Estado
   * [10] Pais
   * [11] CodigoPostal

* **VirtualXML_CCE20AddDestinatario** *(Usar antes SetComercioExterior20)*
   * [01] NumRegIdTrib
   * [02] Nombre
   * [03] Calle
   * [04] NumeroExterior
   * [05] NumeroInterior
   * [06] Colonia
   * [07] Localidad
   * [08] Referencia
   * [09] Municipio
   * [10] Estado
   * [11] Pais
   * [12] CodigoPostal

* **VirtualXML_CCE20AddDestinatarioDomicilio** *(Usar antes CCE20AddDestinatario)*
   * [01] Calle
   * [02] NumeroExterior
   * [03] NumeroInterior
   * [04] Colonia
   * [05] Localidad
   * [06] Referencia
   * [07] Municipio
   * [08] Estado
   * [09] Pais
   * [10] CodigoPostal

* **VirtualXML_CCE20AddPropietario** *(Usar antes SetComercioExterior20)*
   * [01] NumRegIdTrib
   * [02] ResidenciaFiscal

* **VirtualXML_CCE20AddMercancia** *(Usar antes SetComercioExterior20)*
   * [01] NoIdentificacion
   * [02] FraccionArancelaria
   * [03] CantidadAduana
   * [04] UnidadAduana
   * [05] ValorUnitarioAduana
   * [06] ValorDolares
   * [07] Marca
   * [08] Modelo
   * [09] SubModelo
   * [10] NumeroSerie

* **VirtualXML_CCE20AddMercanciaDescripcionesEspecificas** *(Usar antes CCE20AddMercancia)*
   * [01] Marca
   * [02] Modelo
   * [03] SubModelo
   * [04] NumeroSerie


##### CFDI.Complemento.pagos20

* **VirtualXML_SetPagos20**
   * [01] TotalRetencionesIVA
   * [02] TotalRetencionesISR
   * [03] TotalRetencionesIEPS
   * [04] TotalTrasladosBaseIVA16
   * [05] TotalTrasladosImpuestoIVA16
   * [06] TotalTrasladosBaseIVA8
   * [07] TotalTrasladosImpuestoIVA8
   * [08] TotalTrasladosBaseIVA0
   * [09] TotalTrasladosImpuestoIVA0
   * [10] TotalTrasladosBaseIVAExento
   * [11] MontoTotalPagos

* **VirtualXML_Pagos20AddPago** *(Usar antes SetPagos20)*
   * [01] FechaPago
   * [02] FormaDePagoP
   * [03] MonedaP
   * [04] TipoCambioP
   * [05] Monto
   * [06] NumOperacion
   * [07] RfcEmisorCtaOrd
   * [08] NomBancoOrdExt
   * [09] CtaOrdenante
   * [10] RfcEmisorCtaBen
   * [11] CtaBeneficiario
   * [12] TipoCadPago
   * [13] CertPago
   * [14] CadPago
   * [15] SelloPago

* **VirtualXML_Pagos20AddPagoDoctoRelacionado** *(Usar antes Pagos20AddPago)*
   * [01] IdDocumento
   * [02] Serie
   * [03] Folio
   * [04] MonedaDR
   * [05] EquivalenciaDR
   * [06] NumParcialidad
   * [07] ImpSaldoAnt
   * [08] ImpPagado
   * [09] ImpSaldoInsoluto
   * [10] ObjetoImpDR

* **VirtualXML_Pagos20AddPagoDoctoRelacionadoRetencionDR** *(Usar antes Pagos20AddPagoDoctoRelacionado)*
   * [01] BaseDR
   * [02] ImpuestoDR
   * [03] TipoFactorDR
   * [04] TasaOCuotaDR
   * [05] ImporteDR

* **VirtualXML_Pagos20AddPagoDoctoRelacionadoTrasladoDR** *(Usar antes Pagos20AddPagoDoctoRelacionado)*
   * [01] BaseDR
   * [02] ImpuestoDR
   * [03] TipoFactorDR
   * [04] TasaOCuotaDR
   * [05] ImporteDR

* **VirtualXML_Pagos20AddPagoImpuestosPRetencionP** *(Usar antes Pagos20AddPago)*
   * [01] ImpuestoP
   * [02] ImporteP

* **VirtualXML_Pagos20AddPagoImpuestosPTrasladoP** *(Usar antes Pagos20AddPago)*
   * [01] BaseP
   * [02] ImpuestoP
   * [03] TipoFactorP
   * [04] TasaOCuotaP
   * [05] ImporteP

##### CFDI.Complemento.ImpuestosLocales10

* **VirtualXML_SetImpuestosLocales10**
   * [01] TotaldeTraslados
   * [02] TotaldeRetenciones

* **VirtualXML_ImpLocal10AddRetencionesLocales** *(Usar antes SetImpuestosLocales10)*
   * [01] ImpLocRetenido
   * [02] TasadeRetencion
   * [03] Importe

* **VirtualXML_ImpLocal10AddTrasladosLocales** *(Usar antes SetImpuestosLocales10)*
   * [01] ImpLocTrasladado
   * [02] TasadeTraslado
   * [03] Importe

##### CFDI.Complemento.Donatarias11

* **VirtualXML_SetDonatarias11**
   * [01] noAutorizacion
   * [02] fechaAutorizacion
   * [03] leyenda

##### CFDI.Complemento.INE11

* **VirtualXML_SetINE11**
   * [01] TipoProceso
   * [02] TipoComite
   * [03] IdContabilidad
   * [04] ClaveEntidad
   * [05] Ambito
   * [06] EntidadContabilidadIdContabilidad

* **VirtualXML_INE11AddEntidad** *(Usar antes SetINE11)*
   * [01] ClaveEntidad
   * [02] Ambito
   * [03] IdContabilidad

* **VirtualXML_INE11AddEntidadContabilidad** *(Usar antes INE11AddEntidad)*
   * [01] IdContabilidad

##### CFDI.Complemento.Divisas10

* **VirtualXML_SetDivisas10**
   * [01] tipoOperacion 

##### CFDI.Complemento.Aerolineas10

* **VirtualXML_SetAerolineas10**
   * [01] TUA
   * [02] TotalCargos
   * [03] CodigoCargo
   * [04] Importe 

* **VirtualXML_Aerolineas10AddCargo** *(Usar antes SetAerolineas10)*
   * [01] CodigoCargo
   * [02] Importe 


##### CFDI.Complemento.NotariosPublicos10

* **VirtualXML_SetNotariosPublicos10**
   * [01] TipoInmueble
   * [02] Calle
   * [03] NoExterior
   * [04] NoInterior
   * [05] Colonia
   * [06] Localidad
   * [07] Referencia
   * [08] Municipio
   * [09] Estado
   * [10] Pais
   * [11] CodigoPostal
   * [12] NumInstrumentoNotarial
   * [13] FechaInstNotarial
   * [14] MontoOperacion
   * [15] Subtotal
   * [16] IVA
   * [17] CURP
   * [18] NumNotaria
   * [19] EntidadFederativa
   * [20] Adscripcion
   * [21] CoproSocConyugalEEnajenante
   * [22] CoproSocConyugalEAdquiriente 

* **VirtualXML_NotariosPublicos10AddDescInmueble** *(Usar antes SetNotariosPublicos10)*
   * [01] TipoInmueble
   * [02] Calle
   * [03] NoExterior
   * [04] NoInterior
   * [05] Colonia
   * [06] Localidad
   * [07] Referencia
   * [08] Municipio
   * [09] Estado
   * [10] Pais
   * [11] CodigoPostal 

* **VirtualXML_NotariosPublicos10AddDatosUnEnajenante** *(Usar antes SetNotariosPublicos10)*
   * [01] Nombre
   * [02] ApellidoPaterno
   * [03] ApellidoMaterno
   * [04] RFC
   * [05] CURP 

* **VirtualXML_NotariosPublicos10AddDatosEnajenanteCopSC** *(Usar antes SetNotariosPublicos10)*
   * [01] Nombre
   * [02] ApellidoPaterno
   * [03] ApellidoMaterno
   * [04] RFC
   * [05] CURP
   * [06] Porcentaje 

* **VirtualXML_NotariosPublicos10AddDatosUnAdquiriente** *(Usar antes SetNotariosPublicos10)*
   * [01] Nombre
   * [02] ApellidoPaterno
   * [03] ApellidoMaterno
   * [04] RFC
   * [05] CURP 

* **VirtualXML_NotariosPublicos10AddDatosAdquirienteCopSC** *(Usar antes SetNotariosPublicos10)*
   * [01] Nombre
   * [02] ApellidoPaterno
   * [03] ApellidoMaterno
   * [04] RFC
   * [05] CURP
   * [06] Porcentaje 

##### CFDI.Complemento.VehiculoRenovacionSustitucionVehiculo10

* **VirtualXML_SetRenovSustitVehiculos10**
   * [01] TipoDeDecreto

* **VirtualXML_RenovSustitVehiculos10AddRenovVehicular** *(Usar antes SetRenovSustitVehiculos10)*
   * [01] VehEnaj
   * [02] UsadoPrecioVehUsado
   * [03] UsadoTipoVeh
   * [04] UsadoMarca
   * [05] UsadoTipooClase
   * [06] UsadoAño
   * [07] UsadoModelo
   * [08] UsadoNIV
   * [09] UsadoNumSerie
   * [10] UsadoNumPlacas
   * [11] UsadoNumMotor
   * [12] UsadoNumFolTarjCir
   * [13] UsadoNumPedIm
   * [14] UsadoAduana
   * [15] UsadoFechaRegulVeh
   * [16] UsadoFoliofiscal
   * [17] NuevoAño
   * [18] NuevoModelo
   * [19] NuevoNumPlacas
   * [20] NuevoRFC

* **VirtualXML_RenovSustitVehiculos10AddRenovVehicularVehiculoUsado** *(Usar antes RenovSustitVehiculos10AddRenovVehicular)*
   * [01] UsadoPrecioVehUsado
   * [02] UsadoTipoVeh
   * [03] UsadoMarca
   * [04] UsadoTipooClase
   * [05] UsadoAño
   * [06] UsadoModelo
   * [07] UsadoNIV
   * [08] UsadoNumSerie
   * [09] UsadoNumPlacas
   * [10] UsadoNumMotor
   * [11] UsadoNumFolTarjCir
   * [12] UsadoNumPedIm
   * [13] UsadoAduana
   * [14] UsadoFechaRegulVeh
   * [15] UsadoFoliofiscal

* **VirtualXML_RenovSustitVehiculos10AddSustitVehicular** *(Usar antes SetRenovSustitVehiculos10)*
   * [01] VehEnaj
   * [02] UsadoPrecioVehUsado
   * [03] UsadoTipoVeh
   * [04] UsadoMarca
   * [05] UsadoTipooClase
   * [06] UsadoAño
   * [07] UsadoModelo
   * [08] UsadoNIV
   * [09] UsadoNumSerie
   * [10] UsadoNumPlacas
   * [11] UsadoNumMotor
   * [12] UsadoNumFolTarjCir
   * [13] UsadoNumFolAvisoint
   * [14] UsadoNumPedIm
   * [15] UsadoAduana
   * [16] UsadoFechaRegulVeh
   * [17] UsadoFoliofiscal
   * [18] NuevoAño
   * [19] NuevoModelo
   * [20] NuevoNumPlacas
   * [21] NuevoRFC

##### CFDI.Complemento.LeyendasFiscales10

* **VirtualXML_SetLeyendasFiscales10Full**
   * [01] A_disposicionFiscal01
   * [02] A_norma01
   * [03] A_textoLeyenda01
   * [04] A_disposicionFiscal02
   * [05] A_norma02
   * [06] A_textoLeyenda02
   * [07] A_disposicionFiscal03
   * [08] A_norma03
   * [09] A_textoLeyenda03
   * [10] A_disposicionFiscal04
   * [11] A_norma04
   * [12] A_textoLeyenda04
   * [13] A_disposicionFiscal05
   * [14] A_norma05
   * [15] A_textoLeyenda05
   * [16] A_disposicionFiscal06
   * [17] A_norma06
   * [18] A_textoLeyenda06
   * [19] A_disposicionFiscal07
   * [20] A_norma07
   * [21] A_textoLeyenda07
   * [22] A_disposicionFiscal08
   * [23] A_norma08
   * [24] A_textoLeyenda08
   * [25] A_disposicionFiscal09
   * [26] A_norma09
   * [27] A_textoLeyenda09
   * [28] A_disposicionFiscal10
   * [29] A_norma10
   * [30] A_textoLeyenda10

##### CFDI.Complemento.VehiculoUsado10

* **VirtualXML_SetVehiculoUsado10**
   * [01] montoAdquisicion
   * [02] montoEnajenacion
   * [03] claveVehicular
   * [04] marca
   * [05] tipo
   * [06] modelo
   * [07] numeroMotor
   * [08] numeroSerie
   * [09] NIV
   * [10] valor
   * [11] numero
   * [12] fecha
   * [13] aduana 

* **VirtualXML_VehiculoUsado10AddInformacionAduanera** *(Usar antes SetVehiculoUsado10)*
   * [01] numero
   * [02] fecha
   * [03] aduana 

##### CFDI.Complemento.ServicioParcial10

* **VirtualXML_SetServicioParcial10**
   * [01] NumPerLicoAut
   * [02] Calle
   * [03] NoExterior
   * [04] NoInterior
   * [05] Colonia
   * [06] Localidad
   * [07] Referencia
   * [08] Municipio
   * [09] Estado
   * [10] CodigoPostal 

##### CFDI.Complemento.SPEI10

* **VirtualXML_Spei10AddSpeiTercero**
   * [01] FechaOperacion
   * [02] Hora
   * [03] ClaveSPEI
   * [04] sello
   * [05] numeroCertificado
   * [06] cadenaCDA
   * [07] Concepto
   * [08] IVA
   * [09] MontoPago
   * [10] BancoReceptor
   * [11] NombreReceptor
   * [12] TipoCuentaReceptor
   * [13] CuentaReceptor
   * [14] RFCReceptor
   * [15] BancoEmisor
   * [16] NombreEmisor
   * [17] TipoCuentaEmisor
   * [18] CuentaEmisor
   * [19] RFCEmisor 

##### CFDI.Complemento.EstadoCuentaCombustible12

* **VirtualXML_SetEstadoDeCuentaCombustible12**
   * [01] (NumeroDeCuenta
   * [02] SubTotal
   * [03] Total

* **VirtualXML_EstadoDeCuentaCombustible12AddConcepto** *(Usar antes SetEstadoDeCuentaCombustible12)*
   * [01] Identificador
   * [02] Fecha
   * [03] Rfc
   * [04] ClaveEstacion
   * [05] Cantidad
   * [06] TipoCombustible
   * [07] Unidad
   * [08] NombreCombustible
   * [09] FolioOperacion
   * [10] ValorUnitario
   * [11] Importe

* **VirtualXML_EstadoDeCuentaCombustible12AddConceptoTraslado** *(Usar antes EstadoDeCuentaCombustible12AddConcepto)*
   * [01] Impuesto
   * [02] TasaOCuota
   * [03] Importe

##### CFDI.Complemento.ConsumoDeCombustibles11

* **VirtualXML_SetConsumoDeCombustibles11**
   * [01] numeroDeCuenta
   * [02] subTotal
   * [03] total

* **VirtualXML_ConsumoDeCombustibles11AddConcepto** *(Usar antes SetConsumoDeCombustibles11)*
   * [01] identificador
   * [02] fecha
   * [03] rfc
   * [04] claveEstacion
   * [05] tipoCombustible
   * [06] cantidad
   * [07] nombreCombustible
   * [08] folioOperacion
   * [09] valorUnitario
   * [10] importe

* **VirtualXML_ConsumoDeCombustibles11AddConceptoDeterminado** *(Usar antes ConsumoDeCombustibles11AddConcepto)*
   * [01] impuesto
   * [02] tasaOCuota
   * [03] importe

##### CFDI.Complemento.PagoEnEspecie10

* **VirtualXML_SetPagoEnEspecie10**
   * [01] CvePIC
   * [02] FolioSolDon
   * [03] PzaArtNombre
   * [04] PzaArtTecn
   * [05] PzaArtAProd
   * [06] PzaArtDim 

##### CFDI.Complemento.PFIntegranteCoordinado10

* **VirtualXML_SetPFintegranteCoordinado10**
   * [01] ClaveVehicular
   * [02] Placa
   * [03] RFCPF 

##### CFDI.Complemento.TuristaPasajeroExtranjero10

* **VirtualXML_SetTuristaPasajeroExtranjero10**
   * [01] fechadeTransito
   * [02] tipoTransito
   * [03] Via
   * [04] TipoId
   * [05] NumeroId
   * [06] Nacionalidad
   * [07] EmpresaTransporte
   * [08] IdTransporte 

##### CFDI.Complemento.ValesDeDespensa10

* **VirtualXML_SetValesDeDespensa10**
   * [01] registroPatronal
   * [02] numeroDeCuenta
   * [03] total
   * [04] identificador
   * [05] fecha
   * [06] rfc
   * [07] curp
   * [08] nombre
   * [09] numSeguridadSocial
   * [10] importe 

* **VirtualXML_ValesDeDespensa10AddConcepto** *(Usar antes SetValesDeDespensa10)*
   * [01] identificador
   * [02] fecha
   * [03] rfc
   * [04] curp
   * [05] nombre
   * [06] numSeguridadSocial
   * [07] importe 



##### CFDI.Complemento.Detallista10

* **VirtualXML_SetDetallista10**
   * [01] A_documentStatus
   * [02] E_requestForPaymentIdentification_entityType
   * [03] E_orderIdentification_referenceIdentification
   * [04] E_orderIdentification_ReferenceDate
   * [05] A_AdditionalInformationReferenceIdentification_type
   * [06] E_AdditionalInformationReferenceIdentification_referenceIdentification
   * [07] E_buyer_gln
   * [08] E_buyerContactInformationPersonOrDepartmentName_text
   * [09] E_seller_gln
   * [10] A_seller_alternatePartyIdentificationType
   * [11] E_seller_alternatePartyIdentification
   * [12] E_shipTo_gln
   * [13] E_shipTo_nameAndAddressName
   * [14] E_shipTo_nameAndAddressStreetAddressOne
   * [15] E_shipTo_nameAndAddressCity
   * [16] E_shipTo_nameAndAddressPostalCode
   * [17] E_InvoiceCreator_gln
   * [18] A_InvoiceCreator_alternatePartyIdentificationType
   * [19] E_InvoiceCreator_alternatePartyIdentification
   * [20] E_InvoiceCreator_nameAndAddressName
   * [21] E_InvoiceCreator_nameAndAddressStreetAddressOne
   * [22] E_InvoiceCreator_nameAndAddressCity
   * [23] E_InvoiceCreator_nameAndAddressPostalCode
   * [24] A_paymentTerms_paymentTermsEvent
   * [25] A_paymentTerms_PaymentTermsRelationTime
   * [26] A_paymentTerms_netPaymentNetPaymentTermsType
   * [27] A_paymentTerms_netPaymentTimePeriod
   * [28] E_paymentTerms_netPaymentValue
   * [29] A_paymentTerms_discountPaymentDiscountType
   * [30] E_paymentTerms_discountPaymentPercentage
   * [31] E_totalAmount_Amount

* **VirtualXML_Detallista10AddOrderIdentificationReferenceIdentification** *(Usar antes SetDetallista10)*
   * [01] E_orderIdentification_referenceIdentification

* **VirtualXML_Detallista10AddAdditionalInformationReferenceIdentification** *(Usar antes SetDetallista10)*
   * [01] A_AdditionalInformationReferenceIdentification_type
   * [02] E_AdditionalInformationReferenceIdentification_referenceIdentification

* **VirtualXML_Detallista10AddSpecialInstruction** *(Usar antes SetDetallista10)*
   * [01] A_code
   * [02] E_text01
   * [03] E_text02
   * [04] E_text03
   * [05] E_text04
   * [06] E_text05
   * [07] E_text06
   * [08] E_text07
   * [09] E_text08
   * [10] E_text09
   * [11] E_text10
   * [12] E_text11
   * [13] E_text12
   * [14] E_text13
   * [15] E_text14
   * [16] E_text15

* **VirtualXML_Detallista10AddDeliveryNote** *(Usar antes SetDetallista10)*
   * [01] E_ReferenceDate
   * [02] E_referenceIdentification01
   * [03] E_referenceIdentification02
   * [04] E_referenceIdentification03
   * [05] E_referenceIdentification04
   * [06] E_referenceIdentification05
   * [07] E_referenceIdentification06
   * [08] E_referenceIdentification07
   * [09] E_referenceIdentification08
   * [10] E_referenceIdentification09
   * [11] E_referenceIdentification10
   * [12] E_referenceIdentification11
   * [13] E_referenceIdentification12
   * [14] E_referenceIdentification13
   * [15] E_referenceIdentification14
   * [16] E_referenceIdentification15
   * [17] E_referenceIdentification16
   * [18] E_referenceIdentification17
   * [19] E_referenceIdentification18
   * [20] E_referenceIdentification19
   * [21] E_referenceIdentification20

* **VirtualXML_Detallista10AddCustoms** *(Usar antes SetDetallista10)*
   * [01] E_gln

* **VirtualXML_Detallista10AddCurrency** *(Usar antes SetDetallista10)*
   * [01] A_currencyISOCode
   * [02] E_currencyFunction01
   * [03] E_currencyFunction02
   * [04] E_currencyFunction03
   * [05] E_rateOfChange

* **VirtualXML_Detallista10AddShipmentDetail** *(Usar antes SetDetallista10)*
   * [01] E_shipmentDetail

* **VirtualXML_Detallista10AddAllowanceCharge** *(Usar antes SetDetallista10)*
   * [01] A_allowanceChargeType
   * [02] A_settlementType
   * [03] A_sequenceNumber
   * [04] E_specialServicesType
   * [05] A_monetaryAmountOrPercentage_base
   * [06] E_monetaryAmountOrPercentage_percentage

* **VirtualXML_Detallista10AddTotalAllowanceCharge** *(Usar antes SetDetallista10)*
   * [01] A_allowanceOrChargeType
   * [02] E_specialServicesType
   * [03] E_Amount

* **VirtualXML_Detallista10AddLineItem** *(Usar antes SetDetallista10)*
   * [01] A_type
   * [02] A_number
   * [03] E_tradeItemIdentification_gtin
   * [04] A_tradeItemDescriptionInformation_language
   * [05] E_tradeItemDescriptionInformation_longText
   * [06] A_invoicedQuantity_unitOfMeasure
   * [07] E_invoicedQuantity_invoicedQuantity
   * [08] E_grossPrice_Amount
   * [09] E_netPrice_Amount
   * [10] A_AdditionalInformation_type
   * [11] E_AdditionalInformation_referenceIdentification
   * [12] A_LogisticUnits_type
   * [13] E_LogisticUnits_serialShippingContainerCode
   * [14] E_palletInformation_palletQuantity
   * [15] A_palletInformation_type
   * [16] E_palletInformation_description
   * [17] E_palletInformation_methodOfPayment
   * [18] E_totalLineAmount_grossAmount
   * [19] E_totalLineAmount_netAmount

* **VirtualXML_Detallista10AddLineItemAlternateTradeItemIdentification** *(Usar antes Detallista10AddLineItem)*
   * [01] A_type
   * [02] E_alternateTradeItemIdentification

* **VirtualXML_Detallista10AddLineItemAditionalQuantity** *(Usar antes Detallista10AddLineItem)*
   * [01] A_QuantityType
   * [02] E_aditionalQuantity

* **VirtualXML_Detallista10AddLineItemCustoms** *(Usar antes Detallista10AddLineItem)*
   * [01] E_gln
   * [02] A_alternatePartyIdentification_type
   * [03] E_alternatePartyIdentification
   * [04] E_ReferenceDate
   * [05] E_nameAndAddress_name

* **VirtualXML_Detallista10AddLineItemExtendedAttributes** *(Usar antes Detallista10AddLineItem)*
   * [01] A_productionDate
   * [02] E_lotNumber

* **VirtualXML_Detallista10AddLineItemAllowanceCharge** *(Usar antes Detallista10AddLineItem)*
   * [01] A_allowanceChargeType
   * [02] A_settlementType
   * [03] A_sequenceNumber
   * [04] E_specialServicesType
   * [05] E_percentagePerUnit
   * [06] E_amountPerUnit

* **VirtualXML_Detallista10AddLineItemTradeItemTaxInformation** *(Usar antes Detallista10AddLineItem)*
   * [01] E_taxTypeDescription
   * [02] E_referenceNumber
   * [03] E_taxPercentage
   * [04] E_taxAmount
   * [05] E_taxCategory


##### CFDI.Especiales

* **VirtualXML_AddComplemento**
   * [01] fragmentoXML *(Debe ser válido e incluir los namespaces que pudiera utilizar)*

* **VirtualXML_AddComplementoConcepto**
   * [01] fragmentoXML *(Debe ser válido e incluir los namespaces que pudiera utilizar)*

* **VirtualXML_AddNameSpace** *Agrega un namespace al nodo principal XML del CFDI.*
   * [01] Namespace
   * [02] url
   * [03] schemalocation

### Ejemplos

##### Solicitud de Cancelación

```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6

  vxml.cancelaCFDI2022("demo_nodejs",                          // usuario VirtualPAC
                   "EKU9003173C9",                             // rfcemisor
                   "163feb31-9c01-40f0-b85b-ebe1c771da1f",     // UUID
                   "02",                                       // Motivo
                   "",                                         // folioSustitucion
                   "./test/CSD_EKU9003173C9.cer",              // CER
                   "./test/CSD_EKU9003173C9.key",              // KEY
                   "12345678a",                                // usuario PWD
                   "./test/out/",                              // ruta para guardar acuse generado
                   "prefijo",                                  // prefijo de archivo para acuse generado
                   "cancelacion")                              // sufijo de archivo para acuse generado
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### CFDI40 Sin Complemento

  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'A', '1', FechaCFDI, '99', 'Contado Comercial', '1000.00', '50.00', 'MXN', '', '1102.00', 'I', 'PPD', '53050', '', '01');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionados_cfdi40', '04', 'FF93C8BE-AF7B-4FC5-8854-6DAE18CFB5B4', 'D8E18C2F-2859-4927-A0F0-EA3E93642DDC', '', '', '', '', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionado_cfdi40', 'BE1D4B47-E167-47A3-8049-70D4D43BCBE8');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionados_cfdi40', '01', 'FDBA380A-9732-4FB5-A6CB-5FB4BD831697', '', '', '', '', '', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE SA DE CV', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'CTE940531F58', 'CIBERNETICA Y TECNOLOGIA SA DE CV', '', '', 'G01', '53050', '601');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', 'SEFXXX', '1', 'H87', 'Unidad', 'Paquete X - ObjetoImp2', '500.00', '500.00', '', '02');
  vxml.addFunctionCall('VirtualXML_AddConceptoTraslado_cfdi40', '500.00', '002', 'Tasa', '0.160000', '80.00');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', 'SEFXXX', '2', 'H87', 'Unidad', 'Paquete X - ObjetoImp2', '250.00', '500.00', '50.00', '02');
  vxml.addFunctionCall('VirtualXML_AddConceptoTraslado_cfdi40', '450.00', '002', 'Tasa', '0.160000', '72.00');
  vxml.addFunctionCall('VirtualXML_SetImpuestosInfo_cfdi40', '152.00', '');
  vxml.addFunctionCall('VirtualXML_AddTraslado_cfdi40', '002', 'Tasa', '0.160000', '152.00', '950.00');
  vxml.addFunctionCall('VirtualXML_SetAddenda', '<MyOwnNode name="CFDI40"><AnyChildNode data="BASICO" /></MyOwnNode>');

  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_Basico_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### CFDI40 CartaPorte20

  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40','RogueOne','HNFK231',FechaCFDI,'01','','25000.00','','MXN','1','28000.00','I','PUE','06300','','01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40','EKU9003173C9','ESCUELA KEMPER URGATE SA DE CV','601','');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40','CTE940531F58','CIBERNETICA Y TECNOLOGIA SA DE CV','','','G03','53050','601');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40','78101500','01','1','E48','SERVICIO','FLETE','25000.00','25000.00','','02');
  vxml.addFunctionCall('VirtualXML_AddConceptoRetencion_cfdi40','25000.00','002','Tasa','0.040000','1000.00');
  vxml.addFunctionCall('VirtualXML_AddConceptoTraslado_cfdi40','25000.00','002','Tasa','0.160000','4000.00');
  vxml.addFunctionCall('VirtualXML_SetImpuestosInfo_cfdi40','4000.00','1000.00');
  vxml.addFunctionCall('VirtualXML_AddRetencion_cfdi40','002','1000.00');
  vxml.addFunctionCall('VirtualXML_AddTraslado_cfdi40','002','Tasa','0.160000','4000.00','25000.00');
  vxml.addFunctionCall('VirtualXML_SetCartaPorte20','No','','','','2');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddUbicacion','Origen','OR101010','EKU9003173C9','','','','','','','2021-11-01T00:00:00','','','calle','211','','0347','23','casa blanca 1','004','COA','MEX','25350');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddUbicacion','Destino','DE202020','EKU9003173C9','','','','','','','2021-11-01T01:00:00','','1','calle','214','','0347','23','casa blanca 2','004','COA','MEX','25350');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddUbicacion','Destino','DE202021','EKU9003173C9','','','','','','','2021-11-01T02:00:00','','1','calle','220','','0347','23','casa blanca 3','004','COA','MEX','25350');
  vxml.addFunctionCall('VirtualXML_CartaPorte20SetMercancias','2.0','XBX','','2','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddMercancia','11121900','','Productos de perfumería','1.0','XBX','','','Sí','1266','4H2','','1.0','','','','','','','','','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddMercanciaCantidadTransporta','1','OR101010','DE202020','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddMercancia','11121900','','Productos de perfumería','1.0','XBX','','','Sí','1266','4H2','','1.0','','','','','','','','','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddMercanciaCantidadTransporta','1','OR101010','DE202021','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20SetMercanciasAutotransporte','TPAF01','NumPermisoSCT','VL','plac892','2020','SW Seguros','123456789','SW Seguros Ambientales','123456789','SW Seguros','','','CTR003','PAX1234','','');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddFiguraTransporteTiposFigura','01','VAAM130719H60','a234567890','','','','','calle','423','','0347','23','casa azul 1','004','COA','MEX','25350');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddFiguraTransporteTiposFigura','02','VAAM130719H60','','','','','PT01','calle','523','','0347','23','casa azul 2','004','COA','MEX','25350');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddFiguraTransporteTiposFiguraPartesTransporte','PT02');
  vxml.addFunctionCall('VirtualXML_CartaPorte20AddFiguraTransporteTiposFigura','04','VAAM130719H60','','','','','','calle','623','','0347','23','casa azul 3','004','COA','MEX','25350');        
  vxml.addFunctionCall('VirtualXML_SetAddenda', '<MyOwnNode name="CFDI40"><AnyChildNode data="CartaPorte20" /></MyOwnNode>');

  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_Pagos20_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```
  
##### CFDI40 Pagos20

  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionados_cfdi40', '01', '', '00000000-0000-0000-0000-000000000002', '', '00000000-0000-0000-0000-000000000004', '', '00000000-0000-0000-0000-000000000006', '', '00000000-0000-0000-0000-000000000008', '', '00000000-0000-0000-0000-000000000010');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionado_cfdi40', '00000000-0000-0000-0000-111111111111');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionados_cfdi40', '02', '00000000-0000-0000-0000-000000000001', '', '00000000-0000-0000-0000-000000000003', '', '00000000-0000-0000-0000-000000000005', '', '00000000-0000-0000-0000-000000000007', '', '00000000-0000-0000-0000-000000000009', '');
  vxml.addFunctionCall('VirtualXML_AddCfdiRelacionado_cfdi40', '00000000-0000-0000-0000-222222222222');
  vxml.addFunctionCall('VirtualXML_SetInformacionGlobal_cfdi40', '01', '10', '2021');
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', '', '12629', FechaCFDI, '', '', '0', '', 'XXX', '', '0', 'P', '', '53000', '', '01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE SA DE CV', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'CTE940531F58', 'CIBERNETICA Y TECNOLOGIA SA DE CV', '', '', 'P01', '53050', '601');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111506', '', '1', 'ACT', '', 'Pago', '0', '0', '', '01');
  vxml.addFunctionCall('VirtualXML_SetPagos20', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '34925.52');
  vxml.addFunctionCall('VirtualXML_Pagos20AddPago', '2021-01-01T01:01:01', '03', 'USD', '1.00', '13144.66', '0000842', '', '', '', '', '', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_Pagos20AddPagoDoctoRelacionado', '88888888-4444-4444-4444-121212121212', 'Serie', 'Folio', 'USD', '1', '2', '13144.66', '13144.66', '0.00', '01');
  vxml.addFunctionCall('VirtualXML_Pagos20AddPago', '2021-02-02T02:02:02', '03', 'USD', '1.00', '21780.86', '0000842', '', '', '', '', '', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_Pagos20AddPagoDoctoRelacionado', '333-22-999999999', 'Serie2', 'Folio2', 'USD', '1', '3', '14430.86', '14430.86', '0.00', '01');
  vxml.addFunctionCall('VirtualXML_Pagos20AddPagoDoctoRelacionado', 'AAAAAAAA-BBBB-CCCC-DDDD-666666666666', 'Serie3', 'Folio3', 'USD', '1', '4', '7350.00', '7350.00', '0.00', '03');         
  vxml.addFunctionCall('VirtualXML_SetAddenda', '<MyOwnNode name="CFDI40"><AnyChildNode data="Pagos20" /></MyOwnNode>');

  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_Pagos20_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```


##### CFDI40 Nomina12
  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'N', '1', FechaCFDI, '99', '', '5000.00', '123.90', 'MXN', '', '4876.10', 'N', 'PUE', '53050', '', '01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'AEKU9003173C9', 'NombreDelReceptorPersonaFisica', '', '', 'CN01', '52955', '605');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '84111505', '', '1', 'ACT', '', 'Pago de nómina', '5000.00', '5000.00', '123.90', '01');
  vxml.addFunctionCall('VirtualXML_SetNomina12', 'O', '2016-10-31', '2016-10-16', '2016-10-31', '15', '5000.00', '123.90', '');
  vxml.addFunctionCall('VirtualXML_Nomina12SetEmisor', '', 'B5510768108', '', '', '');
  vxml.addFunctionCall('VirtualXML_Nomina12SetReceptor', 'FOLR670417HDFLPN00', '04078873454', '2016-06-01', 'P21W', '01', 'No', '01', '02', '060', 'Sistemas', 'Director', '2', '04', '021', '', '435.50', '435.50', 'JAL');
  vxml.addFunctionCall('VirtualXML_Nomina12SetPercepciones', '5000.00', '', '', '5000.00', '0.00');
  vxml.addFunctionCall('VirtualXML_Nomina12AddPercepcion', '001', '001', 'Sueldos, Salarios Rayas y Jornales', '5000.00', '0.00', '', '', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_Nomina12SetDeducciones', '123.90', '');
  vxml.addFunctionCall('VirtualXML_Nomina12AddDeduccion', '005', '201', 'ISR SALARIOS', '81.00');
  vxml.addFunctionCall('VirtualXML_Nomina12AddDeduccion', '001', '202', 'IMSS', '42.90');

  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_Nomina12_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### CFDI40 ComercioExterior20 (Traslado)
  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10

  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'CE', '1', FechaCFDI, '', '', '0.00', '', 'MXN', '', '0', 'T', '', '42501', '', '01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '', '', 'S01', '42501', '601');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101602', 'A-123LFM', '1', 'DPC', 'Pieza', 'Bombilla 150W', '1000.00', '1000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101600', 'A-123JKL', '1', 'DPC', 'Servicio', 'Bombilla 100W', '2000.00', '2000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101600', 'A-123WHX', '1', 'DPC', 'Servicio', 'Bombilla 75W', '2000.00', '2000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_SetComercioExterior20', '02', 'A1', '0', '', '', 'FOB', '', '17.2957', '400.00');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercancia', 'A-123LFM', '0101299999', '32', '06', '2.50', '80.00', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercancia', 'A-123JKL', '0101299999', '100', '06', '1.60', '160.00', '', '', '', '');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercanciaDescripcionesEspecificas', 'Sony', 'CD Ray', 'Sax', '478382');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercanciaDescripcionesEspecificas', 'Sony', 'PlaystationRay', 'Loc', '023982');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercancia', 'A-123WHX', '0101299999', '20', '06', '8.00', '160.00', 'Samsung', 'Grand Prime', 'Mid', '394821');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercanciaDescripcionesEspecificas', 'Panasonic', 'TV LCD', 'Noc', '958372');
  vxml.addFunctionCall('VirtualXML_CCE20AddMercanciaDescripcionesEspecificas', 'Steeler', 'PC', 'Uta', '847657');
  vxml.addFunctionCall('VirtualXML_CCE20SetReceptor', '', 'Avenue Sahara', '74', '', 'BIG DESERT', '', '', '', 'NV', 'USA', '89316');
  vxml.addFunctionCall('VirtualXML_CCE20SetEmisor', '', 'Hidalgo', '1000', '', '0716', '03', '', '021', 'NLE', 'MEX', '66050');
  vxml.addFunctionCall('VirtualXML_CCE20AddDestinatario', '', '', 'Arquimides', '', '', '', '', '', '', 'YUC', 'ESP', '37284');
  vxml.addFunctionCall('VirtualXML_CCE20AddDestinatarioDomicilio', 'Arquimides', '', '', '', '', '', '', 'OAX', 'ESP', '68020');


  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_ComercioExterior20_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### CFDI33 InstitucionesEdicativas10
  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'IEDU', '1', FechaCFDI, '01', 'CondiciónDePago', '5000.00', '', 'MXN', '', '5000.00', 'I', 'PUE', '68025', '', '01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'VEME800513DU2', 'NombreDelReceptorRazónSocial', '', '', 'G03', '62621', '612');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '86121503', 'PCOLMDAN', '1', 'ZZ', '', 'Colegiatura Anual Secundaria', '4000.00', '4000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConceptoComplementoIedu10', 'NOMBRE ALUMNO1', 'AUPA901028HDFRLXA9', 'Secundaria', '0737', '');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '86121503', 'COL_BS', '1', 'E48', '', 'Colegiatura MAR 2024', '1000.00', '1000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConceptoComplementoIedu10', 'NOMBRE ALUMNO2', 'TAZR030610HCSNBDA2', 'Primaria', '07TPR0004R', '');


  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_iedu10_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### CFDI40 Especiales (AddComplemento)

  ```javascript
  const VirtualXML = require('virtualxml-cfdi');
  let vxml = new VirtualXML();
  let ts = Date.now() - (new Date().getTimezoneOffset()) * 60000; // GMT-6
  let FechaCFDI = (new Date(ts)).toISOString().substring(0, 19); // Fecha formato 2018-03-29T14:22:10
  vxml.addFunctionCall('VirtualXML_SetComprobanteInfo_cfdi40', 'CCE20', '1', FechaCFDI, '', '', '0.00', '', 'MXN', '', '0', 'T', '', '42501', '', '01');
  vxml.addFunctionCall('VirtualXML_SetEmisorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '601', '');
  vxml.addFunctionCall('VirtualXML_SetReceptorInfo_cfdi40', 'EKU9003173C9', 'ESCUELA KEMPER URGATE', '', '', 'S01', '42501', '601');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101602', 'A-123LFM', '1', 'DPC', 'Pieza', 'Bombilla 150W', '1000.00', '1000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101600', 'A-123JKL', '1', 'DPC', 'Servicio', 'Bombilla 100W', '2000.00', '2000.00', '', '01');
  vxml.addFunctionCall('VirtualXML_AddConcepto_cfdi40', '39101600', 'A-123WHX', '1', 'DPC', 'Servicio', 'Bombilla 75W', '2000.00', '2000.00', '', '01');

  // El fragmentoXML debera contiener la definicion de los namespaces en caso de usarlos
  // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  // xmlns:cce20="http://www.sat.gob.mx/ComercioExterior20" 
  // xsi:schemaLocation="http://www.sat.gob.mx/ComercioExterior20 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd"
  vxml.addFunctionCall('VirtualXML_AddComplemento', '<cce20:ComercioExterior xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cce20="http://www.sat.gob.mx/ComercioExterior20" xsi:schemaLocation="http://www.sat.gob.mx/ComercioExterior20 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd" Version="2.0" MotivoTraslado="02" ClaveDePedimento="A1" CertificadoOrigen="0" Incoterm="FOB" TipoCambioUSD="17.2957" TotalUSD="400.00"><cce20:Emisor>...</cce20:Emisor><cce20:Receptor>...</cce20:Receptor><cce20:Destinatario>...</cce20:Destinatario><cce20:Mercancias>...</cce20:Mercancias></cce20:ComercioExterior>');

  vxml.emiteCFDI40("demo_nodejs",
                   "EKU9003173C9",
                   "./test/CSD_EKU9003173C9.cer",
                   "./test/CSD_EKU9003173C9.key",
                   "12345678a",
                   "./test/out/",
                   "CFDI40_Complemento_" + (new Date(ts)).toISOString().substring(0, 10),
                   "nodejs", true, true, true, true)
      .then((response) => {
        // Handle Response
      }).catch((err) => {
        // Handle Error
      });
  ```

##### Changelog

1.4.0
* Se agrega soporte para Complemento **Carta Porte 3.0**.
* Se agrega soporte para Complemento **Comercio Exterior 2.0**.
* Se retira soporte para **CFDI 3.3** (fuera de vigencia).
* Se retira la funcion **emitecfdi33** para emision de CFDI33 (fuera de vigencia).
* Se retira soporte para Complemento Concepto **Terceros 1.1** (fuera de vigencia).
* Se retira soporte para Complemento **Pagos 1.0** (fuera de vigencia).
* Se retira soporte para Complemento **Carta Porte 2.0** (fuera de vigencia).
* Se retira soporte para Complemento **Comercio Exterior 1.1** (fuera de vigencia).

1.3.0
* Se agregan funciones para administrar emisores **(adminEmisorAdd, adminEmisorUpd)**, distribuidores **(adminUsuarioAdd, adminUsuarioUpd)** y timbres **(adminEmisorAsigna, adminEmisorAutoasignacion, adinUsuarioAsigna)**.

1.2.3, 1.2.2, 1.2.1 
* Correccion de errores en **documentacion**

1.2.0
* Se agrega soporte para **CFDI 4.0** 
* Se agrega soporte para **Cancelaciones 2022** 
* Se agrega soporte para Complemento **Pagos 2.0**
* Cambia nombre de funcion de VirtualXML_SetAddenda_cfdi33 a **VirtualXML_SetAddenda**
* Cambia nombre de funcion de VirtualXML_SetAddendaText_cfdi33 a **VirtualXML_SetAddendaText**
* Cambia nombre de funcion para Complemento **iedu 1.0** de VirtualXML_AddConceptoComplementoIedu_cfdi33 a **VirtualXML_AddConceptoComplementoIedu10**
* Cambia nombre de funcion especial para Complementos de VirtualXML_AddComplemento_cfdi33 a **VirtualXML_AddComplemento**
* Cambia nombre de funcion especial para ComplementosConcepto de VirtualXML_AddComplementoConcepto_cfdi33 a **VirtualXML_AddComplementoConcepto**

1.1.0
* Se agrega soporte para Complemento **CartaPorte 2.0** 
* Uso de CSD/KEY EKU9003173C9 para pruebas 

1.0.9
* Se incluye la **cadena original del SAT (cadenasat)** a la respuesta exitosa de timbrado 
* Se incrementa el tiempo de espera para la generacion de sello (util para CFDI con varios cientos de conceptos)

1.0.8
* Implementacion de **cancelaCFDI33 (Solicitud de Cancelación)** 

1.0.7
* Solucionado problema de lectura de datos CER/KEY en formato Base64 para sistemas Linux. Mientras la longitud del valor de los parametros sea menor a 256 y el archivo exista, se leera de la ruta indicada; en caso contrario se tratara como informacion en Base64

1.0.6
* Actualizacion de dependencia al paquete isomorphic-fetch a 3.0.0

1.0.5
* Uso de message en respuestas en lugar de msg
* Seccion DEMO descargable en documentacion

1.0.4
* Funcion emiteCFDI acepta contenido de archivos .CER/.KEY en formato **base64**, 

1.0.3
* Modificacion al formato de documentacion (&lt;br/&gt;) de acuerdo a **NPM**, 

1.0.2
* Modificacion a documentacion que incluye **funciones EstadoDeCuentaCombustible12**, **funciones ConsumoDeCombustibles11** 
* Modificacion a documentacion incluyendo explicitamente **informacion para DEMO**, **informacion de contacto**
* Modificacion a documentacion **completando los ejemplos**
* **Test ComercioExterior11** removido.

1.0.1
* Modificacion a documentacion para utilizar version Markdown usada por **NPM**