Envio de documentos
Esta seccion explica como prevalidar y emitir e-CF con la API de Zarela.
Endpoint
POST /{environment}/documentos-ecf
Donde {environment} es TesteCF, CerteCF o eCF.
Encabezados requeridos
X-API-KEY: {api_key_del_ambiente}
Content-Type: application/json
Accept: application/json
El JSON de emision debe incluir el eNCF que ya asigno tu POS/ERP. No necesitas crear una clave de idempotencia adicional para este endpoint.
Cuerpo
El cuerpo es el documento en formato JSON DGII/XSD (o el contrato simplificado opcional).
Paso 1 (recomendado): prevalidar con validate=true
Antes de emitir oficialmente, valida el documento sin consumir secuencia ni enviar a la DGII:
POST /{environment}/documentos-ecf?validate=true
Cuando validate=true, Zarela:
- Detecta errores de formato y estructura antes de registrar el documento.
- Verifica calculos y totales segun la DGII.
- Genera el XML que saldria hacia DGII y lo comprueba contra el XSD oficial, tambien cuando usas el contrato JSON simplificado de Zarela.
- No consume secuencia de eNCF y no envia a la DGII.
curl -X POST \
'https://ecf.api.zarela.do/TesteCF/documentos-ecf?validate=true' \
-H 'X-API-KEY: zk_test_...' \
-H 'Content-Type: application/json' \
-d @factura.json
Respuesta de pre-flight correcto (200):
{
"ok": true,
"preflight": {
"type": "E31",
"temporaryEncf": "E310000000000",
"xsd": {
"validated": true,
"ok": true,
"schema": "e31.xsd"
},
"totals": {
"baseAfterGlobalDiscount": 2000,
"totalItbis": 360,
"total": 2360
}
},
"errors": [],
"warnings": []
}
Si hay errores, errors contiene el detalle por campo. Corrige y vuelve a prevalidar antes de emitir.
Usa validate=true en desarrollo y QA. Como no consume eNCF, puedes iterar sobre el mismo documento sin gastar rangos.
Paso 2: emitir
Envia el mismo documento sin validate para emitir oficialmente:
curl -X POST \
https://ecf.api.zarela.do/TesteCF/documentos-ecf \
-H 'X-API-KEY: zk_test_...' \
-H 'Content-Type: application/json' \
-d @factura.json
async function emitir(documento) {
const response = await fetch(
"https://ecf.api.zarela.do/TesteCF/documentos-ecf",
{
method: "POST",
headers: {
"X-API-KEY": process.env.ZARELA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify(documento),
}
);
return await response.json(); // { ok, mode, result: { documentId, encf, status } }
}
Respuesta de emision (202):
{
"ok": true,
"mode": "queued",
"result": {
"documentId": "6f89c3d2-5f83-4607-9b50-99527cc40e5a",
"encf": "E310000000010",
"status": "queued_for_signing",
"asyncStatusRequired": true
}
}
Zarela registra el eNCF enviado, convierte el JSON a XML, encola firma y envio, y devuelve de inmediato. Guarda el documentId junto al eNCF para consultar el estado.
Replay seguro y reintentos
El eNCF es la identidad fiscal de la emision. Conserva la relacion ventaERP -> eNCF -> JSON enviado -> documentId.
- El mismo eNCF con el mismo JSON devuelve el documento ya registrado y no crea otro.
- El mismo eNCF con informacion fiscal diferente responde
409 ENCF_PAYLOAD_MISMATCH. - Ante timeout o desconexion, reenvia exactamente el mismo JSON con el mismo eNCF.
- No asignes otro eNCF solo para intentar "destrabar" una solicitud cuyo resultado aun no conoces.
Consulta la matriz de errores y reintentos antes de implementar la politica de retry.
Estados del documento
El procesamiento es asincrono. Un documento pasa por estos estados:
| Estado | Descripcion |
|---|---|
queued_for_signing | Encolado para firma (estado inicial al emitir). |
signed | Firmado (XMLDSig). |
rfce_pending_dispatch | E32 < RD$250,000: resumen RFCE pendiente del despacho nocturno. |
sent | Enviado a la DGII. |
pending_dgii_status | Esperando el estado final de la DGII (TrackID). |
accepted | Aceptado por la DGII (final). |
accepted_conditional | Aceptado condicional, con observaciones de la DGII (final). |
rejected | Rechazado por la DGII (final). |
contingency | DGII no disponible; Zarela reintenta automaticamente. |
cancelled | Cancelado. |
accepted_conditional es un estado final valido fiscalmente, pero la DGII adjunta observaciones (por ejemplo, diferencias de redondeo). Revisa los messages de la consulta por lote y corrige la causa en emisiones futuras.
Debido al procesamiento asincrono, espera unos segundos antes de consultar el estado final. Consulta el estado por lote en Consulta de documentos.
Facturas de consumo (E32) y RFCE
La DGII define dos modalidades de envio para las facturas de consumo segun su monto:
| Modalidad | Que se envia a la DGII | Cuando aplica |
|---|---|---|
| Documento extendido | Encabezado + todos los renglones | MontoTotal ≥ RD$250,000 |
| Resumen RFCE | Solo totales y eNCF | MontoTotal < RD$250,000 |
Zarela gestiona esto automaticamente. Tu siempre envias el documento completo con todos los items; Zarela evalua el MontoTotal y decide la modalidad correcta. Ademas:
- Extrae el codigo de seguridad de la firma para el resumen, garantizando trazabilidad.
- Genera, firma y envia RFCE segun el XSD oficial
RFCE 32 v.1.0.xsd; el runtime usarfce-32.xsd, que modela un solo eNCF por raizRFCE. - Conserva el documento extendido firmado por 10 anos conforme a la retencion de la DGII, sin importar la modalidad enviada.
No necesitas implementar almacenamiento ni decidir la modalidad: Zarela lo hace de forma transparente.
Manejo de errores
| Codigo HTTP | Causa | Solucion |
|---|---|---|
400 | JSON mal formado, invalido o sin eNCF | Verifica la estructura DGII/XSD y el eNCF asignado por el POS. |
401 | Falta o invalida la API key | Revisa el header X-API-KEY. |
403 | API key sin scope ecf:create | Asigna el scope adecuado. |
409 | El eNCF ya existe con otro contenido o fue anulado | No cambies el payload ni la secuencia automaticamente; concilia la venta. |
429 | Limite de solicitudes excedido | Aplica backoff exponencial. |
500 | Error del servidor | Reintenta con backoff; contacta soporte con el correlationId. |
Buenas practicas
- Prevalida con
validate=truedurante el desarrollo. - No bloquees la venta esperando la aceptacion de la DGII.
- Reintentos idempotentes para fallos temporales; no reintentes documentos con errores de validacion.
- Consulta periodica del estado con
status/batch. - Entrega la RI/PDF cuando este disponible y conserva una copia asociada al
documentId.