El sistema de ventas Sublime POS 4 utiliza el plugin HTTP a ESC POS para imprimir el ticket de venta y el ticket de corte de caja.

Como bien sabes, el plugin imprime mis créditos que se pueden remover con una licencia mensual, pero siempre hay clientes que, con justa razón, quieren hacer un pago único para poder imprimir sin mis créditos pero sin pagar mensualmente.

No puedo darles el plugin ilimitado, ya que el plugin no solo sirve para imprimir en SPOS4; sirve para que cualquiera pueda imprimir desde cualquier lenguaje de programación, así que simplemente no puedo arriesgarme a dejar expuesta la herramienta.

Por lo que la solución es crear un plugin especial que ya no va a recibir una lista de operaciones ilimitada e infinita, sino un JSON que representa un recibo de venta o un corte de caja, y a partir de ello crear el recibo hardcodeado de modo que incluso si envían cualquier otro JSON el mismo será ignorado.

Modo de uso de impresión Android

Una vez que cuentes con la aplicación debes hacer algunas pruebas básicas e ir paso por paso para que, si encuentras un error, lo puedas informar.

Instala la aplicación y obliga a instalarla si Google Play Protect o cosas similares te preguntan. En mi caso elegí Instalar sin analizar:

La aplicación te va a pedir permiso Bluetooth:

A partir de Android 13 también te va a pedir permiso para mostrar notificaciones:

Una vez que hayas dado los permisos se va a comenzar con el escaneo. Enciende tu Bluetooth, enciende tu impresora y espera a que aparezca. Si no aparece entonces vuelve a escanear haciendo clic en Buscar Dispositivos.

En mi caso la impresora es la MTP-II así que hago clic en Probar y después de un momento dice Impreso correctamente como se aprecia en la siguiente captura de pantalla:

Se ha impreso un ticket que contiene el nombre de la impresora y la versión de Android desde donde fue impresa:

El dispositivo que he usado tiene Android 16 como se ve en la siguiente captura:

Después de que se haya impreso el ticket asegúrate de que tienes una notificación permanente indicando que el plugin está en segundo plano. Esta notificación debe aparecer siempre, sin importar si haces o no clic en Probar.

He hecho esta misma prueba en Android 12 y 13 y funciona perfectamente, por lo que al menos hasta el momento está probada en Android 12, 13 y 16. Obviamente en teoría debe funcionar desde Android 7 en adelante pues el minSdk de mi app es 24.

Probado en Android 12:

Android 13:

Para Android 16 ya mostré la captura previamente.

Una vez que ya imprimió un ticket con el nombre de la impresora y versión de Android entonces ya puede ser usado normalmente por Sublime POS 4.

No olvides que la notificación del servicio siempre debe estar activa. Si no aparece entonces no vas a poder imprimir

JSON de prueba

Para la venta he usado lo siguiente. Estos son valores hardcodeados pero que se generan de acuerdo a la moneda y configuración del sistema.


{
    "venta": {
        "pagos": [
            {
                "fechaFormateada": "5/08/2025, 10:53:35 a. m.",
                "cambioFormateado": "Q 4,377.00",
                "pagos": [
                    {
                        "pagoFormateado": "Q 1,623.00",
                        "id": 7,
                        "idPagoVenta": 7,
                        "idMetodoPago": 1,
                        "pago": 1623,
                        "nombreMetodoPago": "Efectivo"
                    }
                ],
                "id": 7,
                "fecha": "2025-08-05T10:53:35",
                "usuario": {
                    "id": 1,
                    "nombre": "parzibyte"
                },
                "cambio": 4377
            }
        ],
        "cantidadArticulosFormateada": "3",
        "cantidadServiciosFormateada": "0",
        "cantidadPaquetesFormateada": "0",
        "pagadoFormateado": "Q 1,623.00",
        "cambioORestanteFormateado": "Q 0.00",
        "etiquetaCambioORestante": "Saldo pendiente",
        "productosVendidos": [
            {
                "precioFormateado": "Q 23.00",
                "subtotalFormateado": "Q 23.00",
                "cantidadFormateada": "1",
                "idProducto": 3,
                "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                "codigo": "7501030418399",
                "informacionAdicional": "",
                "cantidadVendida": 1,
                "precio": 23,
                "porcentajeDescuento": 0,
                "categoriaProducto": "General",
                "nota": ""
            },
            {
                "precioFormateado": "Q 800.00",
                "subtotalFormateado": "Q 800.00",
                "cantidadFormateada": "1",
                "idProducto": 92,
                "descripcion": "Super Mario Party",
                "codigo": "04549659430",
                "informacionAdicional": "",
                "cantidadVendida": 1,
                "precio": 800,
                "porcentajeDescuento": 0,
                "categoriaProducto": "General",
                "nota": ""
            },
            {
                "precioFormateado": "Q 800.00",
                "subtotalFormateado": "Q 800.00",
                "cantidadFormateada": "1",
                "idProducto": 101,
                "descripcion": "Amiibo K. Rool",
                "codigo": "045496594121",
                "informacionAdicional": "",
                "cantidadVendida": 1,
                "precio": 800,
                "porcentajeDescuento": 0,
                "categoriaProducto": "General",
                "nota": ""
            }
        ],
        "serviciosVendidos": [],
        "paquetesVendidos": [],
        "totalFormateado": "Q 1,623.00",
        "fechaFormateada": "5/08/2025, 10:53:35 a. m.",
        "tipoVentaJson": "{\"id\":1,\"nombre\":\"Contado\",\"pagosMaximos\":1,\"porcentajePagoParaAprobar\":100.0,\"porcentajePagoParaDescontarProductos\":100.0}",
        "sucursalJson": "{\"id\":1,\"nombre\":\"Principal\"}",
        "clienteJson": "{\"nombre\":\"Mostrador\",\"informacionAdicional\":\"\"}",
        "usuarioJson": "{\"nombre\":\"parzibyte\"}",
        "pagosComoJson": "[{\"id\":7,\"fecha\":\"2025-08-05T10:53:35\",\"usuario\":{\"id\":1,\"nombre\":\"parzibyte\"},\"cambio\":4377.0,\"pagos\":[{\"id\":7,\"idPagoVenta\":7,\"idMetodoPago\":1,\"pago\":1623.0,\"nombreMetodoPago\":\"Efectivo\"}]}]",
        "productosVendidosComoJson": "[{\"idProducto\":3,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"codigo\":\"7501030418399\",\"informacionAdicional\":\"\",\"cantidadVendida\":1.0,\"precio\":23.0,\"porcentajeDescuento\":0.0,\"categoriaProducto\":\"General\",\"nota\":\"\"},{\"idProducto\":92,\"descripcion\":\"Super Mario Party\",\"codigo\":\"04549659430\",\"informacionAdicional\":\"\",\"cantidadVendida\":1.0,\"precio\":800.0,\"porcentajeDescuento\":0.0,\"categoriaProducto\":\"General\",\"nota\":\"\"},{\"idProducto\":101,\"descripcion\":\"Amiibo K. Rool\",\"codigo\":\"045496594121\",\"informacionAdicional\":\"\",\"cantidadVendida\":1.0,\"precio\":800.0,\"porcentajeDescuento\":0.0,\"categoriaProducto\":\"General\",\"nota\":\"\"}]",
        "serviciosComoJson": "[]",
        "paquetesComoJson": "[]",
        "pagado": 1623,
        "total": 1623,
        "id": 12,
        "fecha": "2025-08-05T10:53:35",
        "estado": 1,
        "cliente": {
            "nombre": "Mostrador",
            "informacionAdicional": ""
        },
        "sucursal": {
            "id": 1,
            "nombre": "Principal"
        },
        "tipoVenta": {
            "id": 1,
            "nombre": "Contado",
            "pagosMaximos": 1,
            "porcentajePagoParaAprobar": 100,
            "porcentajePagoParaDescontarProductos": 100
        },
        "usuario": {
            "nombre": "parzibyte"
        }
    },
    "ajustes": {
        "modoImpresion": 2,
        "nombreImpresora": "PT",
        "macImpresoraAndroid": "FF:FF:FF:FF:FF:FF",
        "encabezadoTicket": "Mi tienda\nTeléfono: 1234567\nUbicación: bla bla",
        "pieTicket": "Gracias por su compra\nCon varias\nlíneas",
        "altoTicket": 297,
        "anchoTicket": 250,
        "margenIzquierdoTicket": 0,
        "margenDerechoTicket": 0,
        "licenciaPluginAndroid": "",
        "licenciaPluginDesktop": "",
        "licenciaPluginPdf": "",
        "licenciaSistema": "",
        "logotipoEnBase64": "",
        "venderConCodigoDeBarras": 1,
        "venderConAutocompletado": 1,
        "venderConCamara": 0,
        "registrarConCamara": 0,
        "tokenTelegram": "",
        "idChatTelegram": "",
        "permitirVenderCantidadesNegativas": 0,
        "idiomaSistema": "es",
        "idiomaFormatos": "es-GT",
        "moneda": "GTQ"
    }
}

Y aquí el de caja:



{
    "corte": {
        "id": 1,
        "idSucursal": 1,
        "cantidadFisica": 2000,
        "nota": "Soy la adicional",
        "fecha": "2026-03-22T17:58:03",
        "fechaCorteAnterior": "",
        "usuarioComoJson": "{\"id\":1,\"nombre\":\"parzibyte\"}",
        "sucursalComoJson": "{\"id\":1,\"nombre\":\"Principal\"}",
        "pagosAgrupadosPorMetodoDePagoComoJson": "[{\"nombre\":\"Efectivo\",\"total\":7167.75},{\"nombre\":\"Tarjeta crédito\",\"total\":68.75}]",
        "serviciosVendidosAgrupadosComoJson": "[{\"cantidad\":3.5,\"descripcion\":\"Reparación Nintendo Switch\",\"subtotal\":115.5}]",
        "paquetesVendidosAgrupadosComoJson": "[{\"cantidad\":11.0,\"descripcion\":\"eas\",\"subtotal\":1353.0}]",
        "productosVendidosAgrupadosComoJson": "[{\"cantidad\":32.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":736.0},{\"cantidad\":6.0,\"descripcion\":\"Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB\",\"subtotal\":600.0},{\"cantidad\":7.0,\"descripcion\":\"Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito\",\"subtotal\":35.0},{\"cantidad\":3.0,\"descripcion\":\"Desodorante Gel Mujer Secret Vainilla 45 grs\",\"subtotal\":240.0},{\"cantidad\":4.0,\"descripcion\":\"Sal Yodada Fluorurada - Great Value\",\"subtotal\":120.0},{\"cantidad\":1.0,\"descripcion\":\"Super Mario Party\",\"subtotal\":800.0},{\"cantidad\":4.0,\"descripcion\":\"Amiibo K. Rool\",\"subtotal\":3200.0}]",
        "productosEntregadosPorTipoDeVentaComoJson": "[{\"tipoVenta\":\"Contado\",\"productos\":[{\"cantidad\":8.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":184.0},{\"cantidad\":6.0,\"descripcion\":\"Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB\",\"subtotal\":600.0},{\"cantidad\":7.0,\"descripcion\":\"Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito\",\"subtotal\":35.0},{\"cantidad\":3.0,\"descripcion\":\"Desodorante Gel Mujer Secret Vainilla 45 grs\",\"subtotal\":240.0},{\"cantidad\":4.0,\"descripcion\":\"Sal Yodada Fluorurada - Great Value\",\"subtotal\":120.0},{\"cantidad\":1.0,\"descripcion\":\"Super Mario Party\",\"subtotal\":800.0},{\"cantidad\":4.0,\"descripcion\":\"Amiibo K. Rool\",\"subtotal\":3200.0}]},{\"tipoVenta\":\"Fiado\",\"productos\":[{\"cantidad\":10.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":230.0}]},{\"tipoVenta\":\"Crédito\",\"productos\":[{\"cantidad\":11.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":253.0}]},{\"tipoVenta\":\"Crédito 2\",\"productos\":[{\"cantidad\":2.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":46.0}]},{\"tipoVenta\":\"Apartado\",\"productos\":[{\"cantidad\":1.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":23.0}]}]",
        "utilidadProductosPorTipoVentaComoJson": "[{\"tipoVenta\":\"Apartado\",\"utilidad\":3.0},{\"tipoVenta\":\"Contado\",\"utilidad\":1675.0},{\"tipoVenta\":\"Crédito\",\"utilidad\":33.0},{\"tipoVenta\":\"Crédito 2\",\"utilidad\":6.0},{\"tipoVenta\":\"Fiado\",\"utilidad\":27.0}]",
        "utilidadTotalAgrupadaPorTipoVentaComoJson": "[{\"tipoVenta\":\"Contado\",\"utilidad\":1675.0},{\"tipoVenta\":\"Fiado\",\"utilidad\":27.0},{\"tipoVenta\":\"Crédito\",\"utilidad\":1334.5},{\"tipoVenta\":\"Crédito 2\",\"utilidad\":6.0},{\"tipoVenta\":\"Apartado\",\"utilidad\":3.0}]",
        "utilidadPaquetesPorTipoVentaComoJson": "[{\"tipoVenta\":\"Crédito\",\"utilidad\":1221.0}]",
        "utilidadGeneralComoJson": "{\"productos\":1744.0,\"paquetes\":1221.0,\"servicios\":80.5}",
        "utilidadServiciosPorTipoVentaComoJson": "[{\"tipoVenta\":\"Crédito\",\"utilidad\":80.5}]",
        "productosVendidosPorCategoriaComoJson": "[{\"cantidad\":57.0,\"descripcion\":\"General\",\"subtotal\":5731.0}]",
        "ingresosAdicionalesComoJson": "[]",
        "gastosComoJson": "[]",
        "productosCompradosComoJson": "[{\"cantidad\":112.0,\"descripcion\":\"Donitas Espolvoreadas Bimbo 140 gr\",\"subtotal\":2240.0},{\"cantidad\":10.0,\"descripcion\":\"Super Mario Party\",\"subtotal\":6000.0},{\"cantidad\":16.0,\"descripcion\":\"Amiibo K. Rool\",\"subtotal\":8800.0}]",
        "totalPagosVentas": 7236.5,
        "totalIngresosAdicionales": 0,
        "totalGastos": 0,
        "totalCompras": 13740,
        "pagosAgrupadosPorMetodoDePago": [
            {
                "nombre": "Efectivo",
                "total": 7167.75
            },
            {
                "nombre": "Tarjeta crédito",
                "total": 68.75
            }
        ],
        "paquetesVendidosAgrupados": [
            {
                "cantidad": 11,
                "descripcion": "eas",
                "subtotal": 1353
            }
        ],
        "productosVendidosAgrupados": [
            {
                "cantidad": 32,
                "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                "subtotal": 736
            },
            {
                "cantidad": 6,
                "descripcion": "Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB",
                "subtotal": 600
            },
            {
                "cantidad": 7,
                "descripcion": "Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito",
                "subtotal": 35
            },
            {
                "cantidad": 3,
                "descripcion": "Desodorante Gel Mujer Secret Vainilla 45 grs",
                "subtotal": 240
            },
            {
                "cantidad": 4,
                "descripcion": "Sal Yodada Fluorurada - Great Value",
                "subtotal": 120
            },
            {
                "cantidad": 1,
                "descripcion": "Super Mario Party",
                "subtotal": 800
            },
            {
                "cantidad": 4,
                "descripcion": "Amiibo K. Rool",
                "subtotal": 3200
            }
        ],
        "productosVendidosPorCategoria": [
            {
                "cantidad": 57,
                "descripcion": "General",
                "subtotal": 5731
            }
        ],
        "serviciosVendidosAgrupados": [
            {
                "cantidad": 3.5,
                "descripcion": "Reparación Nintendo Switch",
                "subtotal": 115.5
            }
        ],
        "sucursal": {
            "id": 1,
            "nombre": "Principal"
        },
        "ingresosAdicionales": [],
        "gastos": [],
        "productosComprados": [
            {
                "cantidad": 112,
                "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                "subtotal": 2240
            },
            {
                "cantidad": 10,
                "descripcion": "Super Mario Party",
                "subtotal": 6000
            },
            {
                "cantidad": 16,
                "descripcion": "Amiibo K. Rool",
                "subtotal": 8800
            }
        ],
        "productosEntregadosPorTipoDeVenta": [
            {
                "tipoVenta": "Contado",
                "productos": [
                    {
                        "cantidad": 8,
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "subtotal": 184
                    },
                    {
                        "cantidad": 6,
                        "descripcion": "Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB",
                        "subtotal": 600
                    },
                    {
                        "cantidad": 7,
                        "descripcion": "Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito",
                        "subtotal": 35
                    },
                    {
                        "cantidad": 3,
                        "descripcion": "Desodorante Gel Mujer Secret Vainilla 45 grs",
                        "subtotal": 240
                    },
                    {
                        "cantidad": 4,
                        "descripcion": "Sal Yodada Fluorurada - Great Value",
                        "subtotal": 120
                    },
                    {
                        "cantidad": 1,
                        "descripcion": "Super Mario Party",
                        "subtotal": 800
                    },
                    {
                        "cantidad": 4,
                        "descripcion": "Amiibo K. Rool",
                        "subtotal": 3200
                    }
                ]
            },
            {
                "tipoVenta": "Fiado",
                "productos": [
                    {
                        "cantidad": 10,
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "subtotal": 230
                    }
                ]
            },
            {
                "tipoVenta": "Crédito",
                "productos": [
                    {
                        "cantidad": 11,
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "subtotal": 253
                    }
                ]
            },
            {
                "tipoVenta": "Crédito 2",
                "productos": [
                    {
                        "cantidad": 2,
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "subtotal": 46
                    }
                ]
            },
            {
                "tipoVenta": "Apartado",
                "productos": [
                    {
                        "cantidad": 1,
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "subtotal": 23
                    }
                ]
            }
        ],
        "utilidadProductosPorTipoVenta": [
            {
                "tipoVenta": "Apartado",
                "utilidad": 3
            },
            {
                "tipoVenta": "Contado",
                "utilidad": 1675
            },
            {
                "tipoVenta": "Crédito",
                "utilidad": 33
            },
            {
                "tipoVenta": "Crédito 2",
                "utilidad": 6
            },
            {
                "tipoVenta": "Fiado",
                "utilidad": 27
            }
        ],
        "utilidadPaquetesPorTipoVenta": [
            {
                "tipoVenta": "Crédito",
                "utilidad": 1221
            }
        ],
        "utilidadServiciosPorTipoVenta": [
            {
                "tipoVenta": "Crédito",
                "utilidad": 80.5
            }
        ],
        "utilidadGeneral": {
            "productos": 1744,
            "paquetes": 1221,
            "servicios": 80.5
        },
        "utilidadTotalAgrupadaPorTipoVenta": [
            {
                "tipoVenta": "Contado",
                "utilidad": 1675
            },
            {
                "tipoVenta": "Fiado",
                "utilidad": 27
            },
            {
                "tipoVenta": "Crédito",
                "utilidad": 1334.5
            },
            {
                "tipoVenta": "Crédito 2",
                "utilidad": 6
            },
            {
                "tipoVenta": "Apartado",
                "utilidad": 3
            }
        ],
        "usuario": {
            "id": 1,
            "nombre": "parzibyte"
        },
        "granTotalFormateado": "-Q 6,503.50",
        "diferenciaFormateada": "Q 8,503.50",
        "totalDetallePagosFormateado": "Q 7,236.50",
        "cantidadProductosCompradosFormateada": "138",
        "totalProductosCompradosFormateado": "Q 17,040.00",
        "cantidadIngresosAdicionalesFormateado": "0",
        "totalProductosEntregadosPorCategoria": "Q 5,731.00",
        "cantidadProductosEntregadosPorCategoria": "57",
        "totalServiciosFormateado": "Q 115.50",
        "cantidadServiciosFormateada": "3.5",
        "totalProductosFormateado": "Q 5,731.00",
        "cantidadProductosFormateada": "57",
        "totalPaquetesFormateado": "Q 1,353.00",
        "cantidadPaquetesFormateada": "11",
        "subtotalDeUtilidadesPaquetesParaReporteFormateado": "Q 1,221.00",
        "subtotalDeUtilidadesServiciosParaReporteFormateado": "Q 80.50",
        "subtotalDeUtilidadesProductosParaReporteFormateado": "Q 1,744.00",
        "utilidadTotalDeUtilidadesAgrupadasPorTipoDeVentaFormateada": "Q 3,045.50",
        "fechaFormateada": "22/03/2026, 5:58:03 p. m.",
        "fechaCorteAnteriorFormateada": "",
        "fechaYHoraActualFormateada": "26/03/2026, 3:51:37 p. m.",
        "cantidadFisicaFormateada": "Q 2,000.00",
        "totalPagosVentasFormateado": "Q 7,236.50",
        "totalIngresosAdicionalesFormateado": "Q 0.00",
        "totalGastosFormateado": "Q 0.00",
        "totalComprasFormateado": "Q 13,740.00",
        "utilidadGeneralFormateada": {
            "servicios": "Q 80.50",
            "paquetes": "Q 1,221.00",
            "productos": "Q 1,744.00"
        },
        "pagosAgrupadosPorMetodoDePagoFormateados": [
            {
                "nombre": "Efectivo",
                "total": "Q 7,167.75"
            },
            {
                "nombre": "Tarjeta crédito",
                "total": "Q 68.75"
            }
        ],
        "productosVendidosAgrupadosFormateados": [
            {
                "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                "cantidad": "32",
                "subtotal": "Q 736.00"
            },
            {
                "descripcion": "Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB",
                "cantidad": "6",
                "subtotal": "Q 600.00"
            },
            {
                "descripcion": "Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito",
                "cantidad": "7",
                "subtotal": "Q 35.00"
            },
            {
                "descripcion": "Desodorante Gel Mujer Secret Vainilla 45 grs",
                "cantidad": "3",
                "subtotal": "Q 240.00"
            },
            {
                "descripcion": "Sal Yodada Fluorurada - Great Value",
                "cantidad": "4",
                "subtotal": "Q 120.00"
            },
            {
                "descripcion": "Super Mario Party",
                "cantidad": "1",
                "subtotal": "Q 800.00"
            },
            {
                "descripcion": "Amiibo K. Rool",
                "cantidad": "4",
                "subtotal": "Q 3,200.00"
            }
        ],
        "serviciosVendidosAgrupadosFormateados": [
            {
                "descripcion": "Reparación Nintendo Switch",
                "cantidad": "3.5",
                "subtotal": "Q 115.50"
            }
        ],
        "paquetesVendidosAgrupadosFormateados": [
            {
                "descripcion": "eas",
                "cantidad": "11",
                "subtotal": "Q 1,353.00"
            }
        ],
        "productosVendidosPorCategoriaFormateados": [
            {
                "descripcion": "General",
                "cantidad": "57",
                "subtotal": "Q 5,731.00"
            }
        ],
        "ingresosAdicionalesFormateados": [],
        "gastosFormateados": [],
        "productosCompradosFormateados": [
            {
                "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                "cantidad": "112",
                "subtotal": "Q 2,240.00"
            },
            {
                "descripcion": "Super Mario Party",
                "cantidad": "10",
                "subtotal": "Q 6,000.00"
            },
            {
                "descripcion": "Amiibo K. Rool",
                "cantidad": "16",
                "subtotal": "Q 8,800.00"
            }
        ],
        "utilidadProductosPorTipoVentaFormateada": [
            {
                "tipoVenta": "Apartado",
                "utilidad": "Q 3.00"
            },
            {
                "tipoVenta": "Contado",
                "utilidad": "Q 1,675.00"
            },
            {
                "tipoVenta": "Crédito",
                "utilidad": "Q 33.00"
            },
            {
                "tipoVenta": "Crédito 2",
                "utilidad": "Q 6.00"
            },
            {
                "tipoVenta": "Fiado",
                "utilidad": "Q 27.00"
            }
        ],
        "utilidadServiciosPorTipoVentaFormateada": [
            {
                "tipoVenta": "Crédito",
                "utilidad": "Q 80.50"
            }
        ],
        "utilidadPaquetesPorTipoVentaFormateada": [
            {
                "tipoVenta": "Crédito",
                "utilidad": "Q 1,221.00"
            }
        ],
        "utilidadTotalAgrupadaPorTipoVentaFormateada": [
            {
                "tipoVenta": "Contado",
                "utilidad": "Q 1,675.00"
            },
            {
                "tipoVenta": "Fiado",
                "utilidad": "Q 27.00"
            },
            {
                "tipoVenta": "Crédito",
                "utilidad": "Q 1,334.50"
            },
            {
                "tipoVenta": "Crédito 2",
                "utilidad": "Q 6.00"
            },
            {
                "tipoVenta": "Apartado",
                "utilidad": "Q 3.00"
            }
        ],
        "productosEntregadosPorTipoDeVentaFormateados": [
            {
                "tipoVenta": "Contado",
                "subtotal": "Q 5,179.00",
                "cantidad": "33",
                "productos": [
                    {
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "cantidad": "8",
                        "subtotal": "Q 184.00"
                    },
                    {
                        "descripcion": "Micrófono Dinámico Unidireccional Steren Rojo MIC-100RB",
                        "cantidad": "6",
                        "subtotal": "Q 600.00"
                    },
                    {
                        "descripcion": "Sobre p/Documento Plástico Horizontal c/Hilo Colores Trasluz Carta Barrilito",
                        "cantidad": "7",
                        "subtotal": "Q 35.00"
                    },
                    {
                        "descripcion": "Desodorante Gel Mujer Secret Vainilla 45 grs",
                        "cantidad": "3",
                        "subtotal": "Q 240.00"
                    },
                    {
                        "descripcion": "Sal Yodada Fluorurada - Great Value",
                        "cantidad": "4",
                        "subtotal": "Q 120.00"
                    },
                    {
                        "descripcion": "Super Mario Party",
                        "cantidad": "1",
                        "subtotal": "Q 800.00"
                    },
                    {
                        "descripcion": "Amiibo K. Rool",
                        "cantidad": "4",
                        "subtotal": "Q 3,200.00"
                    }
                ]
            },
            {
                "tipoVenta": "Fiado",
                "subtotal": "Q 230.00",
                "cantidad": "10",
                "productos": [
                    {
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "cantidad": "10",
                        "subtotal": "Q 230.00"
                    }
                ]
            },
            {
                "tipoVenta": "Crédito",
                "subtotal": "Q 253.00",
                "cantidad": "11",
                "productos": [
                    {
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "cantidad": "11",
                        "subtotal": "Q 253.00"
                    }
                ]
            },
            {
                "tipoVenta": "Crédito 2",
                "subtotal": "Q 46.00",
                "cantidad": "2",
                "productos": [
                    {
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "cantidad": "2",
                        "subtotal": "Q 46.00"
                    }
                ]
            },
            {
                "tipoVenta": "Apartado",
                "subtotal": "Q 23.00",
                "cantidad": "1",
                "productos": [
                    {
                        "descripcion": "Donitas Espolvoreadas Bimbo 140 gr",
                        "cantidad": "1",
                        "subtotal": "Q 23.00"
                    }
                ]
            }
        ]
    },
    "ajustes": {
        "modoImpresion": 2,
        "nombreImpresora": "PT",
        "macImpresoraAndroid": "FF:FF:FF:FF:FF:FF",
        "encabezadoTicket": "Mi tienda\nTeléfono: 1234567\nUbicación: bla bla",
        "pieTicket": "Gracias por su compra\nCon varias\nlíneas",
        "altoTicket": 297,
        "anchoTicket": 250,
        "margenIzquierdoTicket": 0,
        "margenDerechoTicket": 0,
        "licenciaPluginAndroid": "",
        "licenciaPluginDesktop": "",
        "licenciaPluginPdf": "",
        "licenciaSistema": "",
        "logotipoEnBase64": "",
        "venderConCodigoDeBarras": 1,
        "venderConAutocompletado": 1,
        "venderConCamara": 0,
        "registrarConCamara": 0,
        "tokenTelegram": "",
        "idChatTelegram": "",
        "permitirVenderCantidadesNegativas": 0,
        "idiomaSistema": "es",
        "idiomaFormatos": "es-GT",
        "moneda": "GTQ"
    }
}

No todos los valores son usados, pero es lo que envío para pruebas.

Programando plugins

No considero que sea una mala práctica el enviar los valores ya formateados, pues el sistema fue pensado desde el inicio para ejecutar absolutamente todo del lado del cliente, y el plugin de impresión solo hace eso: imprimir, no formatear ni calcular totales.

Luego hice que los 2 plugins personalizados devolvieran la lista de impresoras, una versión del plugin falsa junto con su plataforma y que respondieran solo a 2 rutas POST: la ruta /caja y la ruta /venta.

También tuve que hacer que respondieran con el booleano ok y la cadena message pues así responden los plugins originales.

Finalmente para probar usamos:

curl --json @caja.json http://localhost:8000/caja
curl --json @venta.json http://localhost:8000/venta

La impresora se toma de los ajustes. Solo para dar una pequeña prueba, aquí el código que uso para enviar a imprimir:


async function imprimirTicketDeVenta(id: number, traductor: any): Promise<{ ok: boolean, mensaje: string }> {
        const detalleVenta = await dbStore.wasm(id, "obtenerVentaParaTicket");
        if (!detalleVenta.ok) {
            return {
                mensaje: detalleVenta.datos,
                ok: false,
            }
        }
        const venta: VentaParaReporte = detalleVenta.datos;
        const detalleAjustes = await dbStore.wasm({}, "obtenerAjustes");
        if (!detalleAjustes.ok) {
            return {
                mensaje: detalleAjustes.datos,
                ok: false,
            }
        }
        const ajustes = detalleAjustes.datos;
        let [total, restante, pagado, cantidadArticulos, cantidadPaquetes, cantidadServicios] = totalRestantePagadoYCantidadArticulosPaquetesYServicios(venta);
        const { cambioORestante, etiquetaCambioORestante } = obtenerEtiquetaYCambioORestante(restante, traductor);
        const ventaConFormato: VentaParaReporteConFormato = Object.assign({
            pagos: [],
            cantidadArticulosFormateada: filtersStore.numero(cantidadArticulos),
            cantidadServiciosFormateada: filtersStore.numero(cantidadServicios),
            cantidadPaquetesFormateada: filtersStore.numero(cantidadPaquetes),
            pagadoFormateado: filtersStore.dinero(pagado),
            cambioORestanteFormateado: filtersStore.dinero(cambioORestante),
            etiquetaCambioORestante,
            productosVendidos: [],
            serviciosVendidos: [],
            paquetesVendidos: [],
            totalFormateado: filtersStore.dinero(total),
            fechaFormateada: filtersStore.fecha(venta.fecha)
        }, venta);
        ventaConFormato.pagos = venta.pagos.map((pago: PagoVentaConMetodosDePago) => {
            const pagoConFormatos: PagoVentaConMetodosDePagoFormateados = Object.assign({
                fechaFormateada: filtersStore.fecha(pago.fecha),
                cambioFormateado: filtersStore.dinero(pago.cambio),
                pagos: [],
            }, pago);
            pagoConFormatos.pagos = pago.pagos.map((pagoConMetodo: PagoVentaPorMetodo) => {
                return Object.assign({
                    pagoFormateado: filtersStore.dinero(pagoConMetodo.pago),
                }, pagoConMetodo)
            })
            return pagoConFormatos;
        })
        ventaConFormato.productosVendidos = venta.productosVendidos.map(productoVendido => {
            const subtotal = calcularTotalIndividualDeProducto(productoVendido.precio, productoVendido.porcentajeDescuento, productoVendido.cantidadVendida)
            return Object.assign({
                precioFormateado: filtersStore.dinero(productoVendido.precio),
                subtotalFormateado: filtersStore.dinero(subtotal),
                cantidadFormateada: filtersStore.numero(productoVendido.cantidadVendida),
            }, productoVendido);
        })
        ventaConFormato.paquetesVendidos = venta.paquetesVendidos.map(paqueteVendido => {
            const subtotal = calcularTotalIndividualDePaquete(paqueteVendido.precio, paqueteVendido.porcentajeDescuento, paqueteVendido.cantidadVendida)
            return Object.assign({
                precioFormateado: filtersStore.dinero(paqueteVendido.precio),
                subtotalFormateado: filtersStore.dinero(subtotal),
                cantidadFormateada: filtersStore.numero(paqueteVendido.cantidadVendida),
            }, paqueteVendido);
        })
        ventaConFormato.serviciosVendidos = venta.serviciosVendidos.map(servicioVendido => {
            const subtotal = calcularTotalIndividualDeServicio(servicioVendido.precioServicio, servicioVendido.porcentajeDescuento, servicioVendido.cantidadVendida);
            return Object.assign({
                precioFormateado: filtersStore.dinero(servicioVendido.precioServicio),
                subtotalFormateado: filtersStore.dinero(subtotal),
                cantidadFormateada: filtersStore.numero(servicioVendido.cantidadVendida),
            }, servicioVendido);
        })
        try {
            const respuestaHttp = await fetch("http://localhost:8000/venta", {
                method: "POST",
                body: JSON.stringify({ venta: ventaConFormato, ajustes })
            })
            const respuestaDecodificada = await respuestaHttp.json();
            return {
                ok: respuestaDecodificada.ok,
                mensaje: respuestaDecodificada.message,
            }
        } catch (e: any) {
            return { ok: false, mensaje: "Error comunicando con plugin: " + e.message }
        }
    }

Cabe aclarar que ya no sé si estas herramientas pueden ser llamadas plugins, pero así es como las llamo.

Conclusión

A partir de la creación de estas herramientas ya puedo crear plugins personalizados de pago único, pues la estructura base (comunicación HTTP, comandos ESC POS, comunicación con impresora) ya está bien definida, solo sería cuestión de cambiar el JSON que se recibe y que se imprime.

Si te lo preguntas, estoy escribiendo los comandos a mano jaja, seguramente me voy a arrepentir más adelante pero así lo he hecho para ahorrar tiempo. Mira un fragmento de código en Go:

// Tamaño de fuente 2x2
multiplicadorAncho := 2
multiplicadorAlto := 2
byteAncho := (2 << 3) * (multiplicadorAncho - 1)
byteAlto := multiplicadorAlto - 1
byteCompleto := byteAncho + byteAlto
bufer.Write([]byte{groupSeparator, '!', byte(byteCompleto)})
// Enfatizado
bufer.Write([]byte{esc, 'E', 0x01})
bufer.WriteString("Corte de caja\n")
// Sin enfatizar
bufer.Write([]byte{esc, 'E', 0x00})
// Tamaño normal
multiplicadorAncho = 1
multiplicadorAlto = 1
byteAncho = (2 << 3) * (multiplicadorAncho - 1)
byteAlto = multiplicadorAlto - 1
byteCompleto = byteAncho + byteAlto
bufer.Write([]byte{groupSeparator, '!', byte(byteCompleto)})
// Sucursal. Enfatizada la etiqueta, quitamos enfatizado, escribimos el valor
bufer.Write([]byte{esc, 'E', 0x01})
bufer.WriteString("Sucursal: ")
// Sin enfatizar

O en Kotlin:

// Tamaño de fuente 2x2
var multiplicadorAncho = 2
var multiplicadorAlto = 2
var byteAncho = (2 shl 3) * (multiplicadorAncho - 1)
var byteAlto = multiplicadorAlto - 1
var byteCompleto = byteAncho + byteAlto
bufer.write(byteArrayOf(GS, '!'.code.toByte(), byteCompleto.toByte()))

// Enfatizado
bufer.write(byteArrayOf(ESC, 'E'.code.toByte(), 0x01))
bufer.write("Corte de caja\n".toByteArray())

// Sin enfatizar
bufer.write(byteArrayOf(ESC, 'E'.code.toByte(), 0x00))

// Tamaño normal
multiplicadorAncho = 1
multiplicadorAlto = 1
byteAncho = (2 shl 3) * (multiplicadorAncho - 1)
byteAlto = multiplicadorAlto - 1
byteCompleto = byteAncho + byteAlto
bufer.write(byteArrayOf(GS, '!'.code.toByte(), byteCompleto.toByte()))
Si el post ha sido de tu agrado te invito a que me sigas para saber cuando haya escrito un nuevo post, haya actualizado algún sistema o publicado un nuevo software. Facebook | X | Instagram | Telegram | También estoy a tus órdenes para cualquier contratación en mi página de contacto