Integrando un kiosco de autopago con BBVA: lo que aprendí sobre pagos en producción
El problema de negocio
La agencia manejaba el cobro de servicios y trámites en ventanilla, de forma manual. Esto generaba filas, dependía de que un cajero estuviera siempre disponible, y no dejaba un registro digital claro de cada transacción. El objetivo era simple de decir y no tan simple de construir: que el cliente pudiera pagar por sí mismo, de forma segura, sin intervención humana.
Por qué no bastaba con "conectar una API"
Procesar pagos con tarjeta no es como consumir cualquier otro servicio web. Un kiosco de autopago necesita:
- Comunicación certificada con el banco adquirente.
- Manejo cuidadoso de sesiones y tokens, porque un fallo de autenticación en un sistema de pagos no es un error cualquiera.
- Trazabilidad completa: cada transacción debe quedar registrada de forma auditable.
- Una interfaz simple, porque el usuario final no es un desarrollador — es alguien pagando su servicio del coche.
La arquitectura
Construí el sistema en dos partes:
La aplicación de escritorio (WPF/C#) corre directamente en el kiosco y se integra con BBVA a través del SDK TotalPos de EGlobal, que maneja la comunicación certificada con la terminal de pago. Esta capa se mantiene deliberadamente simple: su único trabajo es procesar el pago y reportar el resultado.
La API backend (.NET) es donde vive la lógica real del negocio:
// Autenticación con rotación de refresh tokens — evita que un token
// robado o filtrado tenga validez indefinida
public class TokenService
{
public async Task<TokenPair> RefreshAsync(string refreshToken)
{
var stored = await _repository.GetByTokenAsync(refreshToken);
if (stored is null || stored.IsRevoked || stored.ExpiresAt < DateTime.UtcNow)
throw new UnauthorizedException("Token inválido o expirado");
await _repository.RevokeAsync(stored);
return await GenerateNewPairAsync(stored.UserId);
}
}
Además de JWT con rotación de tokens, agregué un middleware de API Key para
que solo el kiosco autorizado pueda hablar con el backend, manejo de
excepciones personalizado (nada de stack traces genéricos llegando al
cliente), y una estructura de respuesta estandarizada (ApiResponse<T>)
para que cualquier error se maneje de forma predecible.
Coordinación con el banco
Una parte del trabajo que no es puramente técnica: certificar la integración con el equipo de soporte técnico de BBVA. Cualquier sistema que procese pagos con tarjeta pasa por un proceso de validación del banco antes de operar en producción — pruebas de conexión, casos de transacción exitosa y fallida, y confirmación de que el flujo cumple con lo que el adquirente espera recibir. Este paso tomó tiempo de coordinación, pero es justamente lo que da certeza de que el sistema es confiable, no solo "que funciona en mi máquina".
El panel de administración
Del lado del personal de la agencia, construí un dashboard en React/TypeScript donde pueden supervisar los pagos procesados, con control de permisos por rol (no todos deben poder ver o hacer lo mismo) y tablas paginadas de transacciones para no cargar miles de registros de golpe.
Qué aprendí
Trabajar con pagos reales te obliga a pensar distinto que en un CRUD cualquiera: cada decisión de arquitectura tiene que justificarse pensando en "¿qué pasa si esto falla a mitad de una transacción?", no solo en "¿esto funciona en el caso feliz?". Ese cambio de mentalidad terminó mejorando cómo diseño el resto de mis sistemas, incluso los que no tocan dinero.
Si estás evaluando digitalizar el cobro de servicios en tu negocio, con gusto platicamos qué tan cerca o lejos está tu caso de este mismo problema.