La interacción con el usuario se conoce como una “sesión” que se inicia con la primera página desplegada y termina cuando el usuario solicita cerrarla, como por ejemplo al pagar la deuda de un url de pago o cancelando la operación.
Cuando la interacción se realiza en modo de UI “embed”, la página enviará eventos de javascript al window.parent
utilizando el método window.postMessage.
Los eventos son recibidos por el contenedor registrando una función que procese eventos de tipo message
utilizando el método window.addEventListener:
// Registrar nuestro callback para recibir los eventos window.addEventListener("message", recibirMensaje, false); // Aquí detectamos si es un mensaje enviado por Adams function recibirMensaje(event) { var eventoAdams = event.data && event.data.adamsEvent ; if( eventoAdams){ // Recibimos un evento de la página } }
Las propiedades dependen del evento reportado, pero como mínimo estarán presentes:
{ "event":"" // Evento siendo reportado , "pageId":"" // ID de la página que genera el evento. , "pageInfo":{ "isRoot":true // ¿Es la página raíz de esta sesión? } , "intent":"" // Intención registrada de esta sesión. , "intentInfo":{ // propiedades de la intención } }
Si la página presenta el botón de “atrás/cancelar”, el evento tendrá información sobre el mismo:
{ "closePageLink: { // Información del botón atrás/cancelar "url":"" // URL de navegación ,"label":"" // Etiqueta del botón } }
El tipo de evento está dado por la propiedad event
y puede ser uno de:
La página identificada por pageId
ha sido cargada.
Este evento también anula el estado ocupado creado por un evento pageBusy
con isBusy=true
La página está (o dejó de estar) ocupada ejecutando alguna acción como por ejemplo el SUBMIT de un form.
El estado de ocupado es cancelado por otro evento pageBusy
con isBusy=false
o por un evento pageReady
.
Propiedades adicionales para este evento:
{ "isBusy":true // La página está ocupada o dejó de estarlo. }
La sesión del usuario ha terminado (por ejemplo, ha pagado): El contenedor deberá cerrar el iframe/webview y presentar el resultado.
El valor de la propiedad intent
es la intención registrada de esta sesión y puede ser uno de:
Sesiones con esta intención son creadas al abrir una url de pago y tienen por objetivo realizar el pago de una deuda.
En este caso, el evento sessionEnd
tendrá información adicional en la propiedad intentInfo
:
{ "intentInfo":{ "docId:"" // ID de la deuda siendo pagada , "payScene":"" // Última vista mostrada al usuario } }
Los valores posibles para payScene
son:
pending
La deuda está pendiente de pagopaid
La deuda está pagadainactive
La deuda ha sido anuladaexpired
La deuda ha expiradoerror
La deuda está en estado de error y no puede ser pagada
La sesión fue creada con el objetivo de que el usuario agregue una tarjeta a su lista de tarjetas guardadas. Sus eventos tienen las mismas características que los de card-select
.
La sesión tiene por objetivo seleccionar una tarjeta de la lista de tarjetas guardadas (o agregar una).
En este caso, el evento sessionEnd
tendrá información adicional en la propiedad intentInfo
:
{ "intentInfo":{ "cardId:"" // ID de la tarjeta agregada o seleccionada } }
Actualmente no implementada, pero reservada para cuando el usuario edite su propio perfil.
Un boilerplate para procesar eventos de la página.
"use strict"; var segundosParaElPrimerMensaje = 20 , estoyOcupado = false; // Poner un límite al tiempo que esperamos el 1er mensaje var idTimeout = window.setTimeout(cargaDePaginaHaExpirado,segundosParaElPrimerMensaje * 1000); // Empezamos a escuchar eventos de tipo "message" window.addEventListener("message", mensajeRecibido, false); // Procesar eventos "message" function mensajeRecibido(event) { var eventoAdams = event.data && event.data.adamsEvent ; if( !eventoAdams ){ return ; // Ignorar: No es un evento de Adams } desactivarTimeout(); // Ya no estamos esperando if( eventoAdams.event === "pageReady" ){ ejecutarAccion("listo",{"pageId":eventoAdams.pageId}); // Página cargada } else if( eventoAdams.event === "pageBusy" ){ ejecutarAccion("ocupado",{"pageId":eventoAdams.pageId,"isBusy":eventoAdams.isBusy}); } else if( eventoAdams.event === "sessionEnd" ){ ejecutarAccion("terminar",{"intent":eventoAdams.intent,"intentInfo":eventoAdams.intentInfo,"closeUrl":eventoAdams.closePageLink.url}); } } function cargaDePaginaHaExpirado(){ idTimeout = 0; ejecutarAccion("timeout"); } function ejecutarAccion( accion, params ){ switch( accion ) { case "timeout": cerrarVista("Error: No se pudo cargar la página." ); break; case "listo": modoOcupado(false); break; case "ocupado": modoOcupado(params.isBusy); break; case "terminar": var mensaje="Sesión ha terminado"; if( params.intent === "pay-debt" ){ var payScene = params.intentInfo.payScene , docId = params.intentInfo.docId , estado ; switch( payScene ) { case "pending": estado = "pendiente"; break; case "paid": estado = "pagada"; break; case "inactive": estado = "inactiva"; break; case "expired": estado = "expirada"; break; case "error": default: estado = "en error"; break; } mensaje += "\nDeuda " + docId + " está " + estado; } cerrarVista(mensaje); } } function cerrarVista(mensaje) { // Cerramos la página de AdamsPay tomando la acción correspondiente // que podría ser cerrar el webview, navegar al resultado, hacer un POST, etc. if( mensaje )alert(mensaje); console.log("cerrar vista con mensaje: " + mensaje); } function modoOcupado(ocupado){ // Modificamos nuetro UI para desactivar controles temporalmente // hasta que termine la operación if( estoyOcupado !== ocupado ){ estoyOcupado = ocupado; console.log("modoOcupado:" + estoyOcupado); } } function desactivarTimeout(){ if( idTimeout ){ window.clearTimeout(idTimeout); idTimeout = 0; } } // Fin