# Google Pay on Android

Accept Google Pay in your Android application using Finix.

This guide details how to get started accepting Google Pay on Android devices using Finix.

### Dues and Assessments

We recommend that you pass the address field listed in the steps below. If the address is not passed, you will be charged additional dues and assessments per transaction from the card network.

## Step 1: Onboard with Google

Start by familiarizing yourself with [the prerequisites](https://docs.finix.com/guides/online-payments/digital-wallets/google-pay) for using Google Pay with Finix.

## Step 2: Define Google Pay API Version

Declare the version of the Google Pay API that your application uses. The major and minor versions affect the fields expected in each passed object and are included in the response.

Create a base request object that contains properties that are present in all other request objects.

```kotlin
private val baseRequest = JSONObject()
    .put("apiVersion", 2)
    .put("apiVersionMinor", 0)
```

## Step 3: Request a Finix Payment Token

Now that you've defined your Google Pay API Version, request a Finix payment token.

- `gateway` should be set to `finix`
- `gatewayMerchantId` should be set to the **application owner identity** or **merchant owner identity**. To choose the appropriate Identity ID, see [Choose Merchant Identifier Value](https://docs.finix.com/guides/online-payments/digital-wallets/google-pay).

```kotlin
private fun gatewayTokenizationSpecification(): JSONObject {
    return JSONObject().apply {
        put("type", "PAYMENT_GATEWAY")
        put("parameters", JSONObject(mapOf(
                "gateway" to "finix",
                "gatewayMerchantId" to "IDxxx")))
    }
}
```

## Step 4: Define Allowed Card Networks

Now that we've requested a Finix payment token, you can set which card networks will be accepted on your site.

```kotlin
private val allowedCardNetworks = JSONArray(listOf(
        "AMEX",
        "DISCOVER",
        "INTERAC",
        "JCB",
        "MASTERCARD",
        "VISA"))
```

Defining `allowedCardAuthMethods` sets the authentication methods supported by your site and gateway.

```kotlin
private val allowedCardAuthMethods = JSONArray(listOf(
        "PAN_ONLY",
        "CRYPTOGRAM_3DS"))
```

For both `PAN_ONLY` and `CRYPTOGRAM_3DS` authorization methods, support for 3D Secure is dictated by the processors you integrate with in `allowedCardNetworks`. Finix accepts both `PAN_ONLY` and `CRYPTOGRAM_3DS` authorization methods.

## Step 5: Describe Allowed Payment Methods

After you've defined the supported payment card networks, you need to describe your allowed payment methods. You can do this with the following steps:

1. Combine `allowedAuthMethods` and `allowedCardNetworks` to describe how your application supports the `CARD` payment method.
2. Extend the `baseCardPaymentMethod` object and describe the information you expect to be returned to your application. Include a description of the tokenized payment data.

```kotlin
private fun baseCardPaymentMethod(): JSONObject =
    JSONObject()
        .put("type", "CARD")
        .put("parameters", JSONObject()
                .put("allowedAuthMethods", allowedCardAuthMethods)
                .put("allowedCardNetworks", allowedCardNetworks)
                .put("billingAddressRequired", true)
                .put("billingAddressParameters", JSONObject()
                        .put("format", "FULL")
                )
        )
private val cardPaymentMethod: JSONObject = baseCardPaymentMethod()
    .put("tokenizationSpecification", gatewayTokenizationSpecification)
```

## Step 6: Create a PaymentsClient Instance

Create a `PaymentsClient` instance to interact with the Google Pay API.

```kotlin
fun createPaymentsClient(context: Context): PaymentsClient {
    val walletOptions = Wallet.WalletOptions.Builder()
        .setEnvironment(Constants.PAYMENTS_ENVIRONMENT)
        .build()

return Wallet.getPaymentsClient(context, walletOptions)
}
```

## Step 7: Check Readiness to Pay with Google Pay

Now that you've described your allowed payment methods, you need to check readiness to pay with the Google Pay API. To check readiness to pay with Google Pay's API:

1. Add `allowedPaymentMethods` to the `baseRequest` object.
2. Call `isReadyToPay()` to determine if the user can make payments with the Google Pay API.

```kotlin
fun isReadyToPayRequest(): JSONObject? =
    try {
        baseRequest
            .put("allowedPaymentMethods", JSONArray().put(baseCardPaymentMethod()))
    } catch (e: JSONException) {
        null
    }

private fun possiblyShowGooglePayButton() {
    val isReadyToPayJson = PaymentsUtil.isReadyToPayRequest() ?: return
    val request = IsReadyToPayRequest.fromJson(isReadyToPayJson.toString()) ?: return
    // The call to isReadyToPay is asynchronous and returns a Task. We need to provide an
    // OnCompleteListener to be triggered when the result of the call is known.
    val task = paymentsClient.isReadyToPay(request)
    task.addOnCompleteListener { completedTask ->
        try {
            completedTask.getResult(ApiException::class.java)?.let(::setGooglePayAvailable)
        } catch (exception: ApiException) {
            // Process error
            Log.w("isReadyToPay failed", exception)
        }
    }
}
```

## Step 8: Add Google Pay Button

Now that you've checked readiness to pay with Google Pay API, you can add a Google Pay payment button to your website.

- For information about the different button types and display requirements, see [Google's Brand guidelines](https://developers.google.com/pay/api/web/guides/brand-guidelines).
- To try all the different Google Pay buttons, see [Google Pay's interactive demo](https://developers.google.com/pay/api/web/guides/resources/customize).

```kotlin
PayButton(
    modifier = Modifier
        .testTag("payButton")
        .fillMaxWidth(),
    onClick = onGooglePayButtonClick,
    allowedPaymentMethods = PaymentsUtil.allowedPaymentMethods.toString()
)
```

### Initialize Google Pay Button

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

// Use view binding to access the UI elements
  layout = ActivityCheckoutBinding.inflate(layoutInflater)
  setContentView(layout.root)

// Setup buttons
  googlePayButton = layout.googlePayButton
  googlePayButton.initialize(
      ButtonOptions.newBuilder()
          .setAllowedPaymentMethods(PaymentsUtil.allowedPaymentMethods.toString()).build()
  )
  googlePayButton.setOnClickListener { requestPayment() }

// Check Google Pay availability
  model.canUseGooglePay.observe(this, Observer(::setGooglePayAvailable))
}
```

## Step 9: Create a Payment Data Request

After creating a Google Pay payment button, you need to create a `PaymentDataRequest` object. The `PaymentDataRequest` takes in information about the merchant and transaction which is required to start the payment process with Google Pay.

### Get Transaction Info

```kotlin
private fun getTransactionInfo(price: String): JSONObject =
    JSONObject()
        .put("totalPrice", price)
        .put("totalPriceStatus", "FINAL")
        .put("countryCode", Constants.COUNTRY_CODE)
        .put("currencyCode", Constants.CURRENCY_CODE)

private val merchantInfo: JSONObject =
    JSONObject().put("merchantName", "Example Merchant")
```

### Request Arguments

| Field               | Type    | Description |
|---------------------|---------|-------------|
| `countryCode`      | _string_, **required** | The ISO country code. |
| `currencyCode`     | _string_, **required** | The currency code of the locale. |
| `totalPrice`       | _string_, **required** | Total value of the transaction with an optional decimal precision of two decimal places. |
| `totalPriceStatus` | _string_, **required** | The status of the total price used. <br>- Pass **FINAL** if the total price doesn't change from the amount presented to the buyer.<br>- Pass **ESTIMATED** if the total price might adjust based on the details of the response, such as sales tax collected that's based on a billing address.<br>- Pass **NOT_CURRENTLY_KNOWN** when using `totalPriceStatus` for a capability check. |

### Merchant Info Request Arguments

| Field         | Type    | Description |
|---------------|---------|-------------|
| `merchantID` | _string_, **required** | A Google merchant identifier issued after registration with the Google Pay Business Console. Required when PaymentsClient is initialized with an environment property of **LIVE** |
| `merchantName`| _string_, **required** | Pass in the name of the `Merchant` . |

Strong Customer Authentication (SCA) requires the `countryCode`, `totalPrice`, and `merchantName` parameters to meet SCA requirements.

## Step 10: Get Buyer Identity

A buyer identity is required before you can proceed with the next steps. You can either create a new buyer identity through the Finix API or use an existing one you’ve already created.

### Buyer Identity Data

All buyer Identity fields are optional. However, Finix recommends including basic information (name, email, address, and phone) to make payment operations easier.

Use an existing buyer or create a new buyer.

### Buyer Identity Request

```bash
curl -i -X POST \
  -u USfdccsr1Z5iVbXDyYt7hjZZ:313636f3-fac2-45a7-bff7-a334b93e7bda \
  https://finix.sandbox-payments-api.com/identities \
  -H 'Content-Type: application/json' \
  -H 'Finix-Version: 2022-02-01' \
  -d '{
    "entity": {
      "phone": "7145677613",
      "first_name": "John",
      "last_name": "Smith",
      "email": "finix_example@finix.com",
      "personal_address": {
        "city": "San Mateo",
        "country": "USA",
        "region": "CA",
        "line2": "Apartment 7",
        "line1": "741 Douglass St",
        "postal_code": "94114"
      }
    },
    "identity_roles": [
      "BUYER"
    ],
    "tags": {
      "key": "value"
    },
    "type": "PERSONAL"
  }'
```

### Buyer Identity Response

```json
{
  "id": "IDmkDvJfxZWMEK56FDFtbozo",
  "created_at": "2024-08-09T09:34:36.87Z",
  "updated_at": "2024-08-09T09:34:36.87Z",
  "application": "APgPDQrLD52TYvqazjHJJchM",
  "entity": {
    "phone": "7145677613",
    "first_name": "John",
    "last_name": "Smith",
    "email": "finix_example@finix.com",
    "personal_address": {
      "line1": "741 Douglass St",
      "line2": "Apartment 7",
      "city": "San Mateo",
      "region": "CA",
      "postal_code": "94114",
      "country": "USA"
    }
  },
  "identity_roles": [],
  "tags": {
    "key": "value"
  },
  "type": "PERSONAL"
}
```

## Step 11: Create a Payment Instrument

Call `loadPaymentData` using the Google Pay `PaymentsClient` object, which results in a `Task` object. Extract the payment token from the `PaymentData` result object.

### Payment Instrument Request

```bash
curl -i -X POST \
  -u USfdccsr1Z5iVbXDyYt7hjZZ:313636f3-fac2-45a7-bff7-a334b93e7bda \
  https://finix.sandbox-payments-api.com/payment_instruments \
  -H 'Content-Type: application/json' \
  -H 'Finix-Version: 2022-02-01' \
  -d '{
    "address": {
      "city": "San Francisco",
      "country": "USA",
      "line1": "900 Metro Center Blv",
      "line2": "APT 200",
      "postal_code": "94404",
      "region": "CA"
    },
    "identity": "ID78Fh8mcnnzukVzbdoyex5y",
    "merchant_identity": "IDwhCCvPwCDEmiFd8Be7pDzN",
    "name": "Finix Sandbox",
    "third_party_token": "{\"signature\":\"MEYCIQCYTkaEMgug7pcjzEEdbIn+R57kYO5yYc2KYj41AQQn9wIhAN1QvylvZ2XydVecfejwi2xYS9y3Y9y/MmDnRnUfNw5H\",\"intermediateSigningKey\":{\"signedKey\":\"{\\\"keyValue\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4xc3fjeM9SMTjd1TL2GQCPmgqPf2h42aM3akPh/mTUBqWEgOITruK10A02rQ+4YZOvLCpQKQZzLSAd09nctnuA\\u003d\\u003d\",\\\"keyExpiration\\\":\"1648843199734\"}\\",\"signatures\":[\"MEQCICwCI4s5YCLu4qRCyXwSJ3qG8y3ocFtP1Mque4Uzysl8AiARoD/0qbj5W0Q2PWKpxkEnfcP+nU5kwYS8FyQ9boDTmQ\\u003d\\u003d\"]},\"protocolVersion\":\"ECv2\",\"signedMessage\":\"{\\\"encryptedMessage\\\":\\\"roD4ikTpZ7Srunq+0zUnp+eiXzcuZBfIFSuZAJu1PQLXcP0RvnGDiGKtoarNCHvn+cnXsHCzIBWXMZSJ9Aglqky9VfP5a+qsXQhf5m5AFUbT2xnihtKwageGQQK6HzyjHSXXSjvuCzeo75ToOgIUxLFASZyaZ89u3Jifqhhc2c4a0Mtlx564BxXiwcxDFdtNkOle7uAIsJzsryk7Rcwgr8ZMJJM//XpvaeE5wNmkVFHUtR2uTqPm0BvkoYkFHCTRo4NHXWpxeLjXWzKGk2ELyTK1diuCa6c9ig0jO3t8BIh1cR63UeP8Ar7u5fh8C9FPPAsgPbTGLfiaRe615e4SxASgcZ4/8uWo5mikEPFqA5s2K2mid9ncXoMNYaHUc3qzJAyxHVYSd5SRNZYXHMkEcWcjnpDx+ErYjR1sMo1LMYXfrfGyZz3M69bQLKPYFe7ChjvgFI9MnfcFTNB4HAdNKMhbZT0EKinfxxGWkT7LVbGnUuqPlHp4toCe4kpbx7fulwXTj3bAFvg/qvxxwGOS38iP0HR/f+4GF0xHspqYVbdWdIJ5iJUdpBG8Nu5P56h2GEDxXMkKSmh+qbvKWlYipNNGoeg8uHc\\u003d\",\"ephemeralPublicKey\":\"BMqIyb1IyXhuZ4YpWm1PiRr74i3tCwDfQqJ1P4OZ3zK4Rq16SuwgJ605fCEvlViwSQuo2Hpv+CcR+2D3+/YrLB8\\u003d\",\"tag\":\"5K4LlTucDK7jAThbIozYtyoxX95hRNd5cJJGfxWAxw8\\u003d\"}",
    "type": "GOOGLE_PAY"
  }'
```

## Step 12: Create a Payment

Similar to other Finix transactions, after the `Payment Instrument` is created, you can use the instrument and create a [`transfer`](https://docs.finix.com/api/transfers) or an [`authorization`](https://docs.finix.com/api/authorizations/createauthorization) to process transactions.

### Example Transfer Request

```bash
curl https://finix.sandbox-payments-api.com/transfers \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u  USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    -d '{
        "merchant": "MUeDVrf2ahuKc9Eg5TeZugvs",
        "currency": "USD",
        "amount": 662154,
        "source": "PIf8dyFFcEGBqPhaG22hPyYs",
    }'
```

### Example Transfer Response

```json
{
  "id": "TR29av3LN1TAGPbXscsup1tt",
  "amount": 662154,
  "state": "SUCCEEDED",
  "currency": "USD",
  "created_at": "2022-08-25T20:39:37.59Z",
  "updated_at": "2022-08-25T20:39:38.17Z"
}
```
