1. Introducción
Qué compilarás
Cuando completes este codelab, tendrás una app de Jetpack Compose mínima viable con una integración de Google Pay para Android que funcione. Este proyecto recupera un token de pago que se puede enviar a un proveedor de servicios de pago para su procesamiento.
Qué aprenderás
- Cómo instalar y configurar la biblioteca de Jetpack Compose de Google Pay
- Cómo mostrar el botón de Google Pay y controlar los clics
- Cómo solicitar un token de pago a Google Pay
Requisitos
- Android Studio (la versión estable más reciente) instalado
- SDK de Android y un emulador o dispositivo configurado en Android Studio
- Para la producción, necesitarás un Google Pay
merchantId. Solo toma un minuto registrarse en la Consola de Google Pay y la Billetera, así que puedes hacerlo ahora.
2. Crea el proyecto de Jetpack Compose
Crea archivos de proyecto
- Crea un nuevo proyecto de Jetpack Compose en Android Studio llamado
gpay-compose:- Abre Android Studio y selecciona
New Project. - Elige la plantilla
Empty Activity (Jetpack Compose). - Nombre:
gpay-compose, nombre del paquete:com.example.gpay. - Idioma: Kotlin, SDK mínimo: API 21+.
- Haz clic en Finish para generar el proyecto.
- Abre Android Studio y selecciona
- Agrega la dependencia del botón de Compose de Google Pay.En tu archivo
app/build.gradle(.kts), agrega lo siguiente: DSL de Groovy:dependencies { implementation("com.google.pay.button:compose-pay-button:1.0.0") }dependencies { implementation 'com.google.pay.button:compose-pay-button:1.0.0' } - Agrega la dependencia de la Billetera de los Servicios de Google Play (para abrir la hoja de Google Pay).En tu archivo
app/build.gradle(.kts), agrega la siguiente dependencia: Si tu proyecto usa DSL de Groovy, usa lo siguiente:dependencies { implementation("com.google.android.gms:play-services-wallet:19.3.0") }dependencies { implementation 'com.google.android.gms:play-services-wallet:19.3.0' } - Abre
MainActivity.kten Android Studio y reemplaza el contenido por el siguiente scaffold mínimo de la app de Compose (conectaremos el botón a continuación):package com.example.gpay import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { // Google Pay button added in the next section } } } } }
3. Configura Google Pay
Una solicitud de pago de Google Pay requiere un objeto de solicitud. El objeto definido aquí como baseGooglePayRequest contiene la configuración común mínima para todas las solicitudes. Se agregarán parámetros de configuración adicionales según la solicitud realizada, que revisaremos en este codelab.
Agrega las constantes de configuración de Google Pay a MainActivity.kt (las volverás a usar en el siguiente paso):
private const val merchantId = "12345678901234567890"
// This is the base configuration for all Google Pay payment data requests.
private val baseGooglePayRequest = """
{
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"parameters": {
"allowedAuthMethods": [
"PAN_ONLY", "CRYPTOGRAM_3DS"
],
"allowedCardNetworks": [
"AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"
]
},
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "example",
"gatewayMerchantId": "exampleGatewayMerchantId"
}
}
}
],
"merchantInfo": {
"merchantId": "$merchantId"
}
}
""".trimIndent()
Recursos
- Referencia de la API: Documentación de los objetos de solicitud de la API de Google Pay
- Referencia de la API: Consulta
PaymentMethodpara obtener más información sobre los métodos de autorización permitidos, las redes de tarjetas permitidas y las especificaciones de tokenización, incluido el valor de puerta de enlace adecuado.
4. Agrega el botón de Google Pay
Usa el botón de pago de Compose para renderizar un botón nativo de Google Pay y la API de Wallet para abrir la hoja de Google Pay.
Reemplaza todo el contenido de MainActivity.kt por el siguiente ejemplo completo (incluye configuración + botón + flujo de pago):
package com.example.gpay
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.tasks.Task
import com.google.android.gms.wallet.contract.TaskResultContracts.GetPaymentDataResult
import com.google.android.gms.wallet.*
import com.google.pay.button.ButtonTheme
import com.google.pay.button.ButtonType
import com.google.pay.button.PayButton
import org.json.JSONObject
private const val merchantId = "12345678901234567890"
// Base Google Pay request used for both the button and the Wallet request
private val baseGooglePayRequest = """
{
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"parameters": {
"allowedAuthMethods": [
"PAN_ONLY", "CRYPTOGRAM_3DS"
],
"allowedCardNetworks": [
"AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"
]
},
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "example",
"gatewayMerchantId": "exampleGatewayMerchantId"
}
}
}
],
"merchantInfo": {
"merchantId": "$merchantId"
}
}
""".trimIndent()
class MainActivity : ComponentActivity() {
private val paymentDataLauncher = registerForActivityResult(GetPaymentDataResult()) { taskResult ->
when (taskResult.status.statusCode) {
CommonStatusCodes.SUCCESS -> {
handlePaymentData(taskResult.result!!)
}
//CommonStatusCodes.CANCELED -> The user canceled
//CommonStatusCodes.DEVELOPER_ERROR -> The API returned an error (it.status: Status)
//else -> Handle internal and other unexpected errors
}
}
private lateinit var paymentsClient: PaymentsClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create the PaymentsClient
paymentsClient = Wallet.getPaymentsClient(
this,
Wallet.WalletOptions.Builder()
.setEnvironment(WalletConstants.ENVIRONMENT_TEST) // Switch to PRODUCTION when ready
.build()
)
// Derive allowedPaymentMethods for the button from baseGooglePayRequest
val allowedPaymentMethods = JSONObject(baseGooglePayRequest)
.getJSONArray("allowedPaymentMethods")
.toString()
setContent {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PayButton(
onClick = { requestPayment(paymentDataLauncher) },
allowedPaymentMethods = allowedPaymentMethods,
type = ButtonType.Pay,
theme = ButtonTheme.Light
)
}
}
}
private fun requestPayment(launcher: ActivityResultLauncher<Task<PaymentData>>) {
// Build a PaymentDataRequest from the base request by adding transaction info
val requestJson = JSONObject(baseGooglePayRequest).apply {
put("transactionInfo", JSONObject().apply {
put("totalPrice", "14.95")
put("totalPriceStatus", "FINAL")
put("countryCode", "US")
put("currencyCode", "USD")
})
}
val request = PaymentDataRequest.fromJson(requestJson.toString())
val task = paymentsClient.loadPaymentData(request)
task.addOnCompleteListener(paymentDataLauncher::launch)
}
private fun handlePaymentData(paymentData: PaymentData?) {
val json = paymentData?.toJson() ?: return
val paymentMethodData = JSONObject(json).getJSONObject("paymentMethodData")
val tokenizationData = paymentMethodData.getJSONObject("tokenizationData")
val token = tokenizationData.getString("token")
// Send 'token' to your payment service provider (PSP)
println("Payment token: $token")
}
}
5. Realiza una solicitud de pago
Cuando se presiona el botón de Google Pay, requestPayment(...) compila un PaymentDataRequest agregando transactionInfo a tu baseGooglePayRequest, abre la hoja de Google Pay y muestra un token de pago.
Puntos clave
- Botón:
PayButtonrenderiza el botón nativo de Google Pay. - Cliente:
PaymentsClientse configura con TEST o PRODUCTION. - Lanzamiento: Usa
loadPaymentDatay resuelve con unIntentSendercuando sea necesario. - Token: Analiza
PaymentData.toJson()para extraerpaymentMethodData.tokenizationData.tokeny enviarlo a tu PSP.
6. Conclusión
¡Felicitaciones por completar este codelab! Aprendiste a integrar la API de Google Pay en una app de Jetpack Compose para Android.
Cómo ejecutar el proyecto
Ejecuta el proyecto desde Android Studio (Run > Run 'app') para iniciar tu app.
Lo que vendrá
Recursos adicionales
- Únete a la conversación en el canal#payments de Discord
- Sigue a @GooglePayDevs en X
- Mira videos relacionados con Google Pay en YouTube