1. Introduzione
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.
- L'SDK Android e un emulatore o un dispositivo configurato in Android Studio.
- Per la produzione, avrai bisogno di un
merchantIdGoogle Pay. La registrazione alla console di Google Pay e Wallet richiede solo un minuto, quindi tanto vale occuparsene subito.
2. Crea il progetto Jetpack Compose
Creare 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 pacchetto:com.example.gpay. - Linguaggio: Kotlin, SDK minimo: API 21+.
- Fai clic su Fine per generare il progetto.
- Apri Android Studio e seleziona
- Aggiungi la dipendenza del pulsante di composizione di Google Pay.Nel file
app/build.gradle(.kts), aggiungi: Groovy DSL:dependencies { implementation("com.google.pay.button:compose-pay-button:1.2.0") }dependencies { implementation 'com.google.pay.button:compose-pay-button:1.2.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 Groovy DSL, utilizza:dependencies { implementation("com.google.android.gms:play-services-wallet:19.5.0") }dependencies { implementation 'com.google.android.gms:play-services-wallet:19.5.0' } - Apri
MainActivity.ktin Android Studio e sostituisci i contenuti con la seguente struttura di base dell'app Compose minima (collegheremo il pulsante in un secondo momento):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. Configurare Google Pay
Una richiesta di pagamento Google Pay richiede un oggetto richiesta. L'oggetto definito qui come baseGooglePayRequest contiene le impostazioni comuni minime per tutte le richieste. A seconda della richiesta effettuata, verranno aggiunte impostazioni aggiuntive 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 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. Aggiungere il pulsante Google Pay
Utilizza il pulsante di composizione di Google Pay 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. Effettuare una richiesta di pagamento
Quando viene premuto il pulsante Google Pay, requestPayment(...) crea un PaymentDataRequest aggiungendo transactionInfo al tuo 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