Incluir Botón de Google pay en mi App
Integración del SDK de Google Pay (Mobile)
Esta guía cubre la integración de Google Pay en apps móviles para Android e iOS.
Para integrar Google Pay en sitios web, consulta la Integración Web.
Android (Google Pay SDK nativo)
1. Agregar dependencias
En el archivo build.gradle del módulo de la app:
dependencies {
implementation 'com.google.android.gms:play-services-wallet:19.3.0'
}En AndroidManifest.xml, agregar el meta-data de Google Pay:
<application>
<!-- ... -->
<meta-data
android:name="com.google.android.gms.wallet.api.enabled"
android:value="true" />
</application>2. Configurar el PaymentsClient
import com.google.android.gms.wallet.*
val paymentsClient: PaymentsClient = Wallet.getPaymentsClient(
this, // Activity o Context
Wallet.WalletOptions.Builder()
.setEnvironment(WalletConstants.ENVIRONMENT_TEST) // Cambiar a ENVIRONMENT_PRODUCTION en producción
.build()
)3. Verificar disponibilidad de Google Pay
val isReadyToPayRequest = IsReadyToPayRequest.newBuilder()
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
.build()
paymentsClient.isReadyToPay(isReadyToPayRequest)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// Mostrar botón de Google Pay
showGooglePayButton()
}
}4. Construir el PaymentDataRequest
val tokenizationSpec = PaymentMethodTokenizationParameters.newBuilder()
.setPaymentMethodTokenizationType(WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY)
.addParameter("gateway", "conektagpay")
.addParameter("gatewayMerchantId", "conekta")
.build()
val paymentDataRequest = PaymentDataRequest.newBuilder()
.setTransactionInfo(
TransactionInfo.newBuilder()
.setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
.setTotalPrice("100.00") // Monto del cobro
.setCurrencyCode("MXN")
.build()
)
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
.setCardRequirements(
CardRequirements.newBuilder()
.addAllowedCardNetworks(
listOf(
WalletConstants.CARD_NETWORK_VISA,
WalletConstants.CARD_NETWORK_MASTERCARD,
WalletConstants.CARD_NETWORK_AMEX
)
)
.build()
)
.setPaymentMethodTokenizationParameters(tokenizationSpec)
.build()Importante: Los parámetros del gateway deben ser exactamente
gateway: "conektagpay"ygatewayMerchantId: "conekta", igual que en la integración web.
5. Lanzar el flujo de pago y capturar el token
private val GOOGLE_PAY_REQUEST_CODE = 991
fun requestPayment() {
AutoResolveHelper.resolveTask(
paymentsClient.loadPaymentData(paymentDataRequest),
this, // Activity
GOOGLE_PAY_REQUEST_CODE
)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == GOOGLE_PAY_REQUEST_CODE) {
when (resultCode) {
Activity.RESULT_OK -> {
val paymentData = PaymentData.getFromIntent(data!!)
val token = paymentData?.paymentMethodToken?.token ?: return
// Enviar al backend para crear el cargo en Conekta
sendTokenToBackend(token, paymentData)
}
Activity.RESULT_CANCELED -> {
// Usuario canceló el pago
}
AutoResolveHelper.RESULT_ERROR -> {
val status = AutoResolveHelper.getStatusFromIntent(data)
Log.e("GooglePay", "Error: ${status?.statusMessage}")
}
}
}
}6. Enviar el token al backend
fun sendTokenToBackend(token: String, paymentData: PaymentData) {
// El token debe codificarse en base64 antes de enviarlo a Conekta
val tokenBase64 = Base64.encodeToString(token.toByteArray(), Base64.NO_WRAP)
val payload = JSONObject().apply {
put("token", tokenBase64)
put("card_network", "VISA") // Extraer de paymentData
put("card_details", "1234") // Extraer de paymentData
put("card_funding_source", "credit")
put("description", "Visa •••• 1234")
}
// Enviar payload al backend del merchant,
// que a su vez crea el cargo en Conekta (ver api-conekta.md)
}El payload que el backend envía a Conekta es idéntico al de la integración web. Consulta API de Conekta para el detalle completo.
iOS (Google Pay SDK para iOS)
Google Pay en iOS se integra a través del SDK GooglePayButton disponible via Swift Package Manager o CocoaPods.
1. Agregar dependencia
Swift Package Manager:
En Xcode, agregar el paquete: https://github.com/nicklama/google-pay-button-ios
CocoaPods:
pod 'GooglePayButton'2. Configurar el botón de Google Pay
import GooglePayButton
class CheckoutViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let googlePayButton = GooglePayButton(
configuration: GooglePayButton.Configuration(
buttonType: .pay,
buttonStyle: .black,
cornerRadius: 8
)
)
googlePayButton.addTarget(self, action: #selector(googlePayTapped), for: .touchUpInside)
view.addSubview(googlePayButton)
}
}3. Construir el PaymentDataRequest
let paymentDataRequest: [String: Any] = [
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [[
"type": "CARD",
"parameters": [
"allowedAuthMethods": ["CRYPTOGRAM_3DS"],
"allowedCardNetworks": ["VISA", "MASTERCARD", "AMEX"],
"assuranceDetailsRequired": true
],
"tokenizationSpecification": [
"type": "PAYMENT_GATEWAY",
"parameters": [
"gateway": "conektagpay",
"gatewayMerchantId": "conekta"
]
]
]],
"transactionInfo": [
"totalPriceStatus": "FINAL",
"totalPrice": "100.00",
"currencyCode": "MXN",
"countryCode": "MX"
],
"merchantInfo": [
"merchantId": "<GOOGLE_MERCHANT_ID>", // De Google Pay & Wallet Console (producción)
"merchantName": "Nombre del Merchant"
]
]4. Lanzar el flujo y capturar el token
@objc func googlePayTapped() {
// Presentar el flujo de Google Pay con el paymentDataRequest
// El SDK retorna un PaymentData con la misma estructura que en web/Android
// Al recibir el paymentData:
handlePaymentData(paymentData)
}
func handlePaymentData(_ paymentData: [String: Any]) {
guard let paymentMethodData = paymentData["paymentMethodData"] as? [String: Any],
let tokenizationData = paymentMethodData["tokenizationData"] as? [String: Any],
let token = tokenizationData["token"] as? String,
let info = paymentMethodData["info"] as? [String: Any] else {
return
}
// El token debe codificarse en base64 antes de enviarlo a Conekta
let tokenData = Data(token.utf8)
let tokenBase64 = tokenData.base64EncodedString()
let payload: [String: Any] = [
"token": tokenBase64,
"card_network": info["cardNetwork"] ?? "",
"card_details": info["cardDetails"] ?? "",
"card_funding_source": ((info["cardFundingSource"] as? String) ?? "CREDIT").lowercased(),
"description": paymentMethodData["description"] ?? ""
]
// Enviar payload al backend del merchant,
// que a su vez crea el cargo en Conekta (ver api-conekta.md)
sendToBackend(payload)
}Notas Importantes para Ambas Plataformas
Parámetros del gateway
Los parámetros de tokenización son los mismos en todas las plataformas:
| Parámetro | Valor | Descripción |
|---|---|---|
gateway | conektagpay | Identificador de Conekta en Google Pay |
gatewayMerchantId | conekta | Valor fijo |
Método de autenticación
Solo se soporta CRYPTOGRAM_3DS. No usar PAN_ONLY.
Codificación del token
En todas las plataformas, el token retornado por Google Pay debe codificarse en base64 antes de enviarlo a Conekta:
| Plataforma | Codificación |
|---|---|
| Android (Kotlin) | Base64.encodeToString(token.toByteArray(), Base64.NO_WRAP) |
| iOS (Swift) | Data(token.utf8).base64EncodedString() |
Payload a Conekta
El payload que el backend del merchant envía a la API de Conekta es idéntico sin importar si el token proviene de web, Android o iOS. Consulta API de Conekta para el formato completo.
Ambientes
| Ambiente | Android | iOS |
|---|---|---|
| Pruebas | WalletConstants.ENVIRONMENT_TEST | environment: .test |
| Producción | WalletConstants.ENVIRONMENT_PRODUCTION | environment: .production |
En ambiente de pruebas, Google Pay muestra tarjetas de prueba automáticamente sin necesidad de registro en Google Pay & Wallet Console.
Updated 6 days ago
