Flujos de integración

Emisión de un comprobante

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

text
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:

bash
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.

bash
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

bash
curl -X GET "https://www.factura-tor.com/api/documents/123/download?format=pdf" \
  -H "X-API-Key: $API_KEY" \
  -o factura-123.pdf

Y/o enviarlo por correo al cliente:

bash
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:

bash
# 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 id y la access_key del comprobante apenas la API te los devuelva.

Encadenar llamadas: ejemplo realista

javascript
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;
}