Integración · E-commerce

¿Cómo integrar la factura electrónica a tu ecommerce en Costa Rica?

La respuesta corta: conectás el ciclo de tu tienda a la API de Plaxp. Cuando la orden se confirma o se paga, un webhook de tu tienda dispara un POST y Plaxp emite el comprobante v4.4, lo firma con XAdES, lo transmite a Hacienda y le manda al cliente el PDF y el XML por correo. Sin plugin obligatorio: funciona con cualquier tienda a la medida (headless, Next.js, Laravel, la que sea) que pueda hacer una llamada HTTP.

¿Qué significa integrar la factura electrónica a tu ecommerce?

Es enlazar un evento de tu tienda —típicamente orden confirmada o orden pagada— con una llamada a una API que genera y transmite el comprobante electrónico a Hacienda. Vos ya sabés qué se vendió (líneas, montos, cliente); la parte fiscal (XML v4.4, firma digital, consecutivos, envío y rechazos) la resuelve la API.

Este ángulo es para tienda propia: un checkout que vos controlás, donde tenés acceso al ciclo de la orden y podés disparar la llamada en el momento exacto. Si en cambio usás una plataforma empaquetada, mirá —el patrón de fondo es el mismo, cambia dónde vive el disparador.

  • Un punto en tu backend que escucha "orden confirmada/pagada"
  • Un mapeo de cada ítem de la orden a una línea con su CABYS
  • Una regla para decidir factura (01) vs tiquete (04) según los datos del cliente
  • Una llamada POST a la API con receptor, líneas y medios de pago
  • Guardar la clave del comprobante contra la orden, para consultar el estado después

¿Por qué automatizarlo y no facturar a mano después?

Porque a la mano no escala y arriesga multas. Con volumen de órdenes, facturar después una por una se atrasa, se olvida y descuadra la contabilidad. La duda más común al integrar es ¿emito factura o tiquete, y en qué momento? La respuesta operativa: emitís en la confirmación/pago de la orden, y el tipo lo decide si el comprador se identificó o no.

Consumidor final vs. cliente identificado

Si en el checkout el comprador te dio su cédula o NITE, emitís factura electrónica (01) a su nombre; si compró sin identificarse, un tiquete electrónico (04) al consumidor final. Mismo endpoint: solo cambiás tipo_documento. Guardá siempre el correo para poder mandarle el comprobante.

¿Qué exige la normativa costarricense?

Que toda venta se respalde con un comprobante electrónico transmitido a Hacienda, y hoy en la versión 4.4 (obligatoria desde el 1 de setiembre de 2025). Cada línea lleva su código CABYS de 13 dígitos, el IVA general es del 13% (con tarifas reducidas de 4%, 2%, 1% y exentos según el bien o servicio), y hay que enviarle al receptor el PDF y el XML del comprobante.

  • Comprobante electrónico v4.4 por cada venta (obligatoria desde el 1-set-2025)
  • CABYS de 13 dígitos en cada línea; IVA general 13% (más tarifas reducidas/exentas)
  • Envío del PDF y el XML al correo del receptor
  • Consecutivo correcto por sucursal y caja (no se repiten ni saltan)

El costo de no emitir

No respaldar las ventas con comprobante electrónico expone a las sanciones del Código de Normas y Procedimientos Tributarios (arts. 83 y 86), que llegan hasta 100 salarios base y el cierre del negocio. Las fechas y cambios finos de la 4.4 están en . En lo tributario, confirmá siempre con tu contador.

¿Cómo lo resuelve Plaxp?

Tu tienda dispara un POST a /api/procesar al confirmarse la orden, y de ahí en adelante nos encargamos nosotros: armamos el XML v4.4, lo firmamos con XAdES-EPES usando tu certificado .p12, lo transmitimos a Hacienda, consultamos el estado por vos (con reintentos) y le mandamos al cliente el PDF y el XML por correo. La respuesta es HTTP 202: recibís la clave de 50 dígitos y el consecutivo al instante, mientras la firma y el envío ocurren en background.

handlers/orden-confirmada.ts
// Se ejecuta cuando TU tienda marca la orden como pagada/confirmada.
// Idempotente: usá el id de la orden para no emitir dos veces.
export async function onOrdenConfirmada(orden) {
  const res = await fetch('https://api.plaxp.com/api/procesar', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.PLAXP_API_KEY,      // nunca en el frontend
      'Idempotency-Key': orden.id,                  // evita duplicados por reintento
    },
    body: JSON.stringify({
      // Con cédula → factura (01); sin datos → tiquete (04)
      tipo_documento: orden.cliente?.cedula ? '01' : '04',
      codigo_sucursal: '001',
      codigo_caja: '001',
      consecutivo: orden.numero,
      condicion_venta: '01',                         // 01 = contado
      medios_pago: [{ tipo: '04', monto: orden.total }], // 04 = tarjeta
      receptor: orden.cliente?.cedula && {
        tipo_identificacion: '01',                   // 01 = cédula física
        identificacion: orden.cliente.cedula,
        nombre: orden.cliente.nombre,
        correo: orden.cliente.correo,                // acá le llega su comprobante
      },
      lineas: orden.items.map((it) => ({
        codigo_cabys: it.cabys,                       // guardalo por producto
        detalle: it.nombre,
        cantidad: it.cantidad,
        precio_unitario: it.precio,
        codigo_tarifa: '08',                          // 08 = IVA 13%
        tarifa: 13,
      })),
    }),
  });

  const { data } = await res.json();                 // { clave, consecutivo }
  await guardarClaveEnOrden(orden.id, data.clave);   // para consultar el estado luego
}

Plaxp no te manda webhooks de vuelta

El webhook va de tu tienda hacia la API (para disparar la emisión), no al revés. Para saber si Hacienda aceptó o rechazó, consultás por la clave con GET /api/consultar/:clave: nosotros hacemos el polling contra Hacienda por vos. El detalle de webhook vs. consulta está en .

Consecutivos correctos y sin duplicados

La API lleva el consecutivo por caja (podés leerlo con GET /api/caja/:cajaId/consecutivos), así que la secuencia no se rompe aunque tu tienda reintente el webhook. Sumale la Idempotency-Key del ejemplo y un reintento de red no te genera dos comprobantes.

Ejemplo: una tienda tica de ropa que vende en línea

Tu tienda propia (pongamos, un checkout en Next.js) recibe una orden: 2 camisetas a ₡12.500 cada una. La base es ₡25.000, el IVA al 13% son ₡3.250 y el total ₡28.250. Al marcarse pagada la orden, tu handler dispara la llamada:

ejemplo-tico.json
{
  "tipo_documento": "04",            // sin cédula → tiquete al consumidor final
  "codigo_sucursal": "001",
  "codigo_caja": "001",
  "consecutivo": 1043,
  "condicion_venta": "01",
  "medios_pago": [{ "tipo": "04", "monto": 28250 }],
  "lineas": [{
    "codigo_cabys": "1411100000000",   // camiseta de algodón (ejemplo)
    "detalle": "Camiseta algodón",
    "cantidad": 2,
    "precio_unitario": 12500,
    "codigo_tarifa": "08",             // 08 = IVA 13%
    "tarifa": 13
  }]
}

Si esa misma clienta hubiera puesto su cédula en el checkout, cambiás tipo_documento a "01", agregás el bloque receptor con su nombre y correo, y sale factura electrónica a su nombre. En ambos casos ella recibe el PDF y el XML por correo, y vos guardás la clave contra la orden. Confirmá el CABYS real de tus productos con tu contador —usar uno inexistente es de los rechazos más comunes, catalogado en .

¿Por dónde arranco?

Por la : ahí están los tipos de comprobante, la autenticación (API Key u OAuth) y los ejemplos en varios lenguajes. Antes de emitir en real, integrá contra la . Y si tu tienda corre sobre WooCommerce o Shopify en vez de un checkout propio, el atajo es .

¿Querés facturar automático desde tu tienda en línea?

Te damos credenciales de sandbox y te acompañamos en la integración. Escribinos y arrancamos hoy.

Solicitar acceso a la API

Te acompañamos en la puesta en marcha · soporte rápido de gente real · fácil de usar para todo tu equipo. Somos gente ayudando gente.