No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Luis Juarez e1ab81be9d KioskDemo: version del kiosco (WPF net48 x86) con el cliente de ONDAPlus, Banorte y la impresora
Proyecto completo sin binarios: sin bin/obj/.vs, sin la DLL del fabricante de la impresora (autoreplyprint*.dll; licencia sin confirmar,
ver KioskDemo/Lib/Impresora/LEEME.txt) y con las credenciales de Banorte del App.config reemplazadas por un marcador
(BanorteUsuario, BanortePassword, BanorteKey: CAMBIAR-POR-LA-CREDENCIAL-REAL).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:59:04 -06:00
KioskDemo KioskDemo: version del kiosco (WPF net48 x86) con el cliente de ONDAPlus, Banorte y la impresora 2026-10-14 15:59:04 -06:00
.gitignore KioskDemo: version del kiosco (WPF net48 x86) con el cliente de ONDAPlus, Banorte y la impresora 2026-10-14 15:59:04 -06:00
CLAUDE.md Subir archivos a "/" 2026-10-14 15:27:17 -06:00
KioskDemo.sln Subir archivos a "/" 2026-10-14 15:27:17 -06:00
README.md KioskDemo: version del kiosco (WPF net48 x86) con el cliente de ONDAPlus, Banorte y la impresora 2026-10-14 15:59:04 -06:00

Kiosco Demo (WPF · .NET Framework 4.8)

Proyecto de demostración de un kiosco de autoservicio con 3 operaciones: Depósito, Retiro y Compra de productos, conectado a un servidor WebSocket.

Requisitos

  • Windows con Visual Studio 2019 o 2022 (con la carga de trabajo ".NET desktop development").
  • Conexión a internet la primera vez que se abra el proyecto, para que NuGet restaure el paquete Newtonsoft.Json.

Cómo abrir y ejecutar

  1. Abrir KioskDemo.sln con Visual Studio.
  2. Esperar a que se restauren los paquetes NuGet (automático).
  3. Presionar F5 para compilar y ejecutar.

La ventana inicia maximizada. Se puede ajustar el tamaño/comportamiento "kiosco" (pantalla completa sin bordes) en MainWindow.xaml cambiando WindowStyle a None.

Servidor WebSocket

La URL del servidor se configura en App.config (clave ServerUri), para poder apuntar a la máquina real del S_SDK sin recompilar:

<appSettings>
    <add key="ServerUri" value="ws://127.0.0.1:8182/" />
</appSettings>

El default (127.0.0.1:8182) coincide con lo que trae S_SDK de fábrica (Properties.Settings.ipConnection / comConnection). Si el S_SDK real corre en otra máquina, edita ese archivo junto al .exe -no hace falta recompilar-.

Contrato de mensajes (confirmado con S_SDK real, integración 2026-07-09)

La app envía:

{ "Method": "StartPayment", "Amount": 500 }

Valores posibles de Method: StartPayment (compra, con Amount = costo; o depósito abierto, con Amount: 0 = sin monto objetivo), EndPayment (sin Amount; termina un depósito abierto), StartWithdrawal (retiro).

El servidor responde con uno o varios mensajes IdResult: 200 mientras dura la operación (uno por cada billete/moneda aceptado), y el mensaje definitivo trae "finalizado": true dentro de desc:

{
  "Method": "StartPayment",
  "IdResult": 200,
  "desc": {
    "totalDeposited": 100, "montoSolicitado": 75, "finalizado": true,
    "billetes": { "total": 100, "denominaciones": { "100": 1 } },
    "monedas": { "total": 0, "denominaciones": {} },
    "cambio": { "monto": 25, "billetes": {...}, "monedas": {...} },
    "entregado": { "billetes": {...}, "monedas": {...} }
  }
}

IdResult: 200 = éxito (progreso o final, ver finalizado), 500 = error controlado (se muestra desc al usuario), 400 = error no controlado.

Importante para StartPayment: el servidor NO manda un ack inmediato al recibirlo -a diferencia de "Open"-, así que CompraView y DepositoView usan WebSocketService.SendFireAndForgetAsync + el evento MessageReceived, e ignoran todo mensaje hasta ver desc.finalizado == true. Usar SendCommandAsync (que resuelve con el primer mensaje) perdería el cambio/desglose y navegaría a "Gracias" antes de tiempo.

Depósito abierto: DepositoView manda { "Method": "StartPayment", "Amount": 0 } -con Amount: 0, el servidor (S_SDK) no persigue ningún monto: acepta billetes/monedas indefinidamente, empujando el desglose en vivo (mismo mecanismo que la compra), hasta que la app manda { "Method": "EndPayment" } (botón "Terminar depósito"). Ese cierre no tiene una respuesta directa propia: el resultado final llega como un mensaje StartPayment más, con desc.finalizado == true, el totalDeposited definitivo y su desglose -sin cambio/entregado, esos solo aplican cuando Amount > 0 (compra)-.

Toda esta lógica vive en Models/WsMessages.cs (estructuras, incluyendo PagoEstado/DescComoPago()) y Services/WebSocketService.cs (envío/recepción). Si el contrato cambia, solo hay que tocar esos dos archivos.

Flujo de pantallas

  1. Bienvenida (Views/WelcomeView) — "Toca para iniciar".
  2. Menú (Views/MenuView) — Depósito / Retiro / Compra.
  3. Depósito (Views/DepositoView) — botón Iniciar → StartPayment con Amount: 0 (sin monto objetivo) → desglose de monedas ($0.50 a $20) y billetes ($20 a $1000) se actualiza en vivo conforme el servidor va reportando lo insertado → botón "Terminar depósito" envía EndPayment.
  4. Retiro (Views/RetiroView) — montos rápidos $20/$50/$100/$200 u "Otro monto" con teclado numérico en pantalla (tope $1,000) → confirmar envía StartWithdrawal.
  5. Compra (Views/CompraView) — catálogo con imagen/precio, carrito con cantidades → Pagar envía StartPayment.
  6. Gracias (Views/GraciasView) — resumen de la operación (folio, fecha, detalle, total) común a las 3 operaciones, con botón Imprimir ticket (usa el diálogo de impresión de Windows) y Finalizar (regresa a Bienvenida).

Personalización rápida

  • Catálogo de productos: Models/Catalog.cs → lista CatalogoDemo.Productos. Reemplazar por el catálogo real (nombre, precio, ruta de imagen) cuando esté disponible.
  • Colores / estilo: Themes/Styles.xaml (paleta al inicio del archivo).
  • Imágenes: Assets/Products, Assets/Cash, Assets/Icons — son ilustraciones planas generadas para la demo, se pueden sustituir por imágenes reales con el mismo nombre de archivo.
  • Monto máximo de retiro: constante MontoMaximo en Views/RetiroView.xaml.cs.

Notas

  • El proyecto usa el formato de csproj moderno (SDK-style) apuntando a net48, lo que permite que Visual Studio restaure Newtonsoft.Json automáticamente vía NuGet, sin pasos manuales.
  • El indicador de conexión (punto verde/rojo) en la barra superior refleja el estado real del WebSocket.
  • Si el servidor no responde en 15 segundos, la app muestra un aviso de "Sin conexión" en vez de quedarse congelada.