Emitir una factura electrónica desde Node.js
Ejemplo JavaScript con fetch para emitir en beta y consultar el CDR de SUNAT.
Del registro a tu primera prueba
- Crea tu cuenta y registra el RUC de tu empresa.
- Abre Configuración asistida: sube tu certificado .p12/.pfx, comprueba la clave y configura el usuario secundario SOL.
- Mantén el ambiente beta. Genera una llave
ff_test_…. Puedes volver a verla y copiarla en Configuración, en API key del ambiente actual. - Emite la factura de prueba. Un HTTP
202indica que el documento quedó en cola. - Consulta
GET /api/sunat/{ruc}/transactions/{id}hasta obtener el resultado de SUNAT y descarga el XML y CDR.
Para producción completa una prueba aceptada, activa el ambiente y genera una llave ff_live_…. La llave beta no puede emitir en producción.
Emite desde Node.js con fetch
Ejecuta este ejemplo en tu servidor. Lee la llave desde process.env.FACTUFLASH_API_KEY y configura la URL del shard como variable de entorno. No incluyas la llave en un bundle de React o una aplicación pública.
Verifica el estado HTTP y la respuesta JSON: un 202 requiere consultar la transacción después. Mantén el UUID de la operación si reintentas por timeout; un nuevo UUID representa una nueva operación.
Un request, cinco lenguajes
Reemplaza TU_SHARD, TU_RUC, la llave, la fecha y el correlativo. El shard asignado aparece al seleccionar la empresa. Usa la fecha actual de Perú.
const response = await fetch("https://TU_SHARD/api/sunat/TU_RUC/generate-invoice", {
method: 'POST',
headers: { Authorization: "Bearer TU_API_KEY", 'Content-Type': 'application/json', 'Idempotency-Key': "GUARDA_UN_UUID_POR_OPERACION" },
body: JSON.stringify({
"tipo_doc": "01",
"tipo_operacion": "0101",
"serie": "FT01",
"correlativo": "1",
"fecha_emision": "2026-11-12",
"tipo_moneda": "PEN",
"client": {
"tipo_doc": "6",
"num_doc": "20123456789",
"rzn_social": "CLIENTE DE PRUEBA"
},
"mto_oper_gravadas": 100,
"mto_igv": 18,
"total_impuestos": 18,
"valor_venta": 100,
"sub_total": 118,
"mto_imp_venta": 118,
"items": [
{
"cod_producto": "TEST",
"descripcion": "Servicio de prueba beta",
"unidad": "ZZ",
"cantidad": 1,
"valor_unitario": 100,
"precio_unitario": 118,
"valor_venta": 100,
"base_igv": 100,
"igv": 18,
"total_impuestos": 18,
"tipo_afe_igv": "10",
"porcentaje_igv": 18
}
]
})
});
console.log(response.status, await response.json());Guarda la llave en una variable de entorno de tu servidor. Evita incluirla en el código del navegador o en repositorios.
Reintentos e idempotencia
Genera un UUID por operación y envíalo en Idempotency-Key. Guarda ese UUID junto a la venta. Si hay un timeout, reintenta con la misma llave y el mismo JSON. Cambiar la llave representa otra operación.
HTTP 409 indica que la llave corresponde a otro contenido o que la operación original sigue en curso. Consulta el estado antes de emitir otro número. La respuesta repetida incluye Idempotency-Replayed: true.
Referencia de la API
La especificación completa es pública. El envío interactivo está deshabilitado en esta vista para que puedas explorar sin emitir.
Conectar un agente por MCP
Conecta FactuFlash con Claude o ChatGPT desde tu cuenta, y comprueba las conexiones autorizadas en un solo lugar.
Conectar mi asistenteEl servicio MCP remoto usa OAuth con PKCE. Agrega la URL MCP configurada por tu administrador, selecciona las empresas y elige si permites acciones. Cada empresa usa su ambiente actual. En producción, las acciones preparan una vista previa y requieren una segunda llamada de confirmación.
El conector necesita un despliegue independiente. Consulta su disponibilidad antes de configurarlo en Claude, ChatGPT o Codex.