1. Introduction
Objectifs de l'atelier
À la fin de cet atelier de programmation, vous disposerez d'une application Jetpack Compose viable minimale avec une intégration Google Pay fonctionnelle pour Android. Ce projet récupère un jeton de paiement qui peut être envoyé à un fournisseur de services de paiement pour traitement.
Points abordés
- Installer et configurer la bibliothèque Google Pay Jetpack Compose
- Afficher le bouton Google Pay et gérer les clics
- Demander un jeton de paiement à Google Pay
Ce dont vous avez besoin
- Android Studio (dernière version stable) installé.
- SDK Android et émulateur ou appareil configuré dans Android Studio.
- Pour la production, vous aurez besoin d'un Google Pay
merchantId. L'inscription à la Google Pay & Wallet Console ne prend qu'une minute. Vous pouvez donc le faire dès maintenant.
2. Créer le projet Jetpack Compose
Créer des fichiers de projet
- Créez un projet Jetpack Compose dans Android Studio nommé
gpay-compose:- Ouvrez Android Studio, puis sélectionnez
New Project(Nouveau projet). - Choisissez le modèle
Empty Activity (Jetpack Compose). - Nom :
gpay-compose, nom du package :com.example.gpay. - Langue : Kotlin, SDK minimal : API 21+.
- Cliquez sur "Finish" (Terminer) pour générer le projet.
- Ouvrez Android Studio, puis sélectionnez
- Ajoutez la dépendance du bouton Google Pay Compose.Dans le fichier
app/build.gradle(.kts), ajoutez : 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' } - Ajoutez la dépendance Google Play Services Wallet (pour ouvrir la fiche Google Pay) : dans le fichier
app/build.gradle(.kts), ajoutez la dépendance suivante : Si votre projet utilise le DSL Groovy, utilisez :dependencies { implementation("com.google.android.gms:play-services-wallet:19.3.0") }dependencies { implementation 'com.google.android.gms:play-services-wallet:19.3.0' } - Ouvrez
MainActivity.ktdans Android Studio et remplacez le contenu par la structure d'application Compose minimale suivante (nous connecterons le bouton ensuite) :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. Configurer Google Pay
Une demande de paiement Google Pay nécessite un objet de requête. L'objet défini ici comme baseGooglePayRequest contient les paramètres communs minimaux pour toutes les requêtes. Des paramètres supplémentaires seront ajoutés en fonction de la requête effectuée, que nous examinerons dans cet atelier de programmation.
Ajoutez les constantes de configuration Google Pay à MainActivity.kt (vous les réutiliserez à l'étape suivante) :
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()
Ressources
- Documentation de référence sur les API : documentation sur les objets de requête de l'API Google Pay
- Documentation de référence sur les API : consultez
PaymentMethodpour en savoir plus sur les méthodes d'autorisation autorisées, les réseaux de cartes autorisés et les spécifications de tokenisation, y compris la valeur de passerelle appropriée.
4. Ajouter le bouton Google Pay
Utilisez le bouton Compose Pay pour afficher un bouton Google Pay natif et l'API Wallet pour ouvrir la fiche Google Pay.
Remplacez l'intégralité du contenu de MainActivity.kt par l'exemple complet suivant (inclut la configuration, le bouton et le flux de paiement) :
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. Effectuer une demande de paiement
Lorsque vous appuyez sur le bouton Google Pay, requestPayment(...) crée un PaymentDataRequest en ajoutant transactionInfo à votre baseGooglePayRequest, ouvre la fiche Google Pay et renvoie un jeton de paiement.
Points essentiels
- Bouton :
PayButtonaffiche le bouton Google Pay natif. - Client :
PaymentsClientest configuré avec TEST ou PRODUCTION. - Lancement : utilisez
loadPaymentDataet résolvez avec unIntentSendersi nécessaire. - Jeton : analysez
PaymentData.toJson()pour extrairepaymentMethodData.tokenizationData.tokenet envoyez-le à votre PSP.
6. Conclusion
Félicitations ! Vous avez terminé cet atelier de programmation. Vous avez appris à intégrer l'API Google Pay dans une application Jetpack Compose pour Android.
Exécuter le projet
Exécutez le projet à partir d'Android Studio (Run > Run 'app') pour démarrer votre application.
Étapes suivantes
Ressources supplémentaires
- Participez à la conversation sur le canal#payments de Discord.
- Suivez @GooglePayDevs sur X.
- Regardez des vidéos sur Google Pay sur YouTube.