Guía por stack Node 18+ fetch nativo

Cómo integrar facturación electrónica del SRI en Node.js

Emite facturas electrónicas del SRI desde Node.js con una sola función. Sin librerías de firma ni XML: tú envías JSON y Flashpi hace el resto.

LO QUE VAS A HACER4 pasos

  1. Prepara el proyecto
  2. Escribe la función que emite la factura
  3. Ejecútala
  4. Maneja el estado EN_PROCESAMIENTO

Antes de empezar

Node 18 o superior

Trae fetch integrado, no necesitas instalar nada más.

Una API key de pruebas de Flashpi

Guárdala en una variable de entorno, nunca en el código ni en el repositorio.

Solicítala aquí

Tu certificado de firma .p12

Cargado en la cuenta de pruebas.

Cargar el certificado

Tus datos de emisor

RUC, establecimiento y punto de emisión configurados en tu cuenta.

Paso 1 · Prepara el proyecto

bashterminal
mkdir facturacion && cd facturacion
npm init -y
export FLASHPI_API_KEY="tu_api_key_de_pruebas"

Usa archivos .mjs (o agrega "type": "module" en package.json) para poder usar import y await al nivel superior.

Paso 2 · Escribe la función que emite la factura

jsemitir-factura.mjs · Node 18 o superior
// emitir-factura.mjs  (Node 18 o superior)
const BASE_URL = "https://api.flashpi.ec/v1";
const API_KEY = process.env.FLASHPI_API_KEY;

if (!API_KEY) {
  console.error("Falta la variable de entorno FLASHPI_API_KEY");
  process.exit(1);
}

async function emitirFactura(factura) {
  const res = await fetch(`${BASE_URL}/facturas`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(factura),
  });

  const data = await res.json();
  if (!res.ok) {
    throw new Error(`Flashpi ${res.status}: ${JSON.stringify(data)}`);
  }
  return data;
}

const factura = {
  comprador: {
    tipo_identificacion: "cedula",
    identificacion: "0102030405",
    razon_social: "Cliente de ejemplo",
    email: "[email protected]",
  },
  detalles: [
    { descripcion: "Servicio de ejemplo", cantidad: 1, precio_unitario: 25.0 },
  ],
};

try {
  const resultado = await emitirFactura(factura);
  console.log(resultado.estado, resultado.clave_acceso);
} catch (err) {
  console.error(err.message);
  process.exit(1);
}

Paso 3 · Ejecútala

bashterminal
node emitir-factura.mjs

Deberías ver el estado y la clave de acceso del comprobante. Si ves EN_PROCESAMIENTO, pasa al paso siguiente.

Paso 4 · Maneja el estado EN_PROCESAMIENTO

El SRI a veces tarda. En vez de reenviar (lo que provoca el error de clave de acceso registrada), consulta el estado con unos pocos reintentos:

jsconsultar y esperar la autorización
async function consultar(claveAcceso) {
  const res = await fetch(`${BASE_URL}/comprobantes/${claveAcceso}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  if (!res.ok) throw new Error(`Flashpi ${res.status}`);
  return res.json();
}

async function esperarAutorizacion(claveAcceso, intentos = 5, esperaMs = 2000) {
  for (let i = 0; i < intentos; i++) {
    const comprobante = await consultar(claveAcceso);
    if (comprobante.estado !== "EN_PROCESAMIENTO") return comprobante;
    await new Promise((r) => setTimeout(r, esperaMs));
  }
  throw new Error("Sigue en procesamiento: vuelve a consultar más tarde");
}

Para volumen alto, usa webhooks en lugar de polling.

Errores frecuentes

SíntomaCausa probableQué hacerReferencia
401 UnauthorizedAPI key ausente, inválida o de otro ambiente.Revisa el header Authorization y que uses la key del ambiente correcto.Ver detalle
422 Esquema XMLAlgún campo no cumple la estructura esperada.Lee el detalle del error y corrige el campo indicado.Ver detalle
SRI 43Clave de acceso ya registrada.No reenvíes: consulta el estado del comprobante por su clave de acceso.Ver detalle
SRI 70Clave de acceso en procesamiento.Espera unos segundos y consulta el estado. No reenvíes el comprobante.Ver detalle

Siguientes pasos

Empieza hoy

Obtén tu API key y prueba el ejemplo

Prueba la API en el ambiente de pruebas del SRI y pasa a producción cuando estés listo.