La emisión de un comprobante electrónico es el flujo más importante de la API. Detrás de una única llamada HTTP, la plataforma genera el XML, lo firma, lo envía al SRI y consulta la autorización. Esta página describe cómo invocar ese flujo y cómo interpretar el resultado.
Modelo conceptual
Tu sistema
│
│ POST /documents { ..., emit: true }
▼
API ── valida y persiste el documento
│ · calcula impuestos
│ · genera el XML SRI
│ · firma con el certificado del negocio
│ · envía al SRI (recepción + autorización)
▼
SRI Ecuador
│
▼
Respuesta al integrador (estado final del comprobante)Pasos típicos del integrador
1. (Opcional) Crear/asegurar el cliente
Si tu integración recibe el RUC/cédula del receptor, primero consulta el directorio:
curl -X GET https://www.factura-tor.com/api/customers/search/0105678901 \
-H "X-API-Key: $API_KEY"Si no existe, créalo con POST /customers. Si existe, reutiliza su id.
2. Emitir el comprobante en una sola llamada
La ruta más eficiente es enviar emit: true directamente. El backend hará todo: validar, generar XML, firmar, enviar al SRI y consultar autorización.
curl -X POST https://www.factura-tor.com/api/documents \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"business_id": 1,
"customer_id": 1,
"document_type_id": 1,
"emission_type_id": 1,
"establishment_id": 1,
"emission_point_id": 1,
"payment_method_id": 1,
"date": "2026-05-24",
"items": [
{ "item_id": 1, "amount": 2, "price": 500.00 }
],
"emit": true
}'emission_point_id es opcional: si lo omites se usa el punto 001 del establecimiento. Envíalo cuando emitas desde varias cajas — cada serie (estab-ptoEmi por tipo de comprobante) lleva su propio secuencial. Consulta Puntos de Emisión.
3. Interpretar la respuesta
Si la emisión fue exitosa (HTTP 200/201), el documento queda en estado authorizated y la respuesta incluye la clave de acceso y los datos finales del comprobante.
Si recibes 4xx o 5xx, consulta Manejo de errores.
4. Descargar el comprobante autorizado
curl -X GET "https://www.factura-tor.com/api/documents/123/download?format=pdf" \
-H "X-API-Key: $API_KEY" \
-o factura-123.pdfY/o enviarlo por correo al cliente:
curl -X POST https://www.factura-tor.com/api/documents/123/email:send \
-H "X-API-Key: $API_KEY"Variante: emisión diferida (borrador → emisión)
Si tu sistema requiere una validación manual previa (por ejemplo, aprobación contable), crea el documento como borrador y emítelo después:
# 1) Crear borrador
curl -X POST https://www.factura-tor.com/api/documents \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "business_id": 1, "customer_id": 1, "document_type_id": 1, "emit": false, "...": "..." }'
# 2) (luego) Emitir el borrador con id=123
curl -X PUT https://www.factura-tor.com/api/documents/123 \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "emit": true }'Idempotencia recomendada
- Persiste un identificador interno en tu sistema (ej. ticket de venta) antes de emitir.
- Si recibes un timeout, lookup por ese identificador antes de reemitir.
- Considera guardar el
idy laaccess_keydel comprobante apenas la API te los devuelva.
Encadenar llamadas: ejemplo realista
async function issueInvoice(sale) {
// 1. Resolve customer
let customer = await api.get(`/customers/search/${sale.customerId}`).catch(() => null);
if (!customer) {
customer = await api.post('/customers', {
businessId: BUSINESS_ID,
identificationTypeId: sale.identificationTypeId,
identification: sale.customerId,
businessName: sale.customerName,
email: sale.customerEmail,
});
}
// 2. Emit invoice atomically
const invoice = await api.post('/documents', {
business_id: BUSINESS_ID,
customer_id: customer.id,
document_type_id: 1,
emission_type_id: 1,
establishment_id: ESTABLISHMENT_ID,
payment_method_id: 1,
date: sale.date,
items: sale.lines.map(l => ({
item_id: l.itemId,
amount: l.qty,
price: l.unitPrice,
})),
emit: true,
});
// 3. Send PDF to customer
await api.post(`/documents/${invoice.id}/email:send`);
return invoice;
}
