Saltar al contenido
Factuplan
Escritorio de un desarrollador ecuatoriano con laptop mostrando código JSON donde se resalta la clave sendEmail en false, una terminal abierta con un curl POST al endpoint de facturas, post-its con la palabra whitelabel y un teléfono al costado mostrando un correo de factura sin logos

API Whitelabel: emitir facturas sin enviar correos al cliente

Si integras Factuplan en una app whitelabel, usa sendEmail false al emitir facturas vía API y evita que el correo salga con el logo de Factuplan al cliente.

· 15 min de lectura · Equipo Factuplan
Compartir:

Si estás integrando el API de Factuplan dentro de tu propio producto — un ERP, un POS, una app vertical, un SaaS para un nicho específico — probablemente quieres que la experiencia del cliente final sea 100% tu marca. Sin embargo, por defecto, cuando emites una factura por el endpoint POST /v1/developer/invoices, Factuplan envía un correo automático al cliente con el RIDE adjunto y con su propio logo y branding — tanto en pruebas (ak_test_*) como en producción (ak_live_*).

Si tu integración es whitelabel, ese correo rompe la ilusión. Tu cliente recibe la factura “de Factuplan”, no de tu app. La buena noticia: el API tiene una bandera explícita para apagar ese envío y dejarte a ti el control del correo. Se llama sendEmail y va en el body del request.

El problema: el correo automático no es whitelabel

El Modo A del API (el camino recomendado) hace todo el flujo de un golpe: crea el XML, lo firma con tu certificado P12, lo autoriza ante el SRI, genera el RIDE en PDF y envía el correo al cliente automáticamente.

Ese correo:

  • Sale desde un dominio de Factuplan (no del tuyo).
  • Trae la plantilla, los colores y el logo de Factuplan.
  • Aparece igual en pruebas y en producción — no hay un “modo silencioso” implícito.
  • Incluye el RIDE (PDF) y el XML autorizado como adjuntos.

Para un cliente final que está usando tu plataforma “Acme Facturación”, recibir un correo que dice “Factuplan” lo confunde, te pone en una conversación incómoda (“¿y qué es Factuplan?”) y, peor todavía, le entrega a tu cliente un canal directo para descubrir y comparar con tu proveedor de infraestructura. Si vendes whitelabel, eso te puede costar la relación.

La solución: sendEmail: false

El cuerpo del request del endpoint acepta una bandera booleana llamada sendEmail. Por defecto es true. Si la pones en false, Factuplan:

  • Sigue creando el XML, firmándolo, autorizándolo ante el SRI y generando el RIDE.
  • No envía ningún correo al cliente.
  • Te deja a ti el XML y el PDF disponibles para descargar desde los endpoints GET /v1/developer/receipts/{id}/xml y GET /v1/developer/receipts/{id}/pdf.

Es la forma limpia de mantener el flujo automático del SRI sin que tu cliente final reciba un correo de Factuplan.

La bandera existe solo en dos emisiones: facturas (POST /v1/developer/invoices) y liquidaciones de compra (POST /v1/developer/purchase-settlements). Las notas de crédito, las notas de débito y las retenciones emitidas por API no la aceptan: si la envías, el API responde 400, y esos comprobantes siempre envían el correo de Factuplan al receptor.

Ejemplo mínimo

{
"customer": {
"identificationType": "RUC",
"identification": "0993378150001",
"legalName": "Empresa Demo S.A.",
"email": "facturas@empresademo.ec"
},
"items": [
{
"code": "SERV-001",
"description": "Servicio de consultoría",
"quantity": 1,
"unitPrice": 150.0,
"taxType": "IVA_RATE",
"tax": 15
}
],
"payments": [
{ "method": "20", "amount": 172.5 }
],
"sendEmail": false
}

Fíjate que el campo customer.email sigue siendo obligatorio aunque sendEmail esté en false: si no envías customerId, el API responde 400 cuando falta o no es un correo válido. Con sendEmail: false ese correo se guarda en la ficha del cliente, pero Factuplan no lo usa para notificar esta factura. Si tu modelo de datos no captura el email del receptor, envía igualmente una dirección válida (por ejemplo, un buzón de tu plataforma).

Ejemplo completo con cURL

Ventana de terminal
curl https://api-rest.factuplan.com.ec/v1/developer/invoices \
-X POST \
-H "X-API-Key: $FACTUPLAN_API_KEY" \
-H "x-taxpayer-ruc: 0950194407001" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"identificationType": "RUC",
"identification": "0993378150001",
"legalName": "Empresa Demo S.A.",
"email": "facturas@empresademo.ec"
},
"items": [
{
"code": "SERV-001",
"description": "Servicio de consultoría",
"quantity": 1,
"unitPrice": 150.0,
"taxType": "IVA_RATE",
"tax": 15
}
],
"payments": [
{ "method": "20", "amount": 172.5 }
],
"sendEmail": false
}'

La respuesta es la misma 201 Created que en el flujo normal, con el id del comprobante en estado DRAFT. Después haces polling a GET /v1/developer/receipts/{id}/status hasta que llegue a COMPLETED (antes pasa por AUTHORIZED: autorizado por el SRI, pero con el RIDE quizá todavía sin generar) y descargas tú mismo el RIDE para mandárselo al cliente desde tu propio servicio de correo.

Body completo del endpoint POST /v1/developer/invoices

Para que no tengas que saltar entre pestañas, este es el body completo que acepta el endpoint según la referencia del API. El campo sendEmail está al mismo nivel que customer, items y payments. Los valores marcados con (opcional) son marcadores de posición: no envíes el ejemplo tal cual. customerId, productId y emissionPointId solo se envían cuando ya tienes esos IDs, y entonces reemplazan a los datos en línea.

{
"customer": {
"customerId": "cust_id (opcional)",
"identificationType": "RUC",
"identification": "0993378150001",
"legalName": "Empresa Demo S.A.",
"email": "facturas@empresademo.ec",
"address": "Guayaquil, Ecuador",
"phone": "+593958657236",
"saveToContacts": true
},
"items": [
{
"quantity": 1,
"productId": "prod_id (opcional)",
"code": "SERV-001",
"auxiliaryCode": "AUX-001 (opcional)",
"description": "Servicio de consultoría",
"unitPrice": 150.0,
"discount": 0,
"taxType": "IVA_RATE",
"tax": 15,
"saveToProducts": false
}
],
"emissionPointId": "ep_id (opcional)",
"establishment": "001 (opcional)",
"emissionPoint": "001 (opcional)",
"additionalInfo": { "Vendedor": "Juan Pérez" },
"sendEmail": true,
"devReference": "pedido-1001",
"payments": [
{
"method": "20",
"amount": 172.5,
"term": 30,
"timeUnit": "dias"
}
]
}

Campos del customer

CampoTipoRequeridoNotas
customerIdstringNoSi se envía, ignora los demás campos y usa el cliente del directorio.
identificationTypeenumSíRUC, CEDULA, PASSPORT, FINAL_CONSUMER, EXTERIOR.
identificationstringSíRUC = 13 dígitos · CEDULA = 10 dígitos.
legalNamestringSíRazón social o nombre completo.
emailstringSí (salvo que envíes customerId)Debe ser un correo válido aunque sendEmail sea false; en ese caso Factuplan no lo usa para notificar.
addressstringNoAparece en el RIDE.
phonestringNoFormato E.164 con código de país, por ejemplo +593958657236. Cualquier otro formato responde 400.
saveToContactsbooleanNoSi true, lo guarda en tu directorio.

Campos de cada item

CampoTipoRequeridoNotas
quantitynumberSíCantidad facturada.
productIdstringNoSi se envía, los demás campos pueden omitirse.
codestringSíIdentificador del ítem.
auxiliaryCodestringNoCódigo secundario (SKU, código de barras…).
descriptionstringSíAparece en el RIDE.
unitPricenumberSíHasta 6 decimales de precisión.
discountnumberNoDescuento por línea.
taxTypeenumSíIVA_0, IVA_RATE, NOT_TAXABLE, EXEMPT.
taxnumberNoSolo aplica con taxType=IVA_RATE: 0, 5, 8, 12, 14, 15 (default 15).
saveToProductsbooleanNoSi true, lo guarda en tu catálogo.

Campos al nivel raíz

CampoTipoRequeridoNotas
customerobjectSíDatos del receptor del comprobante.
itemsarraySíAl menos un ítem facturable.
paymentsarrayNoSi se omite, se aplica "01" (Sin utilización del sistema financiero).
emissionPointIdstringNoUUID del punto de emisión. Tiene prioridad sobre establishment/emissionPoint.
establishmentstringNoCódigo SRI (3 dígitos).
emissionPointstringNoCódigo SRI (3 dígitos).
additionalInfoobjectNoPares clave/valor que aparecen en el RIDE.
sendEmailbooleanNo (default true)Si false, Factuplan no envía el correo automático al cliente. Indispensable para integraciones whitelabel. Debe ser un booleano JSON: el texto "false" responde 400.
devReferencestringNoTu propia referencia (texto de 1 a 100 caracteres, por ejemplo tu número de pedido). Hace la emisión idempotente: si repites el request con la misma referencia y el mismo contenido, no se emite otra factura y recibes la existente con duplicate: true; con la misma referencia y otro contenido responde 409 (API_10011).

Formas de pago (payments)

Cada entrada lleva el código SRI en method, el amount y, opcionalmente, term + timeUnit. La suma de los amount debe coincidir con el total con impuestos: si difiere en más de un centavo, el API responde 400 con el código INVOICE_4014 y la factura no se crea (no llega al SRI).

CódigoDescripción
01Sin utilización del sistema financiero
15Compensación de deudas
16Tarjeta de débito
17Dinero electrónico
18Tarjeta prepago
19Tarjeta de crédito
20Otros con utilización del sistema financiero
21Endoso de títulos
Factuplan — activa tu cuenta y emite tu primera factura electrónica autorizada por el SRI.

Y entonces, ¿cómo le mando el RIDE al cliente?

Una vez que el comprobante pasa a estado COMPLETED, descarga el PDF (RIDE) y el XML desde el API y envíalo por tu propio servicio de correo (Resend, Postmark, SES, Mailgun, SendGrid, lo que uses).

1. Espera la autorización

Ventana de terminal
curl https://api-rest.factuplan.com.ec/v1/developer/receipts/$RECEIPT_ID/status \
-H "X-API-Key: $FACTUPLAN_API_KEY" \
-H "x-taxpayer-ruc: 0950194407001"

status empieza en DRAFT, avanza por los pasos del proceso (GENERATING_XML, SIGNING, SENDING_SRI, RECEIVED_SRI), llega a AUTHORIZED cuando el SRI autoriza, pasa por GENERATING_PDF (y por SENDING_EMAIL si sendEmail es true) y termina en COMPLETED cuando el RIDE ya está generado, también con sendEmail: false. Espera a COMPLETED antes de descargar el PDF: en AUTHORIZED puede no estar listo y el endpoint responde 404. Si queda en REJECTED, RETURNED o ERROR, el comprobante no llegó a autorizarse y no hay RIDE que enviar; cualquier otro estado significa que sigue en proceso. Un ERROR no siempre es definitivo: si fue un fallo de comunicación con el SRI, Factuplan lo reintenta solo más tarde y puede terminar en COMPLETED, así que no emitas otra factura sin revisarlo antes. Si recibes un evento webhook, igual confirma el estado con GET /v1/developer/receipts/{id} antes de disparar el correo.

2. Descarga el RIDE (PDF)

Ventana de terminal
curl https://api-rest.factuplan.com.ec/v1/developer/receipts/$RECEIPT_ID/pdf \
-H "X-API-Key: $FACTUPLAN_API_KEY" \
-H "x-taxpayer-ruc: 0950194407001"

Devuelve dos URLs: url (pre-firmada, expira en 5 minutos — ideal para descargarla a tu servidor y adjuntarla al correo) y previewUrl (no expira, pero no es un archivo: es la página pública de verificación de Factuplan, con su logo y su dominio. En una integración whitelabel no la enlaces desde tu panel ni la pongas en tu correo; guarda el PDF en tu propio almacenamiento). Con una API key de pruebas, el comprobante y sus archivos se borran cada hora.

Antes de adjuntarlo, abre el PDF: el RIDE que genera Factuplan lleva al pie la línea “Documento generado por Factuplan”, y si el emisor no tiene su logo cargado en la configuración del panel, sale con el logo de Factuplan en la cabecera. El logo lo resuelves subiendo el del emisor; la línea del pie no se puede quitar desde el API.

3. Descarga el XML autorizado

Ventana de terminal
curl https://api-rest.factuplan.com.ec/v1/developer/receipts/$RECEIPT_ID/xml \
-H "X-API-Key: $FACTUPLAN_API_KEY" \
-H "x-taxpayer-ruc: 0950194407001"

Misma estructura: url pre-firmada de 5 minutos + previewUrl (la misma página de verificación de Factuplan; no la pongas en tu correo). Adjunta los dos archivos, el PDF y el XML, al correo que envías desde tu dominio.

4. Manda el correo desde tu marca

Plantilla HTML con tu logo, tu dominio (facturas@tu-app.com), tu tono, tus enlaces. El cliente final recibe un solo correo, desde tu dominio y con tu marca. Factuplan desaparece del correo; lo único que conserva su nombre es la línea al pie del RIDE (ver el punto 7 del checklist).

¿Pruebas o producción? El logo aparece en ambos

Algo que confunde a los integradores nuevos: el correo con logo de Factuplan se manda igual en pruebas que en producción. No hay un “modo silencioso” automático para ak_test_*. Si emites con una API key de pruebas y sendEmail: true, tu cliente de pruebas (o tú mismo en QA) recibe el correo branded de Factuplan.

Por eso, si estás construyendo una integración whitelabel, lo más sano es dejar sendEmail: false desde el primer día, incluso en desarrollo. Así:

  • Tu QA ve el flujo exacto que va a ver el cliente en producción.
  • Nunca te queda un sendEmail: true “olvidado” cuando promueves a prod.
  • Tus pruebas con correos reales pasan por tu propio servicio de correo y descubres ahí los problemas de entregabilidad.

Casos donde sí conviene dejar sendEmail: true

No siempre el envío automático es un problema. Si tu integración:

  • Es interna (un ERP de tu empresa) y los receptores ya saben qué es Factuplan.
  • Es un MVP y aún no tienes infraestructura de correo propia.
  • Apunta a un cliente que prefiere usar el correo tal cual viene, sin personalizar.

…entonces deja sendEmail: true (o sencillamente omite el campo) y deja que Factuplan haga el envío. El esfuerzo de armar plantillas, manejar bounces, autenticar SPF/DKIM y monitorear deliverability no es trivial — si no lo necesitas para diferenciarte, no lo construyas todavía.

La pregunta clave para decidir: ¿el cliente final sabe que existe Factuplan, o crees que sería mejor que no lo supiera? Si la respuesta es la segunda, sendEmail: false es obligatorio.

Otros endpoints relacionados al flujo whitelabel

Si la idea es esconder a Factuplan, conviene revisar también:

  • GET /v1/developer/receipts/{id}/pdf — descarga el RIDE para adjuntarlo a tu correo.
  • GET /v1/developer/receipts/{id}/xml — descarga el XML autorizado.
  • GET /v1/developer/verify/{accessKey} — para consultar el estado de un comprobante por su clave de acceso sin pasar por la UI de Factuplan. Si lo emitiste con Factuplan, responde con el estado que Factuplan tiene guardado (source: "local"); para una clave que no está en Factuplan hoy responde found: false (source: "none"), aunque el SRI la tenga autorizada.
  • POST /v1/developer/sign (Modo C) — si quieres todavía más control: tú generas el XML, Factuplan solo te lo firma y tú te encargas de mandarlo al SRI por tu cuenta. Modo más complejo pero el más whitelabel posible.

Para un comparativo de qué tan flexible es el API de Factuplan frente a otros proveedores ecuatorianos, revisa Factuplan vs Dátil y la lista de los 10 mejores facturadores electrónicos de Ecuador.

Checklist rápido para una integración whitelabel limpia

  1. sendEmail: false en cada llamada a POST /v1/developer/invoices (y a POST /v1/developer/purchase-settlements, que también lo acepta). Ojo: las notas de crédito, las notas de débito y las retenciones emitidas por API no aceptan sendEmail y siempre envían al receptor el correo con la marca de Factuplan.
  2. Tu propio servicio de correo configurado (SPF, DKIM, DMARC, dominio dedicado).
  3. Plantilla HTML del correo con tu logo y tus enlaces — sin mencionar Factuplan.
  4. Webhook o polling a GET /v1/developer/receipts/{id}/status para saber cuándo está COMPLETED (autorizado por el SRI y con el RIDE ya generado); si te avisa el webhook, confirma igual el estado antes de descargar.
  5. Adjuntar siempre el PDF (RIDE) y el XML autorizado al correo. El XML lo necesita el contador del receptor.
  6. Plantilla con el botón “Verificar en el SRI” enlazando al portal oficial — refuerza la legitimidad sin depender de Factuplan.
  7. Revisar el RIDE antes de enviarlo: lleva al pie la línea “Documento generado por Factuplan” y, si el emisor no tiene logo cargado, el logo de Factuplan. Sube el logo del emisor en el panel; si tu cliente exige también quitar la línea del pie, abre conversación con el equipo de Factuplan, porque el API no tiene una opción para ocultarla.

¿Estás integrando el API y tienes una duda específica de implementación? Escríbenos a info@factuplan.com.ec o revisa la documentación completa del API REST. Si trabajas en Node.js o TypeScript, también está el SDK oficial que te ahorra cabecear con cURL.

Preguntas frecuentes

¿Qué hace exactamente sendEmail: false en el API de Factuplan?

Le indica al endpoint POST /v1/developer/invoices que NO envíe el correo automático con el RIDE al receptor. Factuplan sigue haciendo todo lo demás del Modo A (crea el XML, lo firma con tu P12, lo autoriza ante el SRI y genera el PDF), pero no dispara el correo. Tú quedas con el comprobante en COMPLETED (autorizado y con su RIDE generado) y descargas el RIDE y el XML por separado desde GET /v1/developer/receipts/{id}/pdf y /xml para mandarlos por tu propio servicio de correo.

¿Por qué es importante usar sendEmail: false en integraciones whitelabel?

Porque por defecto Factuplan envía el correo automático con su propio logo, plantilla y dominio, tanto en pruebas (ak_test_*) como en producción (ak_live_*). Si tu producto es whitelabel — un ERP, POS o SaaS vertical que vendes con tu marca — ese correo le revela al cliente final que estás usando Factuplan como infraestructura. Apagarlo con sendEmail: false te permite enviar el correo desde tu propio dominio, con tu plantilla y tu marca, sin que Factuplan aparezca en el correo. Ten presente que el RIDE en PDF conserva al pie la línea Documento generado por Factuplan.

¿El logo de Factuplan también aparece en los correos de pruebas?

Sí. No existe un modo silencioso automático para las API keys de pruebas (ak_test_*). El correo se envía con el mismo branding de Factuplan tanto en pruebas como en producción. Por eso lo recomendado para integraciones whitelabel es dejar sendEmail: false desde el primer día, incluso en desarrollo y QA — así pruebas el flujo exacto que verá el cliente en producción y nunca te queda un sendEmail: true olvidado al subir a prod.

¿Dónde va el campo sendEmail dentro del body del request?

Al nivel raíz del body, al mismo nivel que customer, items y payments. No va dentro de customer. Es un booleano opcional cuyo valor por defecto es true. Ejemplo: { 'customer': { ... }, 'items': [...], 'payments': [...], 'sendEmail': false }. Si lo omites, Factuplan asume sendEmail: true y envía el correo automático.

Si pongo sendEmail: false, ¿cómo le entrego el RIDE al cliente?

Después de que el comprobante pase a estado COMPLETED (lo confirmas con GET /v1/developer/receipts/{id}/status; en AUTHORIZED el PDF puede no estar listo todavía), descargas el PDF con GET /v1/developer/receipts/{id}/pdf y el XML con GET /v1/developer/receipts/{id}/xml. Ambos endpoints devuelven una URL pre-firmada de 5 minutos (para descargarla a tu servidor y adjuntarla) y una previewUrl que no expira pero abre la página de verificación de Factuplan, así que no la uses en una integración whitelabel. Luego mandas el correo desde tu propio servicio (Resend, Postmark, SES, Mailgun, SendGrid) con tu logo, tu dominio y los dos archivos adjuntos.

¿sendEmail: false afecta la autorización ante el SRI?

No. La autorización ante el SRI es completamente independiente del envío del correo. Factuplan sigue firmando el XML con tu certificado P12, enviándolo al SRI y obteniendo la autorización (el comprobante pasa por AUTHORIZED, recibe su authorizationNumber y termina en COMPLETED) exactamente igual que con sendEmail: true. Lo único que cambia es que el correo automático al receptor no se dispara. El comprobante queda igual de válido ante el SRI.

¿Puedo usar sendEmail: false junto con el customer.email o ya no tiene sentido?

Sí, y además debes enviarlo: customer.email es obligatorio en el body aunque sendEmail esté en false (salvo que envíes customerId de un cliente ya guardado). Si falta o no es un correo válido, el API responde 400. Con sendEmail: false Factuplan no lo usa para notificar. Conviene guardarlo también en tu propia base de datos porque es el correo al que tu sistema le va a enviar el RIDE desde tu servicio de correo.

Compartir:

¿Te sirvió este artículo? Marca a Factuplan como fuente preferida y aparecerá más en tus resultados de Google.

Añadir a fuentes preferidas
FirmaOK

¿Aún no tienes firma electrónica?

Sin ella no puedes emitir comprobantes ante el SRI. Consíguela 100% en línea.

Compra tu firma electrónica
Programa de aliados
Pantalla de inicio de firmaok.com.ec, donde se compra la firma electrónica

Sé distribuidor de firma electrónica

¿Atiendes a varios clientes? Gana una comisión por cada firma electrónica y cada plan de facturación que vendas. Sin inversión inicial ni metas mínimas.

  • Comisión por cada venta efectiva
  • Ideal para contadores, asesores y agencias
  • La firma se renueva cada 1 o 2 años: ingreso recurrente
Quiero ser distribuidor