Crea una experiencia de confirmación de compra rápida en Android con Google Pay (Kotlin)

1. Introducción

La API de Google Pay les brinda a los usuarios la oportunidad de pagar desde cualquier lugar usando la información de pago almacenada en sus Cuentas de Google. En este lab, usarás la biblioteca cliente de Google Pay para Android para mejorar la experiencia de finalización de compra de una aplicación para dispositivos móviles de ejemplo simplificada a través de la creación de una experiencia más rápida, conveniente y segura que, a su vez, genera más conversiones y clientes felices.

Auto T-Shirt Shop es una innovadora tienda que aprovecha los avances más recientes de la Inteligencia Artificial y usa información como las preferencias de estilo, el clima, la época del año y las tendencias de moda para sugerirte los artículos más apropiados que puedes comprar.

Las métricas sobre el compromiso son fundamentales. Lamentablemente, los números también reflejan una gran cantidad de abandonos durante el proceso de confirmación de compra. Dispuesto a hacerle frente a eso, uno de los propietarios del proyecto recuerda haber visto un video que mostraba los prometedores resultados que había producido Google Pay en otros sitios similares, por lo que se decidió a probarlo y confiar en ti para que te encargues de la integración.

Qué compilarás

En este codelab, descubrirás cómo integrar Google Pay a una aplicación existente, lo que incluye determinar si un usuario puede pagar con una forma de pago compatible con Google Pay, la posición y el diseño del botón de pago, y la ejecución de la transacción.

f5f96f8afc94448c.png

Qué aprenderás

  • Cómo integrar Google Pay a una aplicación existente
  • Cómo elegir entre tus formas de pago preferidas
  • Cómo determinar si un usuario está listo para pagar con Google Pay

Requisitos

  • Una computadora con acceso a Internet
  • Un entorno de desarrollo listo para compilar aplicaciones para Android (recomendamos usar Android Studio)
  • Un dispositivo Android con una versión actualizada de Servicios de Google Play instalada

2. Primeros pasos

Clona el repositorio desde GitHub:

Usa el siguiente comando para clonar el repositorio a una carpeta de tu computadora:

$ git clone https://github.com/google-pay/android-quickstart

O, si lo prefieres, descarga un archivo ZIP:

Descargar código fuente

Observa rápidamente la aplicación de ejemplo

Como puedes ver, el repositorio tiene una estructura de archivo simple. El objetivo principal de este codelab es brindarte la posibilidad de adaptar esta integración para tus aplicaciones existentes y futuras, independientemente del lenguaje de programación, las bibliotecas o las herramientas con los que elijas trabajar.

3. Integra Google Pay en la aplicación (o en tu propia aplicación)

Explora la aplicación

Una vez que tu aplicación está compilada, puedes usar un emulador o un dispositivo real para obtener una vista previa de ella. Te recomendamos usar un dispositivo con una Cuenta de Google y formas de pago ya asociadas a la cuenta.

La aplicación sobre la que se desarrolla este codelab es una tienda para dispositivos móviles de demostración que, con un modelo de aprendizaje automático muy avanzado, sugiere una remera a los visitantes según una variedad de funciones muy complejas. Si te preguntas por qué el sitio te recomienda una remera diferente cada vez que vuelves a cargarlo, bueno… a decir verdad, el modelo de aprendizaje automático muy avanzado es simplemente un generador aleatorio (¡perdón!).

Esta tienda de demostración se creó de manera tal que es similar a la manera en que podría verse tu aplicación existente o potencial, antes de que agregues un medio de compra. De hecho, si bien te recomendamos trabajar sobre esta aplicación de demostración, puedes usar este codelab para integrar Google Play a las aplicaciones que ya tienes.

Si todavía no lo hiciste, ejecuta la aplicación de demostración tal como está.

175215c8c8696ede.png

Si pudiste ver la aplicación de demostración, seguramente no viste nada sorprendente, ¿verdad? Una vista de detalles del producto, con una imagen, el precio, una descripción y un botón que te lleva a una forma de pago común.

El objetivo de este lab es reemplazar, en principio, este flujo tedioso con una experiencia de dos pasos con Google Pay.

Comencemos a planificarlo

Para comprender mejor esta integración, el proceso está dividido en los siguientes pasos fundamentales:

  1. Agrega las dependencias necesarias
  2. Determina la posibilidad de pagar con Google Pay
  3. Muestra el botón para pagar con Google Pay
  4. Crea y envía la solicitud del pago
  5. Recopila los resultados

4. Agrega las dependencias necesarias

Agrega los servicios de Google Play a tu build.gradle

Lo primero que debes hacer para comenzar a usar la API de Google Pay es agregar la dependencia dentro de los servicios de Google Pay que contienen los paquetes que necesitas. Para ello, agrega el siguiente elemento implementation a tu lista de dependencies en el archivo build.gradle dentro del módulo de tu aplicación. En este codelab, el módulo se llama app:

implementation "com.google.android.gms:play-services-wallet:18.0.0"

Habilita la API en tu archivo de manifiesto

Por último, agrega un elemento meta-data dentro del nodo application de tu archivo de manifiesto. De esta manera, el sistema sabe que quieres usar esta API y habilita el acceso a ella.

<meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />

5. Planifica la interfaz de usuario y dónde mostrar el botón de Google Pay

El diseño y la experiencia general de tus vistas son aspectos fundamentales que influyen en la probabilidad de que tus usuarios completen una transacción de pago exitosa. La posibilidad de elegir una forma de pago con solo presionar la pantalla unas pocas veces usando Google Pay habilita un conjunto más amplio de opciones sobre dónde y cuándo ofrecer a los usuarios una forma de pago en tu aplicación. Por ejemplo, puedes agregar opciones de finalización de compra rápidas de manera temprana en el proceso, en áreas como la vista detallada del artículo, para permitir a los usuarios pagar rápidamente por el artículo que les interesa.

Una vez que decidiste cómo organizar tu IU y navegación, el siguiente paso es colocar el botón que activa una transacción de pago con Google Pay. Se espera que el estilo de este botón se ajuste a los lineamientos establecidos que garantizan coherencia y familiaridad cuando los usuarios lo ven en tu aplicación:

a18b3311d84d9dcc.png

Para facilitarte esta tarea, creamos un paquete con todas las opciones disponibles, en diferentes resoluciones y para distintas configuraciones regionales que está disponible para descargar. El paquete incluye recursos de layout, drawable y values que puedes pegar directamente en tu proyecto.

Puedes encontrar el recurso que necesitas agregar a la definición de tu vista, activity_checkout.xml, en el directorio layout. Para agregarlo a tu vista, simplemente colócalo en la posición deseada con el elemento include:

<include
    android:id="@+id/googlePayButton"
    layout="@layout/buy_with_googlepay_button"
    android:layout_width=<your_width_dimension>
    android:layout_height="@dimen/buy_button_height"
    android:visibility="gone"/>

6. Inicializa y configura la API de Google Pay

Crea una instancia del cliente de API

Para comenzar a usar la API, es necesario crear una instancia de un objeto cliente, que usarás para realizar llamadas a la API de Google Pay. Puedes hacerlo en cuanto tu actividad esté creada:

private lateinit var paymentsClient: PaymentsClient

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_checkout)

    paymentsClient = createPaymentsClient(this)
}

fun createPaymentsClient(activity: Activity): PaymentsClient {
    val walletOptions = Wallet.WalletOptions.Builder()
            .setEnvironment(WalletConstants.ENVIRONMENT_TEST).build()
    return Wallet.getPaymentsClient(activity, walletOptions)
}

El cliente de pago se inicializa con un objeto WalletOptions. Configurar el entorno en ENVIRONMENT_TEST te permite experimentar la información de pago simulada en toda la integración. Cuando esté todo listo para crear operaciones que admiten transacciones reales, puedes actualizar la propiedad del entorno a ENVIRONMENT_PRODUCTION.

La estructura base

Cada vez que te comunicas con la API de Google Pay, hay un número de parámetros de configuración que debes incluir en tus solicitudes, como la versión de la API que estás integrando. Para este codelab, este objeto también contiene información sobre las formas de pago aceptadas en tu aplicación. La estructura final se ve de la siguiente manera:

{
    apiVersion: number,
    apiVersionMinor: number,
    allowedPaymentMethods: Array
}

La propiedad allowedPaymentMethods contiene una lista de formas de pago. Debes incluir las siguientes propiedades por cada forma de pago:

{
    type: 'CARD',
    parameters: {
        allowedCardNetworks: Array.<string>,
        allowedAuthMethods: Array.<string>
    }
}

Además de type y parameters, luego, debes agregar la propiedad tokenizationSpecification, que no es necesaria para determinar si el usuario en cuestión puede pagar con Google Pay, pero la utiliza la llamada PaymentDataRequest para definir cómo se procesarán los datos relacionados con la forma de pago seleccionada. Avancemos de a un paso por vez.

Configuración de la forma de pago

En este ejemplo, solo aceptarás pagos con tarjetas Mastercard y Visa, ambos con formato de número de cuenta principal (PAN) y un token asignado. Así es como se ve tu forma de pago:

private val baseCardPaymentMethod = JSONObject().apply {
    put("type", "CARD")
    put("parameters", JSONObject().apply {
        put("allowedCardNetworks", JSONArray(listOf("VISA", "MASTERCARD")))
        put("allowedAuthMethods", JSONArray(listOf("PAN_ONLY", "CRYPTOGRAM_3DS")))
    })
}

Resumen

Repasemos:

Definiste una forma de pago para que tu aplicación la acepte y vas a trabajar con la versión 2.0 de la API. Así es como se ve la configuración resultante:

private val baseCardPaymentMethod = JSONObject().apply {
    put("type", "CARD")
    put("parameters", JSONObject().apply {
        put("allowedCardNetworks", JSONArray(listOf("VISA", "MASTERCARD")))
        put("allowedAuthMethods", JSONArray(listOf("PAN_ONLY", "CRYPTOGRAM_3DS")))
    })
}

private val googlePayBaseConfiguration = JSONObject().apply {
    put("apiVersion", 2)
    put("apiVersionMinor", 0)
    put("allowedPaymentMethods",  JSONArray().put(baseCardPaymentMethod))
}

Ahora que ya tienes lista la configuración básica, pasemos a la parte divertida.

7. Determina la disponibilidad para pagar con Google Pay

Uno de los objetivos principales de Google Pay es proporcionar una experiencia de finalización de compra más conveniente para tus usuarios. Esto se aplica a situaciones en las que tus usuarios pueden aprovechar Google Pay y en las que no. Usar la solicitud isReadyToPay te permite determinar la disponibilidad para pagar con Google Pay y representa una oportunidad para modificar la experiencia en tu sitio de forma acorde.

¿Tu usuario puede pagar con Google Pay?

Lo primero que debes hacer es comprobar si un usuario específico que está a punto de pagar en tu aplicación puede usar Google Pay para hacerlo. Esta solicitud requiere que especifiques la versión de la API de Google Pay y las formas de pago permitidas en tu sitio. Esto es exactamente lo que contiene el objeto de configuración básica definido en el paso anterior:

val readyToPayRequest =
        IsReadyToPayRequest.fromJson(googlePayBaseConfiguration.toString())

val readyToPayTask = paymentsClient.isReadyToPay(readyToPayRequest)
task.addOnCompleteListener { task ->
    try {
        task.getResult(ApiException::class.java)?.let(::setGooglePayAvailable)
    } catch (exception: ApiException) {
        // Error determining readiness to use Google Pay.
        // Inspect the logs for more details.
    }
}

Como puedes ver, si la llamada devuelve una respuesta incorrecta, no se puede realizar ninguna otra acción en el contexto de Google Pay. En esta situación, el próximo paso más adecuado sería mostrar la IU adicional que admite otros medios de pago.

Por otro lado, si la respuesta es correcta, ya puedes permitir a tus usuarios beneficiarse con el uso de Google Pay y, como resultado, puedes mostrar el botón de Google Pay para iniciar el proceso de pago en la activación del usuario (por ejemplo, clics del botón).

Muestra el botón para pagar con Google Pay

Ahora, ya puedes mostrar el botón de Google Pay.

private fun setGooglePayAvailable(available: Boolean) {
    if (available) {
        googlePayButton.visibility = View.VISIBLE
        googlePayButton.setOnClickListener { requestPayment() }
    } else {
       // Unable to pay using Google Pay. Update your UI accordingly.
    }
}

private fun requestPayment() {
  // TODO: Perform transaction
}

Observa que también definiste una función para procesar eventos de clics en el botón. En la siguiente sección, usarás esta función para solicitar una forma de pago.

8. ¡Es hora de pagar!

Prepara la solicitud de pago

En este punto, cargaste la API de Google Pay y determinaste que el usuario de tu aplicación puede usar Google Pay para hacer un pago. Como resultado, mostraste el botón de pago de Google Pay en la IU y ahora tu usuario está listo para iniciar la transacción. Es momento de cargar la hoja de pagos que contiene las formas de pago disponibles para los diferentes usuarios conectados.

Al igual que hiciste durante la definición de la solicitud isReadyToPay, esta llamada también requiere las propiedades del objeto de configuración básica definido anteriormente (apiVersion, apiVersionMinor y allowedPaymentMethods) además de algunas nuevas. Esta vez hay una nueva propiedad llamada tokenizationSpecification y parameters adicionales en tus formas de pago que son relevantes para los fines de esta solicitud solamente. Además, también es necesario agregar transactionInfo y merchantInfo.

Incluye la información adicional necesaria en tus formas de pago

Comienza por crear una copia de la forma de pago de tarjeta básica que utilizamos antes. Esta forma de pago de tarjeta ahora requiere una propiedad tokenizationSpecification para definir cómo procesar los datos relacionados con la forma de pago seleccionada, además de los datos obligatorios para la transacción en sí: en este ejemplo, se requieren una dirección de facturación completa y un número de teléfono.

La propiedad tokenizationSpecification

La especificación de asignación de token determina cómo se procesa y utiliza la forma de pago seleccionada por tus usuarios para completar una transacción.

Se admiten dos tipos de estrategias de procesamiento. Si estás procesando la transacción de pago desde servidores que cumplen con PCI DSS, usa el tipo de especificación DIRECT. En este ejemplo, usas una puerta de enlace de pago para procesar el pago, por lo tanto, configuras el tipo de especificación PAYMENT_GATEWAY. Así es como debería verse tu asignación de token:

private val tokenizationSpecification = JSONObject().apply {
    put("type", "PAYMENT_GATEWAY")
    put("parameters", JSONObject(mapOf(
            "gateway" to "example",
            "gatewayMerchantId" to "exampleGatewayMerchantId")))
}

En la sección parameters, puedes especificar una puerta de enlace a partir de la lista de proveedores compatibles con la API de Google Pay, junto con la configuración adicional que requiere cada puerta de enlace. Para los fines de este lab, es suficiente usar la puerta de enlace example, que produce resultados de prueba para las transacciones ejecutadas.

Parámetros adicionales

De manera similar, ahora puedes brindar más detalles sobre la información que necesitas solicitar para que la transacción se realice correctamente. Observa cómo, en este ejemplo, puedes agregar las propiedades billingAddressRequired y billingAddressParameters, para indicar que, para esta transacción, se requiere la dirección de facturación del usuario en formato completo y un número de teléfono.

private val cardPaymentMethod = JSONObject().apply {
    put("type", "CARD")
    put("tokenizationSpecification", tokenizationSpecification)
    put("parameters", JSONObject().apply {
        put("allowedCardNetworks", JSONArray(listOf("VISA", "MASTERCARD")))
        put("allowedAuthMethods", JSONArray(listOf("PAN_ONLY", "CRYPTOGRAM_3DS")))
        put("billingAddressRequired", true)
        put("billingAddressParameters", JSONObject(mapOf("format" to "FULL")))
    })
}

Cómo agregar información sobre la transacción

La propiedad transactionInfo contiene un objeto con los detalles financieros de la transacción, es decir, el precio y el código de moneda (formato alfa ISO 4217) junto con el estado del precio, que puede ser final o estimado según la naturaleza de la transacción (por ejemplo, el precio puede variar según la dirección de facturación especificada):

private val transactionInfo = JSONObject().apply {
    put("totalPrice", "123.45")
    put("totalPriceStatus", "FINAL")
    put("currencyCode", "USD")
}

Cómo agregar información sobre el comercio

La solicitud de pago toma la información sobre el comercio que realiza la solicitud de la propiedad merchantInfo. En este codelab, te concentrarás en dos propiedades:

  • merchantId espera el identificador asociado con tu cuenta una vez que Google aprueba tu aplicación para operar en producción. Puedes obtener tu identificador de comerciante en tu cuenta, en Business Console de Google Pay. Ten en cuenta que esto no se evalúa cuando se usa el entorno TEST.
  • merchantName es un nombre de tu aplicación u organización que el usuario puede ver. Esto puede aparecer dentro de la hoja de pago de Google Pay para brindar a los usuarios más información sobre quién solicita la operación.

Cuando estés listo, agrega la información sobre el comercio al objeto paymentDataRequest:

private val merchantInfo = JSONObject().apply {
    put("merchantName", "Example Merchant")
    put("merchantId", "01234567890123456789")
}

Solicita información de pago y procesa el resultado

Ahora, combina la configuración definida anteriormente en el objeto final y pásala a la solicitud loadPaymentData:

private val paymentDataRequestJson = JSONObject(googlePayBaseConfiguration.toString()).apply {
    put("allowedPaymentMethods", JSONArray().put(cardPaymentMethod))
    put("transactionInfo", transactionInfo)
    put("merchantInfo", merchantInfo)
}

En este punto, tienes todo lo que necesitas preguntarle a la API de Google Pay para una forma de pago válida. Para ello, usa el método loadPaymentData del objeto PaymentsClient, que se encuentra en la configuración que acabas de definir:

val paymentDataRequest =
        PaymentDataRequest.fromJson(paymentDataRequestJson.toString())

AutoResolveHelper.resolveTask(
        paymentsClient.loadPaymentData(paymentDataRequest),
        this, LOAD_PAYMENT_DATA_REQUEST_CODE)

Cuando se llama a este método, se activa la presentación de la hoja de pago de Google Pay. Si no hay errores de configuración, puedes ver una lista de formas de pago válidas asociadas con la cuenta conectada actualmente.

Después de la selección, la hoja se cierra y el resultado se vuelve a enviar a tu actividad y se captura a través del método onActivityResult:

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    when (requestCode) {
        LOAD_PAYMENT_DATA_REQUEST_CODE -> {
            when (resultCode) {
                Activity.RESULT_OK ->
                    PaymentData.getFromIntent(data)?.let(::handlePaymentSuccess)

                Activity.RESULT_CANCELED -> {
                    // The user cancelled without selecting a payment method.
                }

                AutoResolveHelper.RESULT_ERROR -> {
                    AutoResolveHelper.getStatusFromIntent(data)?.let {
                        handleError(it.statusCode)
                    }
                }
            }
        }
    }
}

Si la selección se realiza correctamente, el resultado se completa con un objeto PaymentData, que incluye la información relevante sobre la forma de pago seleccionada:

{
  "apiVersionMinor": 0,
  "apiVersion": 2,
  "paymentMethodData": {
    "description": "Visa •••• 1234",
    "tokenizationData": {
      "type": "PAYMENT_GATEWAY",
      "token": "examplePaymentMethodToken"
    },
    "type": "CARD",
    "info": {
      "cardNetwork": "VISA",
      "cardDetails": "1234",
      "billingAddress": {
        "phoneNumber": ...,
        ...
      }
    }
  }
}

Ahora, puedes usar esta información sobre la forma de pago para realizar la transacción en sí.

private fun handlePaymentSuccess(paymentData: PaymentData) {
    val paymentMethodToken = paymentData
            .getJSONObject("tokenizationData")
            .getString("token")

    // Sample TODO: Use this token to perform a payment through your payment gateway
}

9. ¡Felicitaciones!

Integraste correctamente la API de Google Pay a tu aplicación.

Ahora, para implementarlo en la producción, no olvides echar un vistazo a la lista de tareas de integración. Cuando la hayas completado y revisado, recibirás un identificador de comerciante (merchantId) para agregarlo a tu configuración de cliente. De manera similar, si planeas usar (o ya estás usando) un procesador de pagos o una puerta de enlace externa, consulta la lista de proveedores compatibles en Google Pay y configura los tuyos. Si integras con Google Pay directamente, observa la sección de documentación sobre este tema.

Temas abordados

  • Cómo importar y configurar la API de Google en tu aplicación
  • Cómo determinar la compatibilidad de la API y reaccionar según corresponda
  • Cómo agregar un botón para permitir a los usuarios pagar con Google Pay
  • Cómo cargar y procesar la información de pago del usuario almacenada anteriormente

Próximos pasos

  • Probar Google Pay en una aplicación real, si es que todavía no lo hiciste
  • Obtener un identificador de comerciante en Business Console de Google Pay
  • Revisar la lista de tareas de integración
  • Observar los dos tipos diferentes de integración y decidir cuál es mejor para ti: integrar directamente o usar una puerta de enlace o un procesador de pago

Más información

¿Esto te resultó útil?

Muy útil Lo suficiente como para cumplir con mis expectativas En realidad, no

¿Te gustaría ver otros codelabs que pueden ayudarte con otros tipos de integración (integración directa, APIs valiosas y pasadas)?

Sí, me gustaría. Estoy bien con la información que tengo.