1. Введение
Что вы построите
По завершении этого практического занятия у вас будет минимально работоспособное приложение Jetpack Compose с интеграцией Google Pay для Android. Этот проект получает платежный токен, который может быть отправлен поставщику платежных услуг для обработки.
Что вы узнаете
- Как установить и настроить библиотеку Google Pay Jetpack Compose
- Как отобразить кнопку Google Pay и обрабатывать клики.
- Как запросить платежный токен в Google Pay
Что вам понадобится
- Установлена версия Android Studio (последняя стабильная).
- Android SDK и эмулятор или устройство, настроенные в Android Studio.
- Для запуска в производство вам потребуется
merchantIdGoogle Pay. Регистрация в консоли Google Pay & Wallet займет всего минуту, так что можете позаботиться об этом прямо сейчас.
2. Создайте проект Jetpack Compose.
Создайте файлы проекта
- Создайте в Android Studio новый проект Jetpack Compose с именем
gpay-compose:- Откройте Android Studio и выберите
New Project. - Выберите шаблон «
Empty Activity (Jetpack Compose). - Имя:
gpay-compose, Имя пакета:com.example.gpay. - Язык программирования: Kotlin, минимальный набор SDK: API 21+.
- Завершите процесс, чтобы сгенерировать проект.
- Откройте Android Studio и выберите
- Добавьте зависимость кнопки «Оформить заказ» от Google Pay. В файл
app/build.gradle(.kts)добавьте: Groovy DSL:dependencies { implementation("com.google.pay.button:compose-pay-button:1.0.0") }dependencies { implementation 'com.google.pay.button:compose-pay-button:1.0.0' } - Добавьте зависимость Google Play Services Wallet (для открытия окна Google Pay): В файле
app/build.gradle(.kts)добавьте следующую зависимость: Если в вашем проекте используется Groovy DSL, используйте:dependencies { implementation("com.google.android.gms:play-services-wallet:19.3.0") }dependencies { implementation 'com.google.android.gms:play-services-wallet:19.3.0' } - Откройте
MainActivity.ktв Android Studio и замените его содержимое следующим минимальным шаблоном приложения Compose (кнопку мы добавим позже):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. Настройка Google Pay
Для отправки платежа через Google Pay требуется объект запроса. Объект, определенный здесь как baseGooglePayRequest содержит минимальные общие настройки для всех запросов. Дополнительные настройки будут добавляться в зависимости от сделанного запроса, что мы рассмотрим в этом практическом занятии.
Добавьте константы конфигурации Google Pay в MainActivity.kt (вы будете использовать их повторно на следующем шаге):
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()
Ресурсы
- Справочник по API : документация по объектам запросов API Google Pay.
- Справочник API : Для получения дополнительной информации о разрешенных методах авторизации, разрешенных платежных сетях и спецификациях токенизации, включая правильное значение платежного шлюза, обратитесь к разделу
PaymentMethod
4. Добавьте кнопку Google Pay.
Используйте кнопку «Создать платеж», чтобы отобразить стандартную кнопку Google Pay, и API Wallet, чтобы открыть окно Google Pay.
Замените всё содержимое файла MainActivity.kt следующим полным примером (включая конфигурацию + кнопку + процесс оплаты):
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. Отправьте запрос на оплату.
При нажатии кнопки Google Pay requestPayment(...) формирует объект PaymentDataRequest , добавляя transactionInfo к вашему baseGooglePayRequest , открывает окно Google Pay и возвращает платежный токен.
Ключевые моменты
- Button:
PayButtonотображает стандартную кнопку Google Pay. - Клиент:
PaymentsClientнастроен на тестовую или производственную среду. - Запуск: Используйте
loadPaymentDataи при необходимости вызовитеIntentSender. - Токен: Используйте метод Pars
PaymentData.toJson()для извлеченияpaymentMethodData.tokenizationData.tokenи отправки их в вашу платежную систему.
6. Заключение
Поздравляем с завершением этого практического занятия! Вы научились интегрировать API Google Pay в приложение Jetpack Compose для Android.
Запустите проект
Запустите проект из Android Studio ( Run > Run 'app' ), чтобы запустить приложение.
Что делать дальше?
Дополнительные ресурсы
- Присоединяйтесь к обсуждению в канале #payments в Discord.
- Подписывайтесь на @GooglePayDevs в X
- Смотрите видеоролики, посвященные Google Pay, на YouTube.