Proformas / cotizaciones
Documento comercial sin valor tributario. Comparte el shape de la
factura (cliente, líneas, totales, IVA) pero NO se firma ni se envía al
SRI. El cliente accede por una URL pública con token único
(sin login): ve el PDF, lo acepta o lo rechaza. Una vez aceptada, la
conviertes en factura real (codDoc 01) con un solo POST.
Eventos
Cada proforma emite proforma.borrador o
proforma.enviada al crearla, proforma.aceptada /
proforma.rechazada cuando el cliente decide, y
proforma.convertida cuando la conviertes en factura.
Crear una proforma
POST /api/v1/proformas — Crea una proforma (queda como BORRADOR o ENVIADA)
Body
| Parámetro | Tipo | Descripción |
|---|---|---|
tipo_identificacion required | string | Tipo de identificación del cliente (tabla SRI). |
identificacion required | string | RUC/cédula/doc. del cliente. |
razon_social required | string | Razón social del cliente. |
direccion optional | string | Dirección del cliente. |
email optional | string | Email del cliente (se muestra en la cabecera de la proforma). |
validez_dias required | integer | Días de validez comercial (1..365). Default 15. |
notas optional | string | Condiciones comerciales (plazo, forma de pago, etc.). Texto libre. |
detalles required | array | Líneas. Mínimo 1. Misma forma que en factura (codigoPrincipal, descripcion, cantidad, precioUnitario, descuento, tarifaIva, ivaCodigo). |
sucursal_id optional | integer | Sucursal de trazabilidad. |
es_borrador optional | boolean | Si true, queda en BORRADOR. Default: false (estado ENVIADA). |
idempotency_key optional | string | Idempotencia (también header Idempotency-Key). |
Respuesta (201 Created)
La respuesta es la proforma creada, con su token_publico (lo usas para armar la URL del cliente, ver Portal público más abajo). El campo detalles es un arreglo con el mismo shape que en las facturas.
Listado (admin)
GET /api/v1/proformas?q=opcional — Listado compacto con búsqueda por nombre/RUC/secuencial
Obtener una proforma
GET /api/v1/proformas/{id} — Detalle completo, con líneas
Cambiar estado manualmente
PATCH /api/v1/proformas/{id}/estado — Cambia el estado (admin)
Body: json con campo "estado". Valores válidos:
BORRADOR, ENVIADA, ACEPTADA,
RECHAZADA, VENCIDA.
PDF interno
GET /api/v1/proformas/{id}/pdf — Devuelve el PDF binario (con marca 'PROFORMA')
Convertir en factura
POST /api/v1/proformas/{id}/convertir — Convierte la proforma en una FACTURA real (codDoc 01) y la enlaza
Devuelve un objeto json con campos ok, proforma_id
y factura_id. La factura queda en estado PENDIENTE
y entra automáticamente al worker del SRI — el resto del flujo es
idéntico al de emitir una factura normal.
Portal público (SIN auth, con token)
Estas rutas viven bajo /api/v1/p/proformas/TOKEN (donde
TOKEN es el valor devuelto en token_publico):
el cliente las accede sin login. El token aparece en la respuesta al
crear la proforma y se puede mostrar al cliente como URL.
URL pública recomendada al cliente
https://app.emitoo.io/p/<token>Ver una proforma (público)
GET /api/v1/p/proformas/{token} — Devuelve datos básicos (sin auth)
PDF público
GET /api/v1/p/proformas/{token}/pdf — Sirve el PDF de la proforma (sin auth)
Aceptar (público)
POST /api/v1/p/proformas/{token}/aceptar — El cliente acepta la proforma
Rechazar (público)
POST /api/v1/p/proformas/{token}/rechazar — El cliente rechaza la proforma
Atajo: convertir tras aceptar
proforma.aceptada. A partir de ahí la UI muestra un botón
'Convertir en factura' para que tú generes la factura real (el cliente
no la convierte por sí mismo).