El error 401 indica que falta autenticación: para generar certificados en producción con Afip SDK necesitas un access_token válido, obtenido desde https://app.afipsdk.com/. Debes incluirlo en la configuración al instanciar Afip, por ejemplo: access_token: 'TU_ACCESS_TOKEN' y asegurarte de que production esté en true según el entorno deseado. No debes pasar la ruta del archivo en cert y key, sino el contenido del archivo o dejar esos campos vacíos al crear el certificado, ya que se generan en la respuesta del método CreateCert.
Según la documentación oficial, la creación de certificados requiere el access_token y los parámetros correctos; si no se provee, la API responde con 401 (no autorizado) (ver guía de producción). Además, para guardar el certificado y la clave, debes usar los valores devueltos por CreateCert, no antes de la llamada.
¿Te gustaría ver un ejemplo de código corregido paso a paso?
Sources:
@user me tira undefined asi esta bien hecho el create certificate import { fileURLToPath } from "url"; import { dirname, join } from "path"; import { writeFileSync } from "fs"; const afipToken = process.env.ACCESS_TOKEN_AFIPSDK; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Usar importación dinámica para los módulos ESM const loadAfipModule = async () => { const Afip = (await import("@afipsdk/afip.js")).default; // Configuración inicial de la AFIP SDK con los archivos generados const afip = new Afip({ CUIT: 20149853139, // CUIT del usuario // cert: join(__dirname, "../certs/certificado.crt"), // key: join(__dirname, "../certs/clave.privada"), access_token: afipToken, production: true, // Cambiado a false para testing }); console.log("afip", afip); return afip; }; const taxId = 20149853139; // CUIT para el certificado const username = "20149853139"; // Usuario const password = "Daniel2580"; // Clave provista por el usuario const alias = "afipsdk"; // Alias para el certificado const generateCert = async () => { const afip = await loadAfipModule(); try { const res = await afip.CreateCert(username, password, alias); const certPath = join(__dirname, "../certs/certificado.crt"); const keyPath = join(__dirname, "../certs/clave.privada"); writeFileSync(certPath, res.cert); writeFileSync(keyPath, res.key); console.log("Certificado y clave generados y guardados correctamente."); } catch (error) { console.error("Error al generar el certificado:", error.message); } }; generateCert(); afip <ref *1> Afip { sdk_version_number: '1.1.1', options: { CUIT: 20149853139, access_token: undefined, production: true, cert: undefined, key: undefined },
No, no está bien: tu variable afipToken está undefined, por lo que el access_token no se está pasando a la instancia de Afip. Esto provoca que el método CreateCert devuelva undefined o error, ya que el access_token es obligatorio para crear certificados (ver documentación).
Asegúrate de que process.env.ACCESS_TOKEN_AFIPSDK tenga el valor correcto antes de instanciar Afip. Puedes hacer un console.log(afipToken) antes de crear la instancia para verificarlo. ¿Te gustaría ver cómo validar y corregir esto en tu código?
Sources:
@user import Afip from "@afipsdk/afip.js"; import "dotenv/config"; const accesTokenAfip = process.env.ACCESS_TOKEN_AFIPSDK; const afip = new Afip({ access_token: "MQ0OWhgXTYF0LZkWrSI8PpqFbrpZCX5KrQgCLqGhX4IORHB9yPRqAhrSvdal2vf0" }); // Aqui deben cambiar los datos por los que correspondan. // Esta request de ejemplo incluye todos posibles // valores para ejecutar la automatizacion create-cert-prod, // puede que algun valor sea opcional. const data = { cuit: "20149853139", username: "20149853139", password: "Daniel2580", alias: "afipsdk", }; (async () => { try { // Ejecutamos la automatizacion const response = await afip.CreateAutomation( "create-cert-prod", data, true ); // Mostramos la respuesta por consola console.log(response); } catch (error) { // En caso de error lo mostramos por consola console.error(error); } })();D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Afip.js:54 if (!options.hasOwnProperty('CUIT')) {throw new Error("CUIT field is required in options array");} ^ Error: CUIT field is required in options array at new Afip (D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Afip.js:54:46) at file:///D:/VALEN/Innovis/Distrolac/server/src/utils/certs/createCertificate.js:6:14 at ModuleJob.run (node:internal/modules/esm/module_job:234:25) at async ModuleLoader.import (node:internal/modules/esm/loader:473:24) at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:122:5) Node.js v20.18.2
El error se debe a que al instanciar Afip, falta el parámetro obligatorio CUIT en el objeto de configuración. Debes agregar CUIT: 20149853139 al crear la instancia, así:
const afip = new Afip({
CUIT: 20149853139,
access_token: "MQ0OWhgXTYF0LZkWrSI8PpqFbrpZCX5KrQgCLqGhX4IORHB9yPRqAhrSvdal2vf0"
});
Sin el campo CUIT, el SDK lanza el error "CUIT field is required in options array" (ver ejemplo oficial).
¿Te gustaría ver el ejemplo completo corregido?
Sources:
@user :52 TypeError: afip.CreateAutomation is not a function at file:///D:/VALEN/Innovis/Distrolac/server/src/utils/certs/createCertificate.js:26:33 at file:///D:/VALEN/Innovis/Distrolac/server/src/utils/certs/createCertificate.js:38:3 at ModuleJob.run (node:internal/modules/esm/module_job:234:25) at async ModuleLoader.import (node:internal/modules/esm/loader:473:24) at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:122:5) ahora tira este error puede ser por la version del sdk que tenemos?
Sí, el error TypeError: afip.CreateAutomation is not a function suele deberse a que la versión del SDK instalada no soporta el método CreateAutomation, o bien a una instalación incorrecta. Debes asegurarte de tener la versión 1.1.1 o superior de @afipsdk/afip.js, ya que versiones anteriores no incluyen este método (ver documentación oficial).
Verifica tu versión con npm list @afipsdk/afip.js y actualiza si es necesario con npm install @afipsdk/afip.js@latest. ¿Te gustaría instrucciones para actualizar el SDK?
Sources:
Error: Request failed with status code 400 at D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Afip.js:84:20 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Axios.request (D:\VALEN\Innovis\Distrolac\server\node_modules\axios\dist\node\axios.cjs:4275:14) at async Afip.CreateAutomation (D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Afip.js:270:17) at async file:///D:/VALEN/Innovis/Distrolac/server/src/utils/certs/createCertificate.js:26:22 { status: 400, statusText: 'Bad Request', data: { statusCode: 400, message: 'Las automatizaciones no se encuentran habilitadas en este proyecto. Ingrese en https://app.afipsdk.com/billing para activarlas. ID bacf1740-3570-4c80-9a80-dc9aa07d0b63' } }
@user Error general al generar factura: Error: Request failed with status code 400 (D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Class\ElectronicBilling.js:346:25) at async ElectronicBilling.getLastVoucher (D:\VALEN\Innovis\Distrolac\server\node_modules@afipsdk\afip.js\src\Class\ElectronicBilling.js:67:11) at async AfipController.generateInvoice (file:///D:/VALEN/Innovis/Distrolac/server/src/controller/afipController.js:169:27) { status: 400, statusText: 'Bad Request', data: { statusCode: 400, message: "El certificado no es válido. Si lo guardó en un archivo, ábralo en un editor de texto y verifique que comience con '-----BEGIN CERTIFICATE-----'." } } POST /api/afip/generateInvoice 500 609.183 ms - 383 -----BEGIN CERTIFICATE----- MIIDQjCCAiqgAwIBAgIIZyn3ZyqH/zswDQYJKoZIhvcNAQENBQAwMzEVMBMGA1UEAwwMQ29tcHV0 YWRvcmVzMQ0wCwYDVQQKDARBRklQMQswCQYDVQQGEwJBUjAeFw0yNTEwMjExMzQ2NTdaFw0yNzEw MjExMzQ2NTdaMC0xEDAOBgNVBAMMB2FmaXBzZGsxGTAXBgNVBAUTEENVSVQgMjAxNDk4NTMxMzkw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLLCG37wU2fnN1vHejmshD1NeqxI/GjH+c 0vKMoOohze3Y98y+fcrsjznMljqv6uVrPB7PPmG9iPGXXVdGllv9yqVv2ld0xsb8ZYxTciGFcykv MS4v3VRfcmFixHpE6NU7vcfrXduuKfJOUuKN8B4SpdLyHUH4CXh6bp93rtw27vbrXpaxRAGn0to2 L9DQzPQ4W+al+x8ih9j/yfVYtawhIOUyWZD8H1k9Tvs6ef73u7+nzwyHvRYgqDb/qfnWhQxQsKBB shPLYw6adQkIDgA2vTtVYzho3iLamDj3vGZwTpnqqcxkfWSHB71jHYB381LbNLeqeR8K8NKsmUsE SmPnAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUKw0vyN9h/QjJThHQNZMEbY5b 0G4wHQYDVR0OBBYEFKJivM3RrEZ2QL7VkAxsmyKuGt0uMA4GA1UdDwEB/wQEAwIF4DANBgkqhkiG 9w0BAQ0FAAOCAQEAHnxCoNZxHcoABwiIKJmHkvOm7Ko61qMAZCqv8t6ZCyPuplhL7LtIPYbJJMAl uNXMjWeOZakjP9mf1iWKkRlyMVToc0jiD4XulQpZhvUKISnvxO69par/8e131KcBm4lQYrqX143z VBedpGwtp5MlGaGoeYNb5jtXqD6rjA2xDaahTE3IX0zxmU3c7TmV+/4hjMQjbW6N6o/AGED3kbpT JpOPaaRO/GiuRTElH9jcA62o4YgKfmdwSQ6W8b58TtSh8AMv39V/KPI32M+7dVVj3nx/LPxLDY8l 8f7F270zQ57AT1F3QZmKjwNo91J8/5AfoBs409q3wSaLY0s/cLqzAA== -----END CERTIFICATE-----
El error indica que el certificado no es válido o no está bien formateado. Debes asegurarte de que el archivo que pasas como cert contenga exactamente el texto del certificado, incluyendo las líneas -----BEGIN CERTIFICATE----- y -----END CERTIFICATE-----, sin espacios extra ni caracteres adicionales (ver documentación).
Además, no debes pasar la ruta del archivo, sino el contenido del archivo leído con fs.readFileSync('./certificado.crt', {encoding: 'utf8'}) al instanciar Afip. Si el certificado fue generado incorrectamente, vuelve a generarlo siguiendo los pasos oficiales.
¿Quieres ver un ejemplo de cómo leer y pasar correctamente el certificado en Node.js?
Sources:
si
@user si
Hola, solo puedo responder preguntas relacionadas con Afip SDK, integración con los web services de ARCA, certificados digitales, facturación electrónica y temas afines. Por favor, si tienes una consulta sobre Afip SDK o necesitas ayuda técnica, detállala un poco más para que pueda ayudarte. ¿En qué aspecto de Afip SDK necesitas asistencia?
@user @si quiero ver un ejemplo de como leer y pasar correctamente el certficado en node js
Claro, aquí tienes un ejemplo de cómo leer y pasar correctamente el contenido del certificado y la clave al instanciar Afip en Node.js:
import fs from 'fs';
import Afip from '@afipsdk/afip.js';
const cert = fs.readFileSync('./certificado.crt', { encoding: 'utf8' });
const key = fs.readFileSync('./clave.privada', { encoding: 'utf8' });
const afip = new Afip({
CUIT: 20149853139,
cert: cert,
key: key,
access_token: 'TU_ACCESS_TOKEN',
production: true
});
No debes pasar la ruta, sino el contenido de los archivos, como muestra la documentación oficial (ver ejemplo).
¿Te gustaría ver cómo usar este objeto para emitir una factura?
Sources:
@user 0|administracion | Error general al generar factura: AfipWebServiceError: (11002) El punto de venta no se encuentra habilitado a usar en el presente WS. Ver metodo FEParamGetPtosVenta 0|administracion | at ElectronicBilling._checkErrors (/home/Distrolac/server/node_modules/@afipsdk/afip.js/src/Class/ElectronicBilling.js:409:10) 0|administracion | at ElectronicBilling.executeRequest (/home/Distrolac/server/node_modules/@afipsdk/afip.js/src/Class/ElectronicBilling.js:350:14) 0|administracion | at process.processTicksAndRejections (node:internal/process/task_queues:95:5) 0|administracion | at async ElectronicBilling.getLastVoucher (/home/Distrolac/server/node_modules/@afipsdk/afip.js/src/Class/ElectronicBilling.js:67:11) 0|administracion | at async AfipController.generateInvoice (file:///home/Distrolac/server/src/controller/afipController.js:169:27) { 0|administracion | code: 11002 0|administracion | }
El error (11002) "El punto de venta no se encuentra habilitado a usar en el presente WS" indica que el punto de venta que intentas usar no está habilitado para el web service de facturación electrónica. Debes crear y habilitar un punto de venta específico para web services desde el portal de AFIP/ARCA, en la opción "Administración de puntos de venta y domicilios" y elegir la opción correspondiente según tu condición fiscal. Luego, espera unos minutos para que el alta impacte en todos los sistemas antes de volver a intentar emitir la factura. Más detalles en la documentación oficial y solución al error en este enlace y el tutorial para crear punto de venta.
¿Te gustaría una guía paso a paso para habilitar el punto de venta o ayuda para verificar si ya está correctamente configurado?
Sources:
@user 00001 Factura en Linea - Responsable Inscripto FISCAL - 0001 - MASSI 222 - MAIPU - MENDOZA DISTROLAC S. A. S. 00002 RECE para aplicativo y web services FISCAL - 0001 - MASSI 222 - MAIPU - MENDOZA DISTROLAC cual de estos 2 puntos de venta es para web services
El punto de venta correcto para web services es el que dice "RECE para aplicativo y web services". Solo este tipo está habilitado para emitir comprobantes mediante integración vía API o SDK, mientras que "Factura en Línea" es solo para facturación manual desde el portal web de AFIP/ARCA. Más información en el tutorial oficial de crear punto de venta.
¿Necesitás ayuda para configurar o verificar la habilitación de ese punto de venta?
Sources: