Android + PAM integration (Español)
Este libro describe como integrar y comunicarse satisfactoriamente con el PAM desde una aplicación Android, con el objetivo de proveer una session de apuestas para clerks.
Introduction
Introduction
Este documento describe los requerimientos y el flujo para integrar el PAM (Aplicación web) con una aplicación Android. Solo se presentarán los detalles de una sesión de apuestas.
Una sesión de apuestas es un período donde un agente realiza apuestas en el nombre de un cliente. Esta sesión termina cuando el cliente ha realizado todas las apuestas deseadas.
Este documento asume que la aplicación web está embedida dentro de Android como un WebView, y considera el flujo un flujo de pago con comunicación en 3 pasos:
- Validación de balance disponible: Previo a continuar con la operación a realizar.
- Confirmación de apuestas: Luego de confirmar una apuesta.
- Sesión finalizada: cuando el cliente deja el mostrador.
Integration basics
Para cumplir satisfactoriamente con el flujo propuesto, nuestra aplicación requiere de una comunicación bi-direccional entre la aplicación padre y la web app.
Pre-requisitos
Pre-requisitos
- WebView JavaScript habilitado
- Tener acceso a la private key del partner para generar tokens seguros
- Configurar el user agent de la WebView como se indica. Esto deberá ser provisto por el equipo de desarrollo y puede variar entre implementaciones.
Detalles técnicos
Autenticando el admin user sin contraseña
Para correctamente autenticar a un usuario dentro de la aplicación, se necesita un token con un cuerpo específico, respetando las normas propuestas por el standard JWT RS256, donde, el cuerpo incluye la siguiente estructura:
{
sub: // adminUserName,
rol: // roles,
aid: // agentId,
nam: // name,
oth: // email,
tit: // title,
}
* Los tokens generados loguean a un admin user si existiese o crean uno de no existir. No se modifican los admin users bajo
ningún concepto
Campos requeridos:
- Sub: El nombre de usuario
- Rol: Un array de roles a aplicar (Cuando se crean agentes, el array debería estar formado por: [*clerk])
- Aid: es el master agent a asignar el usuario, provisto por el partner.
Otros campos:
- Nam: Nombre del agente
- Oth: Email del agente
- Tit: Titulo del agente
* Estos campos son opcionales, no tienen ningún impacto más que ser descriptivos del bodeguero.
Creando la URL de la Retail App
La aplicación retail esta construida en base a un path básico y parámetros adicionales.
La ruta base es: https://pwallet.partner-domain.com/admin/pos/retail.
Set de parametros opcionales:
- Token: El valor de este parametro deberia ser generado de forma segura con el private key provisto en la sección de requisitos #2, siguiendo Autenticar el admin user sin contraseña
- customerId: Si fuese provisto, la session de apuesta se realizará para ese cliente.
- customerEmail: Se creará un cliente asociándole este email.
- customerPhone: Se creará un cliente asociándole este teléfono.
Notes:
- Si fuere provisto, customerId toma precedencia sobre los otros atributos.
- customerEmail y customerPhone realizan una operación OR en la base de datos. Si hubiese mas de un cliente asociado a los mismos, ocurrirá un error y no se continuará con la sesión. Recomendamos usar uno o el otro, no ambos al mismo tiempo.
Examples:
- https://pwallet.partner-domain.com/admin/pos/retail?token=<authToken>
Redirecciona al modo retail con una nueva sesión. - https://pwallet.partner-domain.com/admin/pos/retail?token=<authToken>&customerId=12345
Para obtener el cliente con id 12345 - https://pwallet.partner-domain.com/admin/pos/retail?token=<authToken>&customerEmail=test@domain.com
Para obtener el cliente con el email test@domain.com - https://pwallet.partner-domain.com/admin/pos/retail?token=<authToken>&customerPhone=1234590
Para obtener el cliente con el telefono 1234590
Detalles de la comunicación desde la Aplicación Web al WebView
Referencias: https://developer.android.com/guide/webapps/webview
Esta implementación es usada para enviar datos desde la Aplicación Web hacia la Aplicación wrapper. En un enfoque empírico, es necesario definir una Clase que maneje el mensaje enviado.
/** Instantiate the interface and set the context */
class WebAppInterface(private val mContext: Context) {
/** Handles the JSON stringified object sent by the web application */
@JavascriptInterface
fun messagesHandler(data: String) {
// App logic goes here
}
}
* El `messagesHandler` es un ejemplo, no un método que debería ser implementado.
Luego, se debería agregar la Interface de Javascript con la clase creada previamente desde el objeto del WebView.
mWebView.addJavascriptInterface(WebAppInterface(this), "AndroidInterface")
El segundo argumento siempre debería ser "AndroidInterface", ya que este es el nombre que se usara para comunicarse desde el WebView hacia la Aplicación en Javascript.
Los métodos definidos en la clase WebAppInterface serán los que utilicemos para interactuar con tu aplicación, por lo que se espera que crees métodos específicos con específicas respuestas. La lógica de la implementación queda a tu criterio, siempre que se reciba el formato de respuesta esperado.
Métodos de la Interface
Aviso Importante: El prerrequisito #3 debe ser completado para que esto funcione. Si el user agent no contiene el string 'android-go-pay' no se emitirá ningún evento.
Verificación del Balance
Este método envía una solicitud de balance al wrapper pidiendo la confirmación de que el importe de la apuesta se encuentra disponible y puede ser utilizado por el cliente para la sesión de apuestas actual.
@JavascriptInterface
fun checkBalance(amount: Float, currency: String = "PEN") {
// Your logic
}
Antes de proceder a realizar la apuesta, se debe recibir la confirmación del balance. De lo contrario la apuesta no se realizará.
Esperamos una respuesta en el mensaje con el siguiente formato:
{
‘balance-check’: {
success: Boolean,
error?: Any, // This exists only when success is false, if extra data is needed to be sent.
data?: Any // This exists only when success is true, if extra data is needed to be sent.
}
}
Confirmación de apuesta(s)
Este método recibe dos argumentos, un array de wagerIds (integer) y un totalAmount (float). Este monto total deberá ser menor o igual que el importe previamente confirmado en la llamada del método de checkBalance.
@JavascriptInterface
fun wagersPlaced(wagerIds: IntArray, totalAmount: Float) {
// Your logic here
}
WagerIds puede ser uno o varios id de apuestas, el totalAmount es la cantidad total apostada entre todas esas apuestas.
No se espera que este método envíe ninguna respuesta a la aplicación web. Sólo está pensado para la conciliación entre sistemas y para proporcionar un mapeo de las transacciones financieras a las apuestas.
Sesión finalizada
Este método se llama en la aplicación web siempre que el proceso de apuestas de un empleado con un cliente haya finalizado. Esto sólo ocurrirá si el recibo ha sido enviado al cliente por correo electrónico o mensaje de texto.
Este método, al igual que la confirmación de la apuesta, no espera ninguna respuesta hacia la Aplicación web.
Detalles de la comunicación desde el WebView a la Aplicación Web
Nos comunicamos desde la WebView a la aplicación web invocando una llamada postMessage en el objeto window a través de la evaluación de JavaScript en el contexto de Android.
webView.post(Runnable {
webView.evaluateJavascript("(function () { window.postMessage(object-defined-for-each-method); })();", null)
})
La respuesta debe ser siempre la definida en cada método, otros mensajes no funcionarán.