ReceiptPrint SDK
Todo lo que necesita para imprimir recibos en dispositivos Sunmi POS desde su aplicación web.
1 Introducción
ReceiptPrint SDK es una librería JavaScript desarrollada por Tapara Dev que permite imprimir recibos térmicos en dispositivos Sunmi POS directamente desde su aplicación web. Un solo script, una sola API — sin necesidad de conocer el SDK nativo de Sunmi.
Cómo funciona
- Validación de licenciaEl script consulta los servidores de Tapara Dev para verificar que la licencia es válida y que la solicitud proviene del dominio autorizado.
- Carga del bundle cifradoSe descarga el núcleo del SDK autenticado con un token de sesión de corta duración.
- Conexión con la impresoraEl SDK establece conexión WebSocket local (
ws://localhost:7070/ws) con el servicio de impresión del dispositivo Sunmi.
2 Requisitos previos
| Requisito | Detalle |
|---|---|
| Dispositivo Sunmi | Cualquier Sunmi POS con impresora térmica integrada. |
| Servicio de impresión | El servicio Sunmi Printer Service debe estar corriendo en el dispositivo (normalmente activo por defecto). Escucha en ws://localhost:7070/ws. |
| Llave de licencia | Provista por Tapara Dev. Está ligada a su dominio de producción. Sin llave válida el SDK no carga. |
| Dominio HTTPS | Su aplicación debe servirse desde el dominio exacto registrado en la licencia. www.mitienda.com y mitienda.com son dominios diferentes. |
| Conexión a internet | Necesaria al cargar la página para la validación inicial. La impresión ocurre localmente y no requiere internet. |
localhost:7070) solo existe en dispositivos Sunmi. Desde un PC o celular no-Sunmi el SDK cargará pero init() fallará con un error de conexión.
3 Integración en 2 pasos
Paso 1 — Agregar el script al <head>
Incluya el tag en el <head> de todas las páginas que necesiten imprimir. Reemplace SU_LLAVE_AQUI con la llave entregada por Tapara Dev.
<!-- ReceiptPrint SDK --> <script src="https://sdk.taparadev.com/static/sdk/receipt-print.js?key=SU_LLAVE_AQUI"></script>
?key= debe ser la llave completa exactamente como la recibió.
Paso 2 — Inicializar y usar la API
// Inicializar (conecta con la impresora) ReceiptPrint.init("SU_LLAVE_AQUI") .then(function() { console.log("Impresora lista"); }) .catch(function(err) { console.error("Error:", err.message); }); // Imprimir un recibo ReceiptPrint.print({ header: { name: "Mi Tienda", address: "Av. Principal 123", phone: "2222-3333" }, items: [ { description: "Producto A", qty: 2, price: 1500 }, { description: "Producto B", qty: 1, price: 3000 } ], totals: { subtotal: 6000, tax: 780, total: 6780, paymentMethod: "Efectivo" }, footer: "¡Gracias por su compra!" });
4 ReceiptPrint.init()
Inicializa el SDK y establece conexión con la impresora Sunmi. Debe llamarse antes de cualquier operación de impresión. Se resuelve cuando la impresora está lista, o se rechaza si hay un error.
Parámetros
| Parámetro | Tipo | Descripción |
|---|---|---|
key requerido | string | Llave de licencia provista por Tapara Dev. |
options opcional | object | Opciones de inicialización. |
Opciones
| Opción | Tipo | Por defecto | Descripción |
|---|---|---|---|
paperWidth | number | Según licencia | Ancho del papel en mm. Valores válidos: 58 o 80. |
ReceiptPrint.init("MI_LLAVE").then(...); ReceiptPrint.init("MI_LLAVE", { paperWidth: 58 }).then(...);
init() una vez al cargar la aplicación. No es necesario llamarlo antes de cada impresión. Si ya está inicializado, la llamada retorna inmediatamente.
5 ReceiptPrint.print(receipt)
Imprime un recibo completo a partir de un objeto JSON. Todos los campos son opcionales excepto items y totals.total.
header — encabezado del negocio
| Campo | Tipo | Descripción |
|---|---|---|
header.name | string | Nombre del negocio (centrado, grande). |
header.address | string | Dirección física. |
header.phone | string | Número de teléfono. |
header.taxId | string | Cédula jurídica / RUC / NIT. |
header.extra | string | Línea adicional de encabezado. |
logo | string (URL) | Logo del negocio. PNG cuadrado, mínimo 200×200 px, fondo blanco. |
meta — metadatos del recibo
| Campo | Tipo | Descripción |
|---|---|---|
meta.number | string | Número de recibo / factura. |
meta.date | string | Fecha y hora de la venta. |
meta.cashier | string | Nombre del cajero. |
meta.customer | string | Nombre del cliente. |
items — líneas de producto requerido
| Campo | Tipo | Descripción |
|---|---|---|
items[].description | string | Nombre del producto o servicio. |
items[].qty | number | Cantidad vendida. |
items[].price | number | Precio unitario. |
totals — totales
| Campo | Tipo | Descripción |
|---|---|---|
totals.subtotal | number | Subtotal antes de impuestos. |
totals.tax | number | Monto del impuesto (IVA, IGV, etc.). |
totals.discount | number | Descuento aplicado. |
totals.tip | number | Propina. |
totals.total requerido | number | Monto total a cobrar. |
totals.paymentMethod | string | Forma de pago (ej: "Efectivo", "Tarjeta Visa"). |
totals.cashReceived | number | Efectivo recibido del cliente. |
totals.change | number | Cambio devuelto al cliente. |
QR, barcode, imagen y otros
| Campo | Tipo | Descripción |
|---|---|---|
qr | string | Contenido del código QR (URL, texto, etc.). |
qrLabel | string | Etiqueta debajo del QR. |
barcode | string | Contenido del código de barras. |
barcodeLabel | string | Etiqueta debajo del código de barras. |
image | string (URL) | Imagen adicional (ej: firma digital). |
footer | string | Mensaje de cierre. |
currency | string | Símbolo de moneda. Por defecto: ₡ |
Ejemplo completo
ReceiptPrint.print({ logo: "https://mitienda.com/logo.png", header: { name: "Supermercado Don Pepe", address: "Av. Central 45", phone: "2222-3333", taxId: "3-101-999999" }, meta: { number: "REC-00421", date: "25/04/2026 10:45", cashier: "María López" }, items: [ { description: "Arroz 1kg", qty: 2, price: 950 }, { description: "Frijoles 500g", qty: 3, price: 650 }, { description: "Aceite vegetal 1L", qty: 1, price: 1800 } ], totals: { subtotal: 5750, tax: 747, total: 6497, paymentMethod: "Efectivo", cashReceived: 7000, change: 503 }, qr: "https://mitienda.com/factura/REC-00421", footer: "¡Gracias por su preferencia!", currency: "₡" }) .then(() => console.log("Impreso ✓")) .catch(err => console.error(err.message));
6 Métodos adicionales
Imprime una sola imagen. align: "left", "center" (por defecto) o "right".
Imprime un código QR. data es el texto o URL a codificar. label es la etiqueta opcional debajo.
Imprime un código de barras. label es la etiqueta opcional debajo.
Consulta el estado de la impresora. Retorna { ok, status, message, raw }. Los valores de status: "ready" · "cover_open" · "paper_jam" · "no_paper" · "overheating" · "error".
Retorna true si el SDK ya fue inicializado. Útil para verificación sincrónica.
7 Manejo de errores
Todas las operaciones del SDK devuelven Promises. Use siempre .catch() o try/catch con async/await para capturar errores.
Errores comunes
- License invalidLa llave no existe o está inactiva. Contacte a Tapara Dev.
- License expiredLa licencia venció. Contacte a Tapara Dev para renovarla.
- Domain not allowedLa página se carga desde un dominio diferente al registrado en la licencia.
- Impresora no disponibleEl servicio Sunmi no está corriendo o
localhost:7070no está accesible. - Not initializedSe llamó a
print()antes de queinit()completara.
Patrón recomendado
async function imprimirRecibo(datos) { try { if (!ReceiptPrint.isReady()) { await ReceiptPrint.init("MI_LLAVE"); } await ReceiptPrint.print(datos); } catch (err) { alert("No se pudo imprimir: " + err.message); } }
8 Ejemplos completos
Página HTML mínima
<!DOCTYPE html><html> <head> <script src="https://sdk.taparadev.com/static/sdk/receipt-print.js?key=MI_LLAVE"></script> </head> <body> <button onclick="imprimir()">Imprimir</button> <script> ReceiptPrint.init("MI_LLAVE").catch(e => alert(e.message)); function imprimir() { ReceiptPrint.print({ header: { name: "Mi Tienda", phone: "2222-3333" }, items: [{ description: "Artículo", qty: 1, price: 1000 }], totals: { total: 1000, paymentMethod: "Efectivo" }, footer: "¡Gracias!" }).catch(e => alert(e.message)); } </script> </body></html>
Con async/await y verificación de estado
ReceiptPrint.init("MI_LLAVE") .then(() => { btnImprimir.disabled = false; }) .catch(err => mostrarError(err.message)); async function procesarVenta(venta) { const s = await ReceiptPrint.getStatus(); if (!s.ok) throw new Error("Impresora no disponible: " + s.message); await ReceiptPrint.print({ header: { name: venta.tienda }, items: venta.lineas.map(l => ({ description: l.producto, qty: l.cantidad, price: l.precio })), totals: { total: venta.total, paymentMethod: venta.metodoPago }, footer: "¡Gracias por su compra!" }); }
Solo QR o código de barras
await ReceiptPrint.printQR("https://mitienda.com/cliente/12345", "Escanee para ver sus puntos"); await ReceiptPrint.printBarcode("7501055360006", "Arroz Premium 1kg");
9 Preguntas frecuentes
¿Funciona en cualquier navegador del dispositivo Sunmi?
¿Puedo usar el SDK en localhost para desarrollo?
localhost. Solicite a Tapara Dev una licencia de desarrollo. La impresora seguirá siendo inaccesible a menos que esté en un dispositivo Sunmi.¿Qué pasa si la licencia expira?
¿El SDK envía mis datos de ventas a algún servidor?
¿Puedo cambiar el símbolo de moneda?
currency en el objeto receipt. El valor por defecto es ₡. Puede usar cualquier símbolo: "$", "€", "Q", "S/", etc.¿Cómo sé que el ancho de papel está bien configurado?
10 Soporte
Para consultas técnicas, renovación de licencias o reportar incidencias:
| Canal | Contacto |
|---|---|
| Correo electrónico | [email protected] |
| Sitio web | taparadev.com |