Інтеграція платежної системи Google Pay в мобільний додаток
Google Pay на Android працює через Google Pay API — це не окремий SDK, а частина Google Play Services. Інтеграція технічно простіша за Apple Pay: немає сертифікатів та окремого developer portal, тільки конфігурація PaymentDataRequest та обробка токена. Але точок, де можна помилитися, теж достатньо.
PaymentsClient та середовища ENVIRONMENT_TEST / ENVIRONMENT_PRODUCTION
Google Pay працює в двох середовищах. У ENVIRONMENT_TEST можна отримувати фіктивні токени без реальної карти — зручно для розробки. У ENVIRONMENT_PRODUCTION потрібно заранее пройти перевірку Google (заповнити форму у Google Pay Business Console та отримати одобрення).
private fun createPaymentsClient(activity: Activity): PaymentsClient {
val walletOptions = Wallet.WalletOptions.Builder()
.setEnvironment(WalletConstants.ENVIRONMENT_PRODUCTION)
.build()
return Wallet.getPaymentsClient(activity, walletOptions)
}
Налаштування PaymentDataRequest
private fun createPaymentDataRequest(price: String): PaymentDataRequest {
val tokenizationSpec = JSONObject().apply {
put("type", "PAYMENT_GATEWAY")
put("parameters", JSONObject().apply {
put("gateway", "stripe") // або "cloudpayments", "yookassa" та ін.
put("stripe:version", "2023-10-16")
put("stripe:publishableKey", "pk_live_...")
})
}
val cardPaymentMethod = JSONObject().apply {
put("type", "CARD")
put("parameters", JSONObject().apply {
put("allowedAuthMethods", JSONArray(listOf("PAN_ONLY", "CRYPTOGRAM_3DS")))
put("allowedCardNetworks", JSONArray(listOf("MASTERCARD", "VISA", "MIR")))
})
put("tokenizationSpecification", tokenizationSpec)
}
val request = JSONObject().apply {
put("apiVersion", 2)
put("apiVersionMinor", 0)
put("allowedPaymentMethods", JSONArray(listOf(cardPaymentMethod)))
put("transactionInfo", JSONObject().apply {
put("totalPrice", price)
put("totalPriceStatus", "FINAL")
put("currencyCode", "RUB")
put("countryCode", "RU")
})
put("merchantInfo", JSONObject().apply {
put("merchantName", "Your Company Name")
put("merchantId", "YOUR_MERCHANT_ID") // з Business Console
})
}
return PaymentDataRequest.fromJson(request.toString())
}
PAN_ONLY vs CRYPTOGRAM_3DS
Це часто вивищує питання. PAN_ONLY — карта додана в Google Pay через браузер або вручну, без 3DS-токена. CRYPTOGRAM_3DS — пристрій з апаратною защитою (SE або StrongBox), карта прошла токенізацію у Trusted Execution Environment. Для російських еквайєрів обидва метода підтримуються, але уточніть у провайдера — деякі приймають тільки CRYPTOGRAM_3DS для зниження фроду.
Запуск платіжного інтерфейса
private val paymentLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
when (result.resultCode) {
Activity.RESULT_OK -> {
val data = result.data ?: return@registerForActivityResult
val paymentData = PaymentData.getFromIntent(data)
val token = paymentData
?.paymentMethodToken
?.token // JSON-строка з токеном провайдера
// Передаємо token на бекенд
}
Activity.RESULT_CANCELED -> { /* користувач закрив */ }
AutoResolveHelper.RESULT_ERROR -> {
val status = AutoResolveHelper.getStatusFromIntent(result.data)
Log.e("GPay", "Error: ${status?.statusMessage}")
}
}
}
// Запуск
val task = paymentsClient.loadPaymentData(createPaymentDataRequest("1500.00"))
task.addOnCompleteListener { completedTask ->
if (completedTask.isSuccessful) {
paymentLauncher.launch(
IntentSenderRequest.Builder(
completedTask.result.resolutionPendingIntent!!.intentSender
).build()
)
}
}
Кнопка Google Pay: вимоги дизайну
Google жорстко регулює зовнішній вид кнопки. Не можна змінювати колір, шрифт, співвідношення сторін кнопки Google Pay. Google перевіряє це при ревю перед виходом у ENVIRONMENT_PRODUCTION.
Правильно використовувати готовий віджет:
val button = PayButton(context).apply {
initialize(
ButtonOptions.newBuilder()
.setButtonType(ButtonType.BUY)
.setCornerRadius(8)
.build()
)
}
isReadyToPay перед показом кнопки
Не показуйте кнопку Google Pay без перевірки:
val isReadyToPayRequest = IsReadyToPayRequest.fromJson(
JSONObject().apply {
put("apiVersion", 2)
put("apiVersionMinor", 0)
put("allowedPaymentMethods", JSONArray(listOf(cardPaymentMethod)))
}.toString()
)
paymentsClient.isReadyToPay(isReadyToPayRequest)
.addOnSuccessListener { result ->
googlePayButton.isVisible = result
}
Якщо карта не додана в Google Pay або пристрій несумісний — кнопку показувати не потрібно.
Що входить у роботу
- Налаштування PaymentsClient з правильним environment
- Конфігурація tokenizationSpecification під платіжного провайдера
- Реалізація isReadyToPay та коректне приховування кнопки
- Обробка PaymentData та передача токена на бекенд
- Прохождення ревю Google Pay Business Console
Строки
2–3 дні. Вартість розраховується індивідуально.







