# Implementation

Learn how to use the Google Pay component for Android in your project.

## Overview

Every component follows the same basic two-step lifecycle:

1. Create the component and configure it with your settings.
2. Render the component using Jetpack Compose. This makes the component visible and interactive. Cleanup happens automatically when the Composable leaves composition.


## Before you start

To use the Google Pay button component, you first need to:

* [Install the Android SDK](/guides/checkout/components/android/install).
* Complete the Google Pay onboarding process in the Unity Portal. See [Onboarding](/guides/checkout/components/android/google-pay/onboarding) for details.
* Configure your Google Pay merchant account and link it to the Unity Portal.


## Step 1: Initialise the SDK

To get started, initialise the PXP Checkout SDK with your merchant credentials and transaction data.


```kotlin
import com.pxp.PxpCheckout
import com.pxp.checkout.models.*
import com.pxp.checkout.services.models.transaction.Shopper
import java.text.SimpleDateFormat
import java.util.*

class PaymentActivity : ComponentActivity() {

    private lateinit var pxpCheckout: PxpCheckout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Get session config from your backend API
        val sessionConfig = fetchSessionFromYourBackend()

        // Initialise PxpCheckout SDK
        pxpCheckout = PxpCheckout.builder()
            .withConfig(
                PxpSdkConfig(
                    environment = Environment.TEST,
                    session = sessionConfig,
                    ownerId = "your-owner-id",
                    ownerType = "MerchantGroup",
                    kountDisabled = false, // OPTIONAL: Set to true to disable Kount fraud detection
                    transactionData = TransactionData(
                        amount = 99.99,
                        currency = "GBP",
                        merchant = "your-merchant-id",
                        merchantTransactionId = UUID.randomUUID().toString(),
                        merchantTransactionDate = {
                            SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
                                .apply { timeZone = TimeZone.getTimeZone("UTC") }
                                .format(Date())
                        },
                        entryType = EntryType.Ecom,
                        intent = TransactionIntentData(
                            card = IntentType.Authorisation
                        )
                    ),
                    onGetShopper = {
                        // Return current shopper data dynamically
                        Shopper(
                            id = "shopper-${System.currentTimeMillis()}",
                            email = "customer@example.com",
                            firstName = "John",
                            lastName = "Doe"
                        )
                    },
                    onGetShippingAddress = {
                        // Return current shipping address dynamically (optional)
                        ShippingAddress(
                            addressLine1 = "123 Main Street",
                            city = "London",
                            postalCode = "SW1A 1AA",
                            countryCode = "GB"
                        )
                    }
                )
            )
            .withContext(this)
            .build()

        setContent {
            YourAppTheme {
                PaymentScreen(pxpCheckout = pxpCheckout)
            }
        }
    }

    private fun fetchSessionFromYourBackend(): SessionConfig {
        // Call your merchant backend API to create a session
        // Your backend should call PXP API to create a session
        return SessionConfig(
            sessionId = "session-123",
            hmacKey = "hmac-key",
            data = "session-data",
            encryptionKey = "encryption-key",
            locale = "en-GB"
        )
    }
}
```

| Parameter | Description |
|  --- | --- |
| `environment`Environment | The environment type.Possible values:`Environment.TEST`: Sandbox.`Environment.LIVE`: Live payments. |
| `session`SessionConfig | Session configuration obtained from your backend. |
| `session.sessionId`String | Unique session identifier. |
| `session.hmacKey`String | HMAC key for session validation. |
| `session.data`String | Session data payload. |
| `session.encryptionKey`String | Encryption key for secure data transmission. |
| `ownerId`String | The identifier of the owner. |
| `ownerType`String | The type of owner. Use `"MerchantGroup"`. |
| `kountDisabled`Boolean | Whether to disable the Kount fraud detection service. Defaults to `false` (fraud detection enabled). |
| `onGetShopper`() -> Shopper? | Callback function to provide shopper data dynamically. Returns `Shopper` object from `com.pxp.checkout.services.models.transaction` package with shopper information including ID, email, name, and contact details. Required when using consent tokens for storing payment methods. |
| `onGetShippingAddress`() -> ShippingAddress? | Callback function to provide shipping address dynamically. Returns `ShippingAddress` object from `com.pxp.checkout.models` package with shipping address information. Optional. |
| `transactionData`TransactionData | Details about the transaction. |
| `transactionData.amount`Double | Transaction amount. |
| `transactionData.currency`String (3 characters) | Currency code in ISO 4217 format (e.g., `"GBP"`, `"USD"`, `"EUR"`). |
| `transactionData.merchant`String | Your merchant identifier. |
| `transactionData.merchantTransactionId`String | Your unique identifier for this transaction. |
| `transactionData.merchantTransactionDate`() -> String | Function that returns the transaction date in ISO 8601 format. |
| `transactionData.entryType`EntryType | Entry type. Use `EntryType.Ecom` for e-commerce transactions. |
| `transactionData.intent`TransactionIntentData | Transaction intents for each payment method.Possible values for card:`IntentType.Authorisation``IntentType.Purchase``IntentType.Verification``IntentType.EstimatedAuthorisation` |


## Step 2: Configure the Google Pay component

Create the configuration for your Google Pay button with payment settings and event handlers.

The SDK automatically configures `tokenizationSpecification` and `merchantInfo` with the correct gateway, merchant ID, and merchant name from your session. You only need to provide `allowedPaymentMethods` with the card parameters and `transactionInfo`.


```kotlin
import com.pxp.checkout.components.googlepay.types.*
import com.pxp.checkout.services.kount.*
import com.pxp.checkout.models.MerchantSubmitResult
import com.pxp.checkout.models.FailedSubmitResult

val googlePayConfig = GooglePayButtonComponentConfig().apply {
    
    // Button style
    style = GooglePayButtonStyle(
        type = GooglePayButtonType.PAY,
        theme = GooglePayButtonTheme.DARK,
        cornerRadius = 8
    )
    
    // Payment data request (REQUIRED)
    paymentDataRequest = PaymentDataRequest(
        allowedPaymentMethods = listOf(
            PaymentMethodSpecification(
                parameters = PaymentMethodParameters(
                    allowedCardNetworks = listOf(
                        CardNetwork.VISA,
                        CardNetwork.MASTERCARD,
                        CardNetwork.AMEX
                    ),
                    allowedAuthMethods = listOf(
                        CardAuthMethod.PAN_ONLY,
                        CardAuthMethod.CRYPTOGRAM_3DS
                    )
                )
            )
        ),
        transactionInfo = TransactionInfo(
            currencyCode = "GBP",
            totalPriceStatus = TotalPriceStatus.FINAL,
            totalPrice = "99.99"
        )
    )
    
    // Pre-authorisation callback
    onPreAuthorisation = suspend { preAuthData ->
        Log.d("GooglePay", "Processing payment")
        
        // Return risk screening data
        GooglePayTransactionInitData(
            riskScreeningData = RiskScreeningData(
                performRiskScreening = true,
                excludeDeviceData = false,
                userIp = "192.168.1.100",
                account = RiskScreeningAccount(
                    id = "user_12345678",
                    creationDateTime = "2024-01-15T10:30:00.000Z"
                ),
                items = listOf(
                    RiskScreeningItem(
                        price = 99.99,
                        quantity = 1,
                        category = "Electronics",
                        sku = "GPAY-001"
                    )
                ),
                fulfillments = listOf(
                    RiskScreeningFulfillment(
                        type = FulfillmentType.SHIPPED,
                        shipping = RiskScreeningShipping(
                            shippingMethod = ShippingMethod.STANDARD
                        ),
                        recipientPerson = RiskScreeningRecipientPerson(
                            phoneNumber = "+1234567890"
                        )
                    )
                )
            )
        )
    }
    
    // Handle successful payment
    onPostAuthorisation = { result, paymentData ->
        when (result) {
            is MerchantSubmitResult -> {
                Log.d("GooglePay", "Payment successful: ${result.systemTransactionId}")
                handlePaymentSuccess(result)
            }
            is FailedSubmitResult -> {
                Log.e("GooglePay", "Payment failed: ${result.errorReason}")
                handlePaymentFailure(result)
            }
        }
    }
    
    // Handle errors
    onError = { error ->
        Log.e("GooglePay", "Error: ${error.message}")
        showError(error.message)
    }
}
```

## Step 3: Create and render the component

Create the Google Pay component and render it in your Compose UI.


```kotlin
import com.pxp.checkout.components.googlepay.GooglePayButtonComponent
import com.pxp.checkout.types.ComponentType

@Composable
fun PaymentScreen(pxpCheckout: PxpCheckout) {
    
    val googlePayComponent = remember {
        pxpCheckout.createComponent<GooglePayButtonComponent, GooglePayButtonComponentConfig>(
            type = ComponentType.GOOGLE_PAY_BUTTON,
            config = googlePayConfig
        )
    }
    
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Complete your purchase",
            style = MaterialTheme.typography.headlineMedium,
            modifier = Modifier.padding(bottom = 16.dp)
        )
        
        // Render the Google Pay button
        googlePayComponent?.Content(
            modifier = Modifier
                .fillMaxWidth()
                .height(56.dp)
        )
    }
}
```

## Complete example

Here's a complete working example that puts everything together:


```kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import com.pxp.PxpCheckout
import com.pxp.checkout.components.googlepay.GooglePayButtonComponent
import com.pxp.checkout.components.googlepay.types.*
import com.pxp.checkout.models.*
import com.pxp.checkout.services.kount.*
import com.pxp.checkout.services.models.transaction.Shopper
import com.pxp.checkout.types.ComponentType
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : ComponentActivity() {

    private lateinit var pxpCheckout: PxpCheckout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            // Initialise SDK
            pxpCheckout = initializeSDK()

            setContent {
                MaterialTheme {
                    GooglePayScreen(pxpCheckout)
                }
            }
        }
    }

    private suspend fun initializeSDK(): PxpCheckout {
        val sessionConfig = fetchSessionFromYourBackend()

        return PxpCheckout.builder()
            .withConfig(
                PxpSdkConfig(
                    environment = Environment.TEST,
                    session = sessionConfig,
                    ownerId = "your-owner-id",
                    ownerType = "MerchantGroup",
                    kountDisabled = false,
                    transactionData = TransactionData(
                        amount = 99.99,
                        currency = "GBP",
                        merchant = "your-merchant-id",
                        merchantTransactionId = UUID.randomUUID().toString(),
                        merchantTransactionDate = {
                            SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
                                .apply { timeZone = TimeZone.getTimeZone("UTC") }
                                .format(Date())
                        },
                        entryType = EntryType.Ecom,
                        intent = TransactionIntentData(
                            card = IntentType.Authorisation
                        )
                    ),
                    onGetShopper = {
                        Shopper(
                            id = "shopper-${System.currentTimeMillis()}",
                            email = "customer@example.com",
                            firstName = "John",
                            lastName = "Doe"
                        )
                    },
                    onGetShippingAddress = {
                        ShippingAddress(
                            addressLine1 = "123 Main Street",
                            city = "London",
                            postalCode = "SW1A 1AA",
                            countryCode = "GB"
                        )
                    }
                )
            )
            .withContext(this)
            .build()
    }

    private suspend fun fetchSessionFromYourBackend(): SessionConfig {
        // Call your backend to fetch session
        return SessionConfig(
            sessionId = "session-123",
            hmacKey = "hmac-key",
            data = "session-data",
            encryptionKey = "encryption-key",
            locale = "en-GB"
        )
    }
}

@Composable
fun GooglePayScreen(pxpCheckout: PxpCheckout) {
    var showSuccess by remember { mutableStateOf(false) }
    var errorMessage by remember { mutableStateOf<String?>(null) }

    val googlePayConfig = remember {
        GooglePayButtonComponentConfig().apply {
            style = GooglePayButtonStyle(
                type = GooglePayButtonType.PAY,
                theme = GooglePayButtonTheme.DARK,
                cornerRadius = 8
            )

            paymentDataRequest = PaymentDataRequest(
                allowedPaymentMethods = listOf(
                    PaymentMethodSpecification(
                        parameters = PaymentMethodParameters(
                            allowedCardNetworks = listOf(
                                CardNetwork.VISA,
                                CardNetwork.MASTERCARD,
                                CardNetwork.AMEX
                            ),
                            allowedAuthMethods = listOf(
                                CardAuthMethod.PAN_ONLY,
                                CardAuthMethod.CRYPTOGRAM_3DS
                            )
                        )
                    )
                ),
                transactionInfo = TransactionInfo(
                    currencyCode = "GBP",
                    totalPriceStatus = TotalPriceStatus.FINAL,
                    totalPrice = "99.99"
                )
            )

            onPreAuthorisation = suspend { preAuthData ->
                GooglePayTransactionInitData(
                    riskScreeningData = RiskScreeningData(
                        performRiskScreening = true,
                        excludeDeviceData = false,
                        userIp = "192.168.1.100",
                        account = RiskScreeningAccount(
                            id = "user_12345678",
                            creationDateTime = "2024-01-15T10:30:00.000Z"
                        ),
                        fulfillments = listOf(
                            RiskScreeningFulfillment(
                                type = FulfillmentType.SHIPPED,
                                recipientPerson = RiskScreeningRecipientPerson(
                                    phoneNumber = "+1234567890"
                                )
                            )
                        )
                    )
                )
            }

            onPostAuthorisation = { result, paymentData ->
                when (result) {
                    is MerchantSubmitResult -> {
                        showSuccess = true
                    }
                    is FailedSubmitResult -> {
                        errorMessage = result.errorReason
                    }
                }
            }

            onError = { error ->
                errorMessage = error.message
            }
        }
    }

    val googlePayComponent = remember {
        pxpCheckout.createComponent<GooglePayButtonComponent, GooglePayButtonComponentConfig>(
            type = ComponentType.GOOGLE_PAY_BUTTON,
            config = googlePayConfig
        )
    }

    Scaffold { paddingValues ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues)
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            if (showSuccess) {
                Text(
                    text = "✓ Payment Successful!",
                    style = MaterialTheme.typography.headlineMedium,
                    color = MaterialTheme.colorScheme.primary
                )
            } else {
                Text(
                    text = "Complete your purchase",
                    style = MaterialTheme.typography.headlineMedium,
                    modifier = Modifier.padding(bottom = 24.dp)
                )

                googlePayComponent?.Content(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(56.dp)
                )

                errorMessage?.let { error ->
                    Text(
                        text = error,
                        color = MaterialTheme.colorScheme.error,
                        modifier = Modifier.padding(top = 16.dp)
                    )
                }
            }
        }
    }
}
```

## Next steps

Now that you've implemented the basic Google Pay integration, you can:

* [Configure 3D Secure authentication](/guides/checkout/components/android/google-pay/3ds) for enhanced security.
* [Set up recurring payments](/guides/checkout/components/android/google-pay/recurring-payments) to enable subscriptions.
* [Implement CVC collection](/guides/checkout/components/android/google-pay/configuration#cvc-collection) for additional security.
* [Handle payment events](/guides/checkout/components/android/google-pay/events) to track the payment lifecycle.