Solución a problemas con la nueva Resolución General ARCA N° 5.616/2024:

Crear Factura Electrónica de ARCA en n8n

Con workflow para importar directamente en tu proyecto.


Crear Factura Electrónica de ARCA en n8n

Si es tu primera vez conectándote con la facturación electrónica de ARCA, te recomiendo leer esta guía básica sobre su funcionamiento general.

Conectar tu sistema con la facturación electrónica de ARCA

Conectar tu sistema con la facturación electrónica de ARCA

Guía paso a paso

A continuación te presento una guía completa para integrar la API de Afip SDK con n8n. Esta guía está pensada para que comprendas el funcionamiento de cada nodo, cómo se comunica la información entre ellos y de qué manera se automatiza el proceso completo de generar una factura electrónica, incluyendo la obtención del último número de comprobante, la generación del código QR, la construcción del HTML y la creación y descarga del PDF.

Workflow en n8n

Les dejo el create-bill-sample.json para que puedan importar rápidamente este workflow en su proyecto antes de comenzar.


Para usar los web services de ARCA, se requiere un certificado digital, con Afip SDK puedes integrarte en modo desarrollo usando el CUIT 20409378472 sin necesidad de obtener un certificado, para poder integrarte lo más rápido posible.

Te dejo este enlace por si luego quieres usar tu propio certificado para desarrollo.


Índice

  1. Introducción
  2. Estructura del Workflow en n8n
  3. Paso a Paso de la Implementación
  4. Problemas comunes
  5. Conclusiones y Consideraciones Finales

Introducción

La integración de la API de Afip SDK en plataformas de automatización como n8n permite agilizar y automatizar procesos de facturación electrónica. En este ejemplo, se crea un workflow que, al activarse manualmente, realiza las siguientes acciones:

  • Autentica al usuario y obtiene los tokens necesarios.
  • Consulta el último número de comprobante autorizado para calcular el siguiente número a utilizar.
  • Solicita la creación del comprobante mediante la API de Afip.
  • Genera un código QR con la información necesaria, formateándolo en base64 y linkeándolo a la URL oficial de consulta.
  • Construye el documento HTML de la factura, incorporando datos dinámicos (por ejemplo: número de comprobante, CAE, fecha de vencimiento, etc.) y la imagen del QR.
  • Llama a la API para convertir dicho HTML a PDF.
  • Descarga el PDF resultante.

Estructura del Workflow en n8n

El workflow se compone de los siguientes nodos conectados en cadena:

  1. Manual Trigger: Punto de inicio para ejecutar el flujo.
  2. get_authorization: Realiza una petición POST para obtener el token de autorización.
  3. get_last_voucher_number: Consulta el último comprobante autorizado.
  4. create_voucher: Envía la solicitud de creación del comprobante (FECAESolicitar), utilizando el número del comprobante calculado (último + 1).
  5. Code: Nodo que ejecuta código JavaScript para preparar el texto del código QR.
  6. generate_html: Construye el HTML de la factura utilizando valores dinámicos extraídos de los pasos anteriores.
  7. create_pdf: Envía el HTML generado a la API de Afip SDK para convertirlo en un PDF.
  8. download_pdf: Descarga el archivo PDF resultante.

En la imagen debajo puedes ver cómo luce visualmente el workflow, lo cual ayuda a comprender la secuencia de nodos.

Workflow en n8n


Paso a Paso de la Implementación

1. Nodo: Manual Trigger

  • Función: Activa manualmente la ejecución del workflow.
  • Uso: Útil para pruebas iniciales o ejecución bajo demanda.
  • Configuración: No requiere parámetros adicionales.

2. Nodo: get_authorization

  • Objetivo: Autenticar al usuario ante la API de Afip SDK.
  • Endpoint: https://app.afipsdk.com/api/v1/afip/auth
  • Método: POST
  • Parámetros del cuerpo:
    {
      "environment": "dev",
      "tax_id": "20409378472",
      "wsid": "wsfe"
    }
    
  • Resultado: Devuelve las credenciales necesarias (Token y Sign) que serán utilizados en posteriores peticiones.

Este paso es fundamental para establecer la comunicación segura con la API.


3. Nodo: get_last_voucher_number

  • Objetivo: Obtener el último número de comprobante autorizado.
  • Endpoint: https://app.afipsdk.com/api/v1/afip/requests
  • Método: POST
  • Parámetros del cuerpo:
    Se define utilizando el método FECompUltimoAutorizado, junto a los datos de autenticación obtenidos en el paso anterior y los parámetros específicos como “PtoVta” y “CbteTipo”.
    Ejemplo (fragmento):
    {
      "environment": "dev",
      "method": "FECompUltimoAutorizado",
      "wsid": "wsfe",
      "params": {
        "Auth": {
          "Token": "{{ $json.token }}",
          "Sign": "{{ $json.sign }}",
          "Cuit": "20409378472"
        },
        "PtoVta": 1,
        "CbteTipo": 11
      }
    }
    
  • Resultado: Se obtiene el número de comprobante (por ejemplo, CbteNro) del último comprobante autorizado. Luego, en el siguiente nodo se utilizará ese número incrementado en uno para la creación del comprobante.

4. Nodo: create_voucher

  • Objetivo: Solicitar a Afip la autorización para emitir un nuevo comprobante.
  • Endpoint: https://app.afipsdk.com/api/v1/afip/requests
  • Método: POST
  • Parámetros del cuerpo:
    Se define utilizando el método FECAESolicitar y se incorporan los datos de autorización, junto a los detalles específicos del comprobante.
    Ejemplo de fragmento del JSON:
    {
      "environment": "dev",
      "method": "FECAESolicitar",
      "wsid": "wsfe",
      "params": {
        "Auth": {
          "Token": "{{ $('get_authorization').item.json.token }}",
          "Sign": "{{ $('get_authorization').item.json.sign }}",
          "Cuit": "20409378472"
        },
        "FeCAEReq": {
          "FeCabReq": {
            "CantReg": 1,
            "PtoVta": 1,
            "CbteTipo": 11
          },
          "FeDetReq": {
            "FECAEDetRequest": {
              "Concepto": 1,
              "DocTipo": 80,
              "DocNro": 33693450239,
              "CbteDesde": {{ $json.FECompUltimoAutorizadoResult.CbteNro + 1 }},
              "CbteHasta": {{ $json.FECompUltimoAutorizadoResult.CbteNro + 1 }},
              "CbteFch": {{ new Date(Date.now() - ((new Date()).getTimezoneOffset() * 60000)).toISOString().split('T')[0].replace(/-/g, '') }},
              "ImpTotal": 100,
              "ImpTotConc": 0,
              "ImpNeto": 100,
              "ImpOpEx": 0,
              "ImpIVA": 0,
              "ImpTrib": 0,
              "MonId": "PES",
              "MonCotiz": 1,
              "CondicionIVAReceptorId": 1
            }
          }
        }
      }
    }
    
  • Notas:
    • Se utiliza una expresión para calcular el número del comprobante como último número + 1.
    • La fecha de emisión se obtiene dinámicamente y se adapta a la zona horaria local.
  • Resultado: Se recibe la respuesta con datos del nuevo comprobante, entre ellos el número asignado y el CAE (Código de Autorización Electrónica), que serán esenciales en el paso siguiente.

5. Nodo: Code (Generación del QR)

  • Objetivo: Construir el texto que se usará para generar el código QR, conforme a las especificaciones de Afip.
  • Descripción:
    Se define un objeto QRCodeData que contiene:
    • Versión del formato
    • Fecha de emisión
    • CUIT del emisor
    • Punto de venta y tipo de comprobante
    • Número de comprobante
    • Importe, moneda y cotización
    • Datos del receptor
    • Tipo y código de autorización (utilizando el CAE obtenido)
    Luego, el objeto se codifica a una cadena Base64 y se concatena en una URL oficial:
    const QRCodeData = {
        'ver': 1,
        'fecha': '2017-10-25', // Asegurarse de actualizar a la fecha real
        'cuit': Number(12345678912),
        'ptoVta': Number(1),
        'tipoCmp': Number(6),
        'nroCmp': Number(32),
        'importe': Number(150),
        'moneda': 'ARS',
        'ctz': Number(1),
        'tipoDocRec': Number(80),
        'nroDocRec': Number(12345678912),
        'tipoCodAut': 'E',
        'codAut': Number($input.first().json.FECAESolicitarResult.FeDetResp.FECAEDetResponse[0].CAE)
    };
    
    const QRCodeText = 'https://www.afip.gob.ar/fe/qr/?p=' + Buffer.from(JSON.stringify(QRCodeData)).toString('base64');
    
    return [{
      qr_code_text: QRCodeText
    }];
    
  • Resultado: El nodo devuelve una propiedad qr_code_text que contiene el enlace completo para la generación del código QR, listo para incorporarse en el HTML de la factura.

6. Nodo: generate_html

  • Objetivo: Construir el documento HTML que representa la factura electrónica.
  • Detalle de la Implementación:
    • Se utiliza un nodo HTML en n8n donde se define una plantilla HTML con estilos y estructura propia.
    • Se incluyen expresiones dinámicas para insertar datos específicos, por ejemplo:
      • Número de comprobante: {{ $('create_voucher').item.json.FECAESolicitarResult.FeDetResp.FECAEDetResponse[0].CbteDesde }}
      • CAE: {{ $('create_voucher').item.json.FECAESolicitarResult.FeDetResp.FECAEDetResponse[0].CAE }}
      • Fecha de vencimiento del CAE: {{ $('create_voucher').item.json.FECAESolicitarResult.FeDetResp.FECAEDetResponse[0].CAEFchVto }}
      • Código QR: La imagen se genera mediante una URL de un servicio externo (por ejemplo, qrserver.com) utilizando el qr_code_text generado en el nodo anterior:
        <img id="qrcode" src="{{ 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' + encodeURIComponent($json.qr_code_text) }}">
        
  • Resultado: Se obtiene el HTML completo de la factura, que se utilizará para generar el PDF.

7. Nodo: create_pdf

  • Objetivo: Convertir el HTML generado en un archivo PDF.
  • Endpoint: https://app.afipsdk.com/api/v1/pdfs
  • Método: POST
  • Parámetros del cuerpo:
    El JSON enviado incluye:
    • El HTML a procesar (serializado usando JSON.stringify).
    • Nombre del archivo (por ejemplo, “Factura”).
    • Opciones de formato (configuración de márgenes, ancho, etc.).
      Ejemplo de JSON:
    {
      "html": "{{ JSON.stringify($json.html) }}",
      "file_name": "Factura",
      "options": {
        "width": 8,
        "marginLeft": 0.4, 
        "marginRight": 0.4, 
        "marginTop": 0.4, 
        "marginBottom": 0.4 
      }
    }
    
  • Resultado: La API devuelve una URL o identificador del PDF generado.

8. Nodo: download_pdf

  • Objetivo: Descargar el archivo PDF generado.
  • Parámetro clave:
    La URL del PDF se extrae de la respuesta del nodo anterior, utilizando expresiones como ={{ $json.file }} para definir la URL en la solicitud.
  • Resultado: Se descarga el PDF final, listo para su uso o almacenamiento.

Problemas comunes

Si estas teniendo el error (10016) El numero o fecha del comprobante no se corresponde con el proximo a autorizar te recomiendo leer este artículo.

Error (10016) El numero o fecha del comprobante no se corresponde con el proximo a autorizar

Error (10016) El numero o fecha del comprobante no se corresponde con el proximo a autorizar

Pasos para resolver este error

Si estas teniendo el error (10242) El campo Condicion IVA receptor es obligatorio. Consular metodo FEParamGetCondicionIvaReceptor te recomiendo leer este artículo.

Error (10242) El campo Condicion IVA receptor no es un valor valido/es obligatorio

Error (10242) El campo Condicion IVA receptor no es un valor valido/es obligatorio

Pasos para resolver este error


Conclusiones y Consideraciones Finales

Aspectos a destacar:

  • Integración Completa: Cada nodo está diseñado para comunicarse y obtener datos necesarios en tiempo real. La autenticación, consulta y generación de comprobante se realizan de manera consecutiva.
  • Flexibilidad de n8n: Permite incluir nodos de código personalizado (JavaScript) que facilitan el formateo y la transformación de datos, algo útil para la creación del código QR.
  • Uso de APIs Externas: El nodo de creación de PDF se conecta a la API de Afip SDK para procesar el HTML, demostrando cómo n8n facilita la integración de servicios externos.
  • Automatización y Escalabilidad: Este workflow puede programarse para ejecutarse automáticamente según las necesidades y adaptarse a flujos de trabajo más complejos.

Si necesitas ajustar alguno de los parámetros (por ejemplo, la fecha en el QR o los estilos del HTML) puedes hacerlo directamente en los nodos correspondientes, aprovechando la capacidad de n8n de trabajar con expresiones dinámicas y código personalizado.

Esta solución ofrece una excelente base para automatizar procesos de facturación electrónica usando Afip SDK en n8n y puede servir como punto de partida para ampliar funcionalidades, como integraciones con sistemas de gestión o notificaciones automáticas.


Luego, lo único que nos queda es pasar a modo producción, para más información de cómo hacerlo pueden dirigirse a la documentación de la librería https://docs.afipsdk.com/


Ante cualquier duda o pregunta al respecto, pueden resolverla rápidamente dentro de la Comunidad Afip SDK. Además, puedes unirte para estar al tanto de las novedades y problemas técnicos al usar los servicios de ARCA.

Conéctate a ARCA hoy mismo

Certificados, código, tutoriales, soporte... todo lo que necesitas para usar los web services de ARCA en un solo lugar.