1. Introduzione
Che cosa creerai
Al termine di questo codelab, avrai un'app Jetpack Compose minima e funzionante con un'integrazione di Google Pay per Android. Questo progetto recupera un token di pagamento che può essere inviato a un fornitore di servizi di pagamento per l'elaborazione.
Obiettivi didattici
- Come installare e configurare la libreria Jetpack Compose di Google Pay
- Come visualizzare il pulsante Google Pay e gestire i clic
- Come richiedere un token di pagamento da Google Pay
Che cosa ti serve
- Android Studio (ultima versione stabile) installato.
- SDK Android e un emulatore o un dispositivo configurato in Android Studio.
- Per la produzione, avrai bisogno di un Google Pay
merchantId. La registrazione nella Console di Google Pay e Wallet richiede solo un minuto, quindi puoi occupartene subito.
2. Crea il progetto Jetpack Compose
Crea i file di progetto
- Crea un nuovo progetto Jetpack Compose in Android Studio denominato
gpay-compose:- Apri Android Studio e seleziona
New Project. - Scegli il modello
Empty Activity (Jetpack Compose). - Nome:
gpay-compose, nome del pacchetto:com.example.gpay. - Lingua: Kotlin, SDK minimo: API 21+.
- Completa la generazione del progetto.
- Apri Android Studio e seleziona
- Aggiungi la dipendenza del pulsante Google Pay Compose.Nel file
app/build.gradle(.kts), aggiungi: DSL 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' } - Aggiungi la dipendenza di Google Play Services Wallet (per aprire il foglio Google Pay):nel file
app/build.gradle(.kts), aggiungi la seguente dipendenza: Se il tuo progetto utilizza DSL Groovy, usa:dependencies { implementation("com.google.android.gms:play-services-wallet:19.3.0") }dependencies { implementation 'com.google.android.gms:play-services-wallet:19.3.0' } - Apri
MainActivity.ktin Android Studio e sostituisci i contenuti con il seguente scaffold dell'app Compose minima (collegheremo il pulsante nel passaggio successivo):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 richiesta di pagamento di Google Pay richiede un oggetto della richiesta. L'oggetto definito qui come baseGooglePayRequest contiene le impostazioni comuni minime per tutte le richieste. Verranno aggiunte impostazioni aggiuntive a seconda della richiesta effettuata, che esamineremo in questo codelab.
Aggiungi le costanti di configurazione di Google Pay a MainActivity.kt (le riutilizzerai nel passaggio successivo):
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()
Risorse
- Riferimento API: documentazione sugli oggetti della richiesta dell'API Google Pay
- Riferimento API: consulta
PaymentMethodper ulteriori informazioni sui metodi di autorizzazione consentiti, sulle reti di carte consentite e sulle specifiche di tokenizzazione, incluso il valore del gateway corretto.
4. Aggiungi il pulsante Google Pay
Utilizza il pulsante di pagamento Compose per eseguire il rendering di un pulsante Google Pay nativo e l'API Wallet per aprire il foglio Google Pay.
Sostituisci l'intero contenuto di MainActivity.kt con il seguente esempio completo (include configurazione, pulsante e flusso di pagamento):
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. Effettua una richiesta di pagamento
Quando viene premuto il pulsante Google Pay, requestPayment(...) crea un PaymentDataRequest aggiungendo transactionInfo a baseGooglePayRequest, apre il foglio Google Pay e restituisce un token di pagamento.
Punti chiave
- Pulsante:
PayButtonesegue il rendering del pulsante Google Pay nativo. - Client:
PaymentsClientè configurato con TEST o PRODUCTION. - Avvio: utilizza
loadPaymentDatae risolvi con unIntentSenderquando necessario. - Token: analizza
PaymentData.toJson()per estrarrepaymentMethodData.tokenizationData.tokene inviarlo al tuo PSP.
6. Conclusione
Congratulazioni per aver completato questo codelab. Hai imparato a integrare l'API Google Pay in un'app Jetpack Compose per Android.
Esegui il progetto
Esegui il progetto da Android Studio (Run > Run 'app') per avviare l'app.
Come procedere
Risorse aggiuntive
- Partecipa alla conversazione nel canale#payments su Discord
- Segui @GooglePayDevs su X
- Guarda i video correlati a Google Pay su YouTube