ServicePay POS
PagueTodoSunmi
PagueTodo — pt-theme

SERVICIOS PAGUETODO, C.A

RIF: J-40339964-6

--------------------------------------------------------------------------------

ServicePay POS

Terminal de pago de servicios para dispositivos Sunmi: cobra, factura e imprime el recibo en el acto.

--------------------------------------------------------------------------------

CategoríaApp móvil fintech / punto de venta
Año2025
Rol

Desarrollo móvil Flutter e integración nativa Android (impresora térmica Sunmi)

Estado

Entregado al cliente — versión 1.0.7 (build 63), con builds separados para demo, QA y producción

* * * gracias por su compra * * *

com.paguetodo.servicepay.pos · lib/mains/pt

Las maquetas reproducen la interfaz real; los datos que muestran son de ejemplo.

01 · el mostrador
01 / El mostrador

Antes se anotaba a mano. Ahora sale impreso.

El mismo comercio, la misma venta, dos comprobantes muy distintos.

COMPROBANTE MANUAL

escrito a mano · sin número

------------------------------------------------------------

Los comercios aliados que venden pagos de servicios en Venezuela trabajaban con procesos dispersos: consultar la deuda de CANTV o CORPOELEC, cobrar en efectivo o pago móvil, anotar la operación y entregar un comprobante escrito a mano. No había forma de saber cuánto inventario quedaba, ni de emitir un recibo con número de aprobación, ni de operar el mismo software bajo dos marcas distintas sin mantener dos aplicaciones separadas.

Nro.
Aprobación
Inventario?
EstatusSIN VERIFICAR
ANULADO

RECIBO DE COMPRA

impreso en la térmica del terminal

------------------------------------------------------------

Una aplicación Flutter para terminales Android/Sunmi que concentra todo el ciclo: autenticación por RIF/cédula o correo con verificación del dispositivo por código OTP y desbloqueo biométrico opcional; catálogo de servicios que llega del backend; formularios de consulta y pago por operador; compra de inventario con cuatro medios de pago; reporte de movimientos filtrable por fechas; y un recibo que se imprime en la térmica del equipo. La marca y la paleta se resuelven en tiempo de arranque desde un archivo de temas, de modo que el mismo código compila como PagueTodo o como marca Sunmi.

Nro.0000004871
Aprobación884213
Inventario1.250 unid.
EstatusAPROBADO

Operación conforme

02 · lo que sostiene la caja

Destacados

Cinco piezas que hacen que el terminal cobre solo

Impresión térmica nativa línea por línea

Un MethodChannel (`samples.flutter.dev/print`) envía quince campos del voucher a `MainActivity.java`, que usa `com.sunmi:printerlibrary` para imprimir el bitmap del operador, la cabecera, el cuerpo campo a campo y el pie, con alineaciones y avance de papel.

01 / 05

Multimarca desde un archivo de temas

`themes.json` declara pt-theme (azul #0C7CEC / amarillo #ECCC04) y sunmi-theme (naranja #FF6000 / #FCA069) con sus logos, políticas y filtro por documento de identidad; `ThemeProvider` construye el `ThemeData` completo a partir del proveedor de color activo.

02 / 05

Sesión endurecida en el terminal

Contraseñas y datos de pago se cifran con RSA PKCS#1 (pointycastle + basic_utils) usando llaves públicas por ambiente; el dispositivo se autoriza con un código de seis dígitos, se identifica con un fingerprint UUID persistido, y un interceptor HTTP inyecta el bearer token y el contexto de negocio en cada petición.

03 / 05

Inventario y cuadre de caja en el propio equipo

La pantalla de inventario muestra saldo disponible, inventario en consignación y límite mínimo de unidades; el detalle lista cada movimiento con entrada/salida y saldo posterior, filtrado por período y paginado.

04 / 05

Compra de inventario con cuatro canales de cobro

Pago móvil, C2P Bancaribe, Credicard Pagos débito y transferencia inmediata, con validación de tarjeta, token bancario, clave de operaciones especiales y catálogo de 27 bancos venezolanos codificados en la app.

05 / 05

03 · las pantallas

Interfaz

Cuatro pantallas del terminal, recreadas tal cual

Mueve el interruptor de arriba y las cuatro cambian de marca a la vez: es lo mismo que hace ThemeProvider al arrancar la app.

80 mm
PagueTodo

Pago de servicios

v1.0.7 (63)
Iniciar con RIF/Cédula
RIF/CI
J-403399646
Contraseña
••••••••
INICIAR SESIÓN

¿Olvidaste tu contraseña? · Registrarme

Política de seguridad

Términos y condiciones

Inicio de sesión

Toggle RIF/correo, versión de la app y huella para volver a entrar.

80 mm
SERVICIOS DISPONIBLES

COMERCIAL LA ESQUINA, C.A

caja01@laesquina.com

J-40339964-6

PagueTodo
SERVICIOS DISPONIBLES
CANTV

CANTV POSPAGO

MOVISTAR

MOVISTAR PREPAGO

CORPOELEC

CORPOELEC POSPAGO

DIGITEL

DIGITEL PREPAGO

SIMPLETV

SIMPLETV POSPAGO

MOVILNET

MOVILNET PREPAGO

InicioInventarioAyuda

Servicios disponibles

Catálogo del backend en cuadrícula y barra inferior de tres destinos.

80 mm
CANTV
CANTV

El servicio no es anulable, por favor verifique el número de cuenta a pagar ya que el pago no puede ser reversado

J
RIF/CI
403399646
Número de contrato
02123456789
Deuda vencida:1.234,56 Bs
Deuda actual:987,00 Bs
LIMPIAR PAGAR

Cobro pospago

Consulta de deuda por contrato y aviso de servicio no anulable.

80 mm
INVENTARIO
Actualizar

INVENTARIO DISPONIBLE

(Prepago)

1.250 unid.

Ver detalles

INVENTARIO EN CONSIGNACIÓN

(Pospago)

Cantidad límite500Disponibles320
COMPRA RETIRO
InicioInventarioAyuda

Inventario

Saldo disponible, consignación y el botón de compra de inventario.

04 · el recibo

Del voucher al papel

La misma información, dos veces

Recibo de compra: primero se dibuja en pantalla y después sale por la ranura. En medio hay un canal nativo y quince campos que viajan uno por uno.

CANTV

SERVICIOS PAGUETODO, C.A

RIF: J-40339964-6

RECIBO DE COMPRA

------------------------------------------------------------

Nro: 0000004871

Fecha: 07/03/2025 11:42

Operador: caja01@laesquina.com

Empresa: CANTV

Servicio: CANTV POSPAGO

Cuenta: 02123456789

Monto: 1.234,56 bs

Nro. aprobación: 884213

------------------------------------------------------------

Total a pagar: 1.234,56 bs

Estatus: APROBADO

Cerrar

El único puente nativo del proyecto

1

Dart

Voucher declara el canal y arma los campos

lib · Flutter

2

MethodChannel

samples.flutter.dev/print

quince campos, en orden

3

Java

MainActivity.java traduce cada campo

android/app

4

SDK

com.sunmi:printerlibrary 1.0.18

SunmiPrintHelper

5

Papel

bitmap + cabecera + cuerpo + pie + avance

80 mm

Logos que se imprimen como bitmap

CANTVMOVISTARDIGITELSIMPLETVMOVILNET

SERVICIOS PAGUETODO, C.A

RIF: J-40339964-6

RECIBO DE COMPRA

------------------------------------------------

Nro: 0000004871

Fecha: 07/03/2025 11:42

Operador: caja01@laesquina.com

Empresa: CANTV

Servicio: CANTV POSPAGO

Total a pagar: 1.234,56 bs

Estatus: APROBADO

05 · la marca

themes.json

Un mismo código, dos identidades

Utilitario y contrastado, como una terminal de caja: azul corporativo de barra superior, amarillo de acento para el saldo y los llamados a la acción, fondo gris papel y tarjetas blancas con sombra corta. Tipografía de etiqueta compacta, mayúsculas para los títulos de sección.

PagueTodoSunmi
marca / ambientedesarrolloQA / demoproducción
pt-theme

lib/mains/pt/main_dev.dart

env.demo

lib/mains/pt/main_demo.dart

env.qa

lib/mains/pt/main_prod.dart

env.prod

sunmi-theme

lib/mains/sunmi/main_dev.dart

env.demo

lib/mains/sunmi/main_demo.dart

env.qa

lib/mains/sunmi/main_prod.dart

env.prod

06 · el inventario

Cuadre de caja

El comercio compra unidades y las va gastando

Cuatro maneras de recargar el inventario, tomadas de la propia app, y un reporte que deja la caja cuadrada sin salir del terminal.

Tarjeta del método de compra Pago Móvil
Pago Móvil
Tarjeta del método de compra C2P Bancaribe
C2P Bancaribe
Tarjeta del método de compra Credicard Pagos débito
Credicard Pagos débito
Tarjeta del método de compra Transferencia inmediata
Transferencia inmediata

Reporte de movimientos

Período (inicio) Período (fin)
FechaTipoDescripciónEntradaSalidaSaldo
07/03 11:42SALIDACANTV POSPAGO · 0212345678911.250
07/03 10:15SALIDAMOVISTAR PREPAGO · 0414-862445011.251
06/03 17:02ENTRADACompra de inventario · C2P Bancaribe5001.252
06/03 09:38SALIDACORPOELEC POSPAGO · 300144821752
05/03 16:20ENTRADACompra de inventario · Pago Móvil250753
1234

CUADRE DE INVENTARIO

------------------------------------------------

Disponible1.250 unid.
Consignación320 unid.
Límite500 unid.
Bancos27
Métodos4

Pago móvil, C2P Bancaribe, Credicard Pagos débito y transferencia inmediata, con token bancario y clave de operaciones especiales.

07 · funcionalidades

Detalle de la compra

Quince renglones en el mismo ticket

Cant. DescripciónEstado

==========================================================================================

01[x]Inicio de sesión con RIF/cédula o correo electrónico, alternable con un toggle animado
02[x]Autorización del dispositivo por código OTP de 6 campos enviado al correo del usuario
03[x]Desbloqueo biométrico opcional (local_auth) cuando el usuario eligió mantener la sesión
04[x]Auto-registro del aliado con preguntas de seguridad, recuperación de contraseña y flujo de contraseña expirada
05[x]Catálogo de servicios disponibles en cuadrícula, con logos servidos desde el CDN estático del backend
06[x]Pago pospago con consulta previa de deuda: CANTV, CORPOELEC (contratos múltiples con selección por radio), MOVISTAR, SIMPLETV, INTER
07[x]Recarga prepago de MOVISTAR, MOVILNET y DIGITEL con validación del prefijo por operadora y confirmación del número
08[x]Aviso explícito cuando el servicio no es anulable antes de cobrar
09[x]Recibo de compra en pantalla con número, fecha, operador, empresa, servicio, cuenta, monto, número de aprobación y estatus
10[x]Impresión del recibo en la impresora térmica del terminal Sunmi
11[x]Compra de inventario por pago móvil, C2P, tarjeta de débito o transferencia
12[x]Reporte de movimientos de inventario con filtro por período y paginador numérico
13[x]Sección de ayuda con 11 preguntas frecuentes buscables y 4 tutoriales en video
14[x]Detección de conectividad y aviso de nueva versión disponible (new_version_plus)
15[x]Cierre de sesión con renovación de token y reinicio limpio de la app
TOTAL DE RENGLONES15
Ilustración de la tarjeta Tutoriales en la sección de ayuda
Ilustración de la tarjeta Tutoriales en la sección de ayuda
Ilustración de la tarjeta Preguntas frecuentes en la sección de ayuda
Ilustración de la tarjeta Preguntas frecuentes en la sección de ayuda
08 · stack

Materiales

Con qué está hecho el terminal

App

01Flutter
02Dart SDK >=2.19.6 <3.0.0
03Material 3 (ThemeData propio)

Arquitectura y estado

01flutter_bloc
02rxdart
03provider
04equatable
05get_it
06injectable
07freezed
08json_serializable
09build_runner

Navegación

01go_router (ShellRoute con barra inferior)

Red y sesión

01http_interceptor
02connectivity_plus
03shared_preferences
04ffcache
05flutter_dotenv
06optional

Seguridad

01pointycastle
02basic_utils
03encrypt
04local_auth
05device_info_plus
06unique_identifier
07uuid

UI y formularios

01google_fonts
02lottie
03flutter_svg
04cached_network_image
05flutter_otp_text_field
06animated_toggle_switch
07drop_down_list
08number_paginator
09flutter_multi_formatter
10mask_text_input_formatter
11flutter_masked_text2
12currency_text_input_formatter
13intl
14flutter_localization

Nativo Android

01Java
02MethodChannel
03com.sunmi:printerlibrary 1.0.18
04ZXing core 3.3.0
05androidx.appcompat
06Material Components
07ConstraintLayout

Utilidades

01package_info_plus
02new_version_plus
03url_launcher
04timezone
05flutter_launcher_icons
06logger
07flutter_lints
09 · arquitectura

Bajo el capó

Cómo está armado por dentro

Monorepo Flutter de una sola app con seis puntos de entrada: `lib/mains/pt/{main_dev,main_demo,main_prod}.dart` y `lib/mains/sunmi/{...}`, que llaman a `mainCommon(env, theme)` con el ambiente (`env.demo`, `env.qa`, `env.prod` cargados como assets con flutter_dotenv) y el nombre del tema. `configureInjection` arma el grafo de dependencias con get_it + injectable (31 registros en `injection.config.dart`) y `ThemeProvider` lee `themes.json` para elegir marca, colores y assets antes de `runApp`. La UI vive en `lib/pages` con 12 módulos, cada uno con su BLoC, eventos, estados y servicio; go_router define las rutas planas de autenticación y un `ShellRoute` con las tres pestañas persistentes (Inicio, Inventario, Ayuda). La capa de datos es `ApiServices` sobre `http` con dos interceptores: `AuthInterceptor` (inyecta bearer token y realm/business_id/user_id en cada request) y `LoggingInterceptor`; los modelos se generan con json_serializable y freezed. La impresión es el único puente nativo: `Voucher` declara el `MethodChannel` y `MainActivity.java` traduce esos campos a llamadas de `SunmiPrintHelper`.

get_it + injectable

31 registros

lib/pages

12 módulos con BLoC

go_router

1 ShellRoute · 3 pestañas

Lo que costó resolver

Cuatro incidencias del proyecto, con su resolución.

Incidencia 01

El recibo no es un PDF ni una imagen: la impresora térmica del Sunmi recibe instrucciones secuenciales (alinear, imprimir texto, imprimir bitmap, avanzar papel) y no existe un plugin de Flutter que cubra el SDK del fabricante.

Resolución

Se definió un contrato de quince campos que Flutter envía por MethodChannel y se escribió la capa Java que los reproduce en orden: bitmap del operador según la empresa, cabecera centrada, cuerpo etiqueta por etiqueta en negrita y valor normal, pie y avance de papel; los logos de CANTV, MOVISTAR, DIGITEL, SIMPLETV y MOVILNET viven como drawables nativos para poder imprimirse como bitmap.

Incidencia 02

La misma app debía distribuirse bajo dos marcas distintas, con colores, logo, ícono y documentos legales propios, sin duplicar el proyecto.

Resolución

La marca se externalizó a `themes.json` (paleta, URI de assets, políticas, términos y filtro por RIF) y toda la UI consume colores a través de `ColorProvider`; el ícono de lanzamiento se genera con flutter_launcher_icons apuntando al asset de la marca y cada marca tiene su propio `main_*.dart`, de modo que cambiar de identidad es cambiar de entry point.

Incidencia 03

Los terminales POS tienen pantallas muy variadas: algunos equipos Sunmi son alargados y otros apenas superan los 400 puntos de alto, lo que rompía los formularios de pago.

Resolución

Las pantallas críticas (login, prepago, detalles) ramifican su layout según `MediaQuery.of(context).size.height > 432`: en equipos bajos se colapsan los filtros a una sola fila, se reduce el logo con un `AnimatedSwitcher` y se sustituyen columnas expandidas por listas desplazables.

Incidencia 04

Se manejan contraseñas, PIN, claves de operaciones especiales y números de tarjeta sobre redes de comercios que no controlamos.

Resolución

Los datos sensibles se cifran en el cliente con RSA PKCS#1 usando llaves públicas distintas por ambiente (`PASSWORD_PUBLIC_KEY` y `PAYMENT_PUBLIC_KEY` en los archivos env), el dispositivo se registra con un fingerprint UUID persistido y debe autorizarse con un código enviado al correo, y el token se renueva o la sesión se destruye desde `SessionTimer`.

10 · totales

Resumen de operación

El proyecto, en cifras

19

pantallas

12

módulos con BLoC propio

32

endpoints REST consumidos

2

marcas desde un mismo código

DETALLE DEL PROYECTO

----------------------------------------------------

pantallas19
módulos con BLoC propio12
endpoints REST consumidos32
marcas desde un mismo código2
puntos de entrada (marca × ambiente)6
métodos de compra de inventario4
bancos codificados27
líneas Dart escritas a mano~22 300

====================================================

VERSIÓN1.0.7 · build 63
11 · la letra pequeña

La letra pequeña

De qué va ServicePay POS

ServicePay POS (paquete `com.paguetodo.servicepay.pos`, etiqueta en Android "PAGO DE SERVICIOS") es la aplicación que un comercio aliado instala en su terminal Sunmi para vender pagos de servicios: recargas de telefonía prepago y cobro de facturas pospago.

El comercio compra inventario dentro de la app (pago móvil, C2P, tarjeta de débito o transferencia), y ese saldo se va consumiendo con cada operación; la pantalla de inventario y el reporte de movimientos paginado permiten cuadrar la caja sin salir del terminal.

Cada operación termina en un recibo: la app dibuja el voucher en pantalla y un canal nativo (`MethodChannel`) lo entrega línea por línea a la impresora térmica del dispositivo Sunmi, con el logo del operador como bitmap.

Es una app multimarca: `themes.json` define dos identidades (pt-theme y sunmi-theme) con paleta, logos, términos y filtro por RIF, y hay seis puntos de entrada (`lib/mains/pt/*` y `lib/mains/sunmi/*`) que combinan marca y ambiente.

Marcas e íconos del proyecto · arrastra

Ícono de la aplicación: la P monolínea en amarillo #ECCC04 sobre fondo transparente
Ícono de la aplicación: la P monolínea en amarillo #ECCC04 sobre fondo transparente
Logotipo horizontal del pt-theme: símbolo azul #0C7CEC con punto amarillo y wordmark PAGUETODO
Logotipo horizontal del pt-theme: símbolo azul #0C7CEC con punto amarillo y wordmark PAGUETODO
Isotipo del pt-theme usado en la cabecera de perfil de la pantalla de servicios
Isotipo del pt-theme usado en la cabecera de perfil de la pantalla de servicios
Logotipo de la segunda marca (sunmi-theme), naranja #FF6000
Logotipo de la segunda marca (sunmi-theme), naranja #FF6000
Ícono naranja del sunmi-theme, fuente de flutter_launcher_icons en el build actual
Ícono naranja del sunmi-theme, fuente de flutter_launcher_icons en el build actual
Ícono de lanzador compilado en el APK Android
Ícono de lanzador compilado en el APK Android
CANTVCORPOELECMOVISTARMOVILNETDIGITELSIMPLETVINTERSunmiPago móvilC2P BancaribeCANTVCORPOELECMOVISTARMOVILNETDIGITELSIMPLETVINTERSunmiPago móvilC2P Bancaribe

----------------------------------------------------

Total a pagar1.234,56 bs
Nro. aprobación884213

ESTATUS: APROBADO

0000004871 · 07 03 2025

FintechEn producción

ServicePay POS

¿Quieres algo así para tu producto?

Una terminal de pago de servicios que cobra, cuadra inventario e imprime el recibo en el propio equipo, bajo dos marcas y tres ambientes. Si necesitas algo así —Flutter con puente nativo, dinero de por medio y hardware real— es terreno conocido.