Google Pay API untuk Jetpack Compose di Android

1. Pengantar

Yang akan Anda build

Setelah menyelesaikan codelab ini, Anda akan memiliki aplikasi Jetpack Compose yang layak minimum dengan integrasi Google Pay yang berfungsi untuk Android. Project ini mengambil token pembayaran yang dapat dikirim ke penyedia layanan pembayaran untuk diproses.

Yang akan Anda pelajari

  • Cara menginstal dan mengonfigurasi library Jetpack Compose Google Pay
  • Cara menampilkan tombol Google Pay dan menangani klik
  • Cara meminta token pembayaran dari Google Pay

Yang Anda butuhkan

  • Android Studio (stabil terbaru) terinstal.
  • Android SDK dan emulator atau perangkat yang disiapkan di Android Studio.
  • Untuk produksi, Anda memerlukan merchantId Google Pay. Hanya perlu satu menit untuk mendaftar di Konsol Google Pay & Wallet, jadi sebaiknya selesaikan sekarang.

2. Buat project Jetpack Compose

Membuat file project

  1. Buat project Jetpack Compose baru di Android Studio yang diberi nama gpay-compose:
    • Buka Android Studio dan pilih New Project.
    • Pilih template Empty Activity (Jetpack Compose).
    • Nama: gpay-compose, Nama paket: com.example.gpay.
    • Bahasa: Kotlin, SDK Minimum: API 21+.
    • Selesaikan untuk membuat project.
  2. Tambahkan dependensi Tombol Compose Google Pay.Di file app/build.gradle(.kts) Anda, tambahkan:
    dependencies {
        implementation("com.google.pay.button:compose-pay-button:1.0.0")
    }
    
    DSL Groovy:
    dependencies {
        implementation 'com.google.pay.button:compose-pay-button:1.0.0'
    }
    
  3. Tambahkan dependensi Wallet layanan Google Play (untuk membuka halaman Google Pay):Di file app/build.gradle(.kts), tambahkan dependensi berikut:
    dependencies {
        implementation("com.google.android.gms:play-services-wallet:19.3.0")
    }
    
    Jika project Anda menggunakan Groovy DSL, gunakan:
    dependencies {
        implementation 'com.google.android.gms:play-services-wallet:19.3.0'
    }
    
  4. Buka MainActivity.kt di Android Studio dan ganti kontennya dengan scaffold aplikasi Compose minimal berikut (kita akan menghubungkan tombol berikutnya):
    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. Mengonfigurasi Google Pay

Permintaan pembayaran Google Pay memerlukan objek permintaan. Objek yang ditentukan di sini sebagai baseGooglePayRequest berisi setelan umum minimum untuk semua permintaan. Setelan tambahan akan ditambahkan bergantung pada permintaan yang dibuat dan akan kita tinjau dalam codelab ini.

Tambahkan konstanta konfigurasi Google Pay ke MainActivity.kt (Anda akan menggunakannya kembali pada langkah berikutnya):

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()

Resource

  • Referensi API: Dokumentasi objek permintaan Google Pay API
  • Referensi API: Lihat PaymentMethod untuk mengetahui informasi selengkapnya tentang metode otorisasi yang diizinkan, jaringan kartu yang diizinkan, dan spesifikasi tokenisasi termasuk nilai gateway yang tepat.

4. Menambahkan tombol Google Pay

Gunakan Tombol Pembayaran Compose untuk merender tombol Google Pay native, dan Wallet API untuk membuka halaman Google Pay.

Ganti seluruh konten MainActivity.kt dengan contoh lengkap berikut (mencakup konfigurasi + tombol + alur pembayaran):

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. Membuat permintaan pembayaran

Saat tombol Google Pay ditekan, requestPayment(...) akan membuat PaymentDataRequest dengan menambahkan transactionInfo ke baseGooglePayRequest Anda, membuka halaman Google Pay, dan menampilkan token pembayaran.

Poin utama

  • Tombol: PayButton merender tombol Google Pay asli.
  • Klien: PaymentsClient dikonfigurasi dengan TEST atau PRODUCTION.
  • Peluncuran: Gunakan loadPaymentData dan selesaikan dengan IntentSender jika diperlukan.
  • Token: Parsing PaymentData.toJson() untuk mengekstrak paymentMethodData.tokenizationData.token dan mengirimkannya ke PSP Anda.

6. Kesimpulan

Selamat, Anda telah menyelesaikan Codelab ini. Anda telah mempelajari cara mengintegrasikan Google Pay API ke aplikasi Jetpack Compose untuk Android.

Menjalankan project

Jalankan project dari Android Studio (Run > Run 'app') untuk memulai aplikasi Anda.

Tujuan berikutnya

Referensi lainnya