Disponible
Emite cientos de e-CF a la vez desde una hoja de cálculo, sin programar. Firmo lee todo el archivo, lo valida con las mismas reglas de POST /v1/ecf y te muestra los errores por hoja, fila y columna. No emite nada hasta que lo confirmas. Tres formas de usarlo:
- Portal: Facturas → Importar desde Excel.
- API: las rutas
/v1/importsde esta página. - Google Sheets: la misma plantilla con un botón Emitir (ver más abajo).
La plantilla#
Descarga firmo-plantilla-facturas.xlsx (o con GET /v1/imports/template). Tiene tres hojas: Facturas (una fila por factura), Detalle (una fila por ítem, unida por la referencia) e Instrucciones (un ejemplo con datos ficticios). Las columnas tipo, itbis y tipo_pago tienen listas desplegables.
Hoja Facturas
| Columna | Obligatoria | Qué va |
|---|---|---|
referencia | Sí | Tu identificador, único en el archivo. Firmo lo guarda como idExterno: una referencia ya emitida no se vuelve a emitir. |
tipo | Sí | 31, 32, 33, 34, 41, 43, 44, 45, 46 o 47. |
fecha_emision | No | AAAA-MM-DD, DD/MM/AAAA o fecha de Excel. Vacío = hoy (hora de RD). No puede ser futura. |
rnc_comprador | Según el tipo | RNC (9) o cédula (11), sin guiones. Obligatorio en 31, 41 y 45. En 46 y 47 acepta un identificador extranjero. |
razon_social_comprador | Según el tipo | Obligatoria en 31 y 45. |
correo_comprador | No | Correo del comprador. |
tipo_pago | No | contado (por defecto), credito o gratuito. |
fecha_limite_pago | Si es crédito | Obligatoria con tipo_pago credito (salvo en 32). |
forma_pago | No | efectivo, transferencia, tarjeta, credito, bonos, permuta, nota_credito u otras. Se registra por el total. |
encf_modificado | En 33 y 34 | e-NCF de la factura que modificas. |
fecha_modificado | En 33 y 34 | Fecha de esa factura. |
codigo_modificacion | En 33 y 34 | 1 a 5. |
enviar_correo | No | si o no (por defecto no). |
total_esperado | No | Si lo llenas, Firmo verifica que el total calculado (con ITBIS) cuadre. |
Hoja Detalle
| Columna | Obligatoria | Qué va |
|---|---|---|
referencia | Sí | La referencia de su factura. |
descripcion | Sí | Hasta 80 caracteres. |
cantidad | Sí | Mayor que 0. |
precio_unitario | Sí | Precio SIN ITBIS. |
itbis | No | 18 (por defecto), 16, 0 o exento. |
descuento | No | Monto de descuento de la línea. |
tipo | No | bien (por defecto) o servicio. En CSV se llama tipo_item. |
codigo | No | Tu código del producto. |
Además de las reglas de la DGII, Firmo revisa: referencias repetidas, ítems sin factura, facturas sin ítems, RNC de 9 u 11 dígitos, fechas reales y que el total cuadre.
Formato CSV#
Una sola tabla, una fila por ítem: las columnas de la hoja Facturas y, en la misma fila, las del ítem (descripcion, cantidad, precio_unitario, itbis, descuento, tipo_item y codigo). Repite la referencia en cada ítem; los datos de la factura se toman de su primera fila (en las siguientes déjalos vacíos o iguales). Separador coma, punto y coma o tabulador; UTF-8 (también acepta el CSV de Excel en Windows).
referencia;tipo;rnc_comprador;razon_social_comprador;tipo_pago;descripcion;cantidad;precio_unitario;itbis;tipo_item
FAC-0101;31;101010101;Ferretería El Martillo SRL;contado;Cemento gris 42.5 kg;10;600;18;bien
FAC-0101;;;;;Transporte a obra;1;2000;18;servicio
FAC-0102;32;;;contado;Libro de recetas;1;800;exento;bienAPI#
1. Subir y validar (vista previa)
POST/v1/imports
multipart/form-data con archivo (.xlsx o .csv). Responde 201 con la vista previa en estado validado o con_errores. Un archivo sin la estructura de la plantilla responde 400.
curl -X POST https://api.firmo.do/v1/imports \
-H "Authorization: Bearer $FIRMO_API_KEY" \
-F "archivo=@facturas-noviembre.xlsx"{
"id": "6f1c2a8e-3b7d-4f0a-9c51-2d8e7b4a1f30",
"estado": "con_errores",
"resumen": { "facturas": 120, "items": 348, "montoTotal": 1845230.5, "totalItbis": 281475.18 },
"errores": [],
"filas": [
{
"referencia": "FAC-0101", "tipo": 31, "comprador": "Ferretería El Martillo SRL",
"montoTotal": 9440, "totalItbis": 1440, "errores": [], "resultado": null
},
{
"referencia": "FAC-0102", "tipo": 31, "comprador": null, "montoTotal": 0, "totalItbis": 0,
"errores": [
{ "hoja": "Facturas", "fila": 3, "columna": "rnc_comprador", "mensaje": "El tipo 31 requiere el RNC o la cédula del comprador" },
{ "hoja": "Detalle", "fila": 5, "columna": "precio_unitario", "mensaje": "«mil» no es un número" }
],
"resultado": null
}
]
}2. Emitir
POST/v1/imports/{id}/emit
Solo si está validado (si tiene errores responde 409). Encola la emisión y responde 202 en emitiendo. Cada factura se emite con idExterno = referencia: una referencia que ya existe no se duplica y queda como ya_emitida con su e-NCF. Repetir la llamada no vuelve a emitir; usa Idempotency-Key.
curl -X POST https://api.firmo.do/v1/imports/6f1c2a8e-3b7d-4f0a-9c51-2d8e7b4a1f30/emit \
-H "Authorization: Bearer $FIRMO_API_KEY" \
-H "Idempotency-Key: 9b2f4c1e-7a3d-4e8b-a6c5-1f0e2d3c4b5a"3. Progreso y resultados
GET/v1/imports/{id}
progreso cuenta las facturas con resultado; cada filas[].resultado trae encf, estado (el del e-CF, o ya_emitida / no_emitida), mensaje y pdf. La importación pasa a completado cuando todas tienen su resultado final.
GET/v1/imports/{id}/results
Excel con tu hoja Facturas original (o el CSV) más las columnas encf, estado, mensaje y pdf. Antes de emitir, marca las filas con errores.
GET/v1/imports
Historial de importaciones (?limit=&cursor=), las más recientes primero.
Plantilla de Google Sheets#
Si trabajas en Google Sheets, usa la misma plantilla con un menú Firmo que emite desde la hoja. El script está en tools/plantillas/google-sheets/ del repositorio de Firmo (Codigo.gs y appsscript.json).
- Sube la plantilla .xlsx a Google Drive, ábrela con Google Sheets y guárdala como hoja de cálculo de Google.
- Extensiones → Apps Script: pega
Codigo.gsy reemplaza el manifiestoappsscript.json(actívalo en Configuración del proyecto). - Recarga la hoja y usa Firmo → Configurar API key. Google pide autorizar el script (solo esta hoja, llamadas a api.firmo.do y el menú).
- Selecciona una fila y usa Emitir fila seleccionada, o Emitir todas las pendientes. Con Actualizar estados consultas las que quedaron en proceso.
Cada fila se envía a POST /v1/ecf?wait=true con Idempotency-Key e idExterno iguales a la referencia, y el script escribe encf, estado, mensaje y pdf. Si algo falla, pinta la fila de rojo con el motivo.
Cuida tu API key
La llave se guarda en las propiedades de tu usuario de Google, nunca en la hoja. Aun así, no compartas con permiso de edición una hoja en la que uses una llave de producción (sk_live_). Haz las pruebas con sk_test_: el simulador responde como la DGII y nada llega a ella.