# Accept Google Pay on Android (Early Preview)

If you have a native Android App you can use Tyro Android SDK to easily accept Google Pay payments.

## Prerequisites

Please familiarise yourself with the guide to  [Accept an Online Payment](/app/apis/pay/accept-an-online-payment), as the steps outlined in this document builds upon the existing knowledge.

## Integration Steps

### 1. Configure Your Android App

Make sure your app's build file uses the following values:

* A `minSdkVersion` of `21` or higher
* A `compileSdkVersion` of `31` or higher


Add the following element to the `<application>` element in your `AndroidManifest.xml` file to enable Google Pay.


```xml
<meta-data
  android:name="com.google.android.gms.wallet.api.enabled"
  android:value="true" />
```

### 2. Add Tyro Android SDK

Currently the SDK is published to GitHub Packages, to use a published package from GitHub Packages, you need to authenticate to GitHub Package and also add the repository to your project.

#### 2.1 Authentication to GitHub

Make sure you have your GitHub username accessible by the `build.gradle`, you can store it as an environment variable:


```bash
export GITHUB_PACKAGES_USER={YOUR_GITHUB_USERNAME}
```

Follow this [GitHub guide](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) to generate a GitHub Personal Access Token with `read:packages` permission, and store it as an environment variable:


```bash
export GITHUB_PACKAGES_TOKEN={YOUR_GITHUB_TOKEN}
```

#### 2.2 Add Package Dependency

Add the Tyro Android SDK dependency to your module's Gradle build file, which is commonly `app/build.gradle`.


```groovy
dependencies {
  implementation 'com.tyro:tyro-pay-api-sdk-android:+'
}
```

#### 2.3 Add Repository to Project

Add the repository to your `gradle.build`


```groovy
repositories {
    maven {
            url = uri("https://maven.pkg.github.com/tyro/tyro-pay-api-sdk-android")
            credentials {
                username = System.getenv("GITHUB_PACKAGES_USER")
                password = System.getenv("GITHUB_PACKAGES_TOKEN")
            }
        }
}
```

Check more detail on the [GitHub Packages - working with the gradle registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry).

### 3. Add The Google Pay Button

Follow [Google's guidelines](https://developers.google.com/pay/api/android/guides/brand-guidelines) to add the Google Pay button to your App's UI.

### 4. Create a TyroGooglePayClient

* Create an instance of the `TyroGooglePayClient` inside `onCreate()` of your `Activity` or `Fragment`.
* Provide the configuration and listeners.



```kotlin
// Kotlin Sample Code
class YourCheckoutActivity : AppCompatActivity() {
  ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.your_checkout_activity)

    val tyroGooglePayClient = TyroGooglePayClient(
      activity = this,
      config = TyroGooglePayClient.Config(
        liveMode = false,
        merchantName = "Example Merchant",
        allowedCardNetworks = listOf(
          GooglePayCardNetwork.AMEX,
          GooglePayCardNetwork.JCB,
          GooglePayCardNetwork.MASTERCARD,
          GooglePayCardNetwork.VISA),
          googlePayReadyListener = :: onGooglePayReady,
          paymentResultListener = :: onPaymentResult,
      )
    )
  }

  private fun onGooglePayReady(available: Boolean) {...}
  private fun onPaymentResult(result: TyroGooglePayClient.Result){...}
  ...
}
```

### 5. Handle the Google Pay Ready Event

Before you display the Google Pay button, use the `GooglePayReadyListener` to determine if Google Pay is available for the user.
Show the button if `available` is `true`, otherwise Google Pay is not available and the button cannot be shown.


```kotlin
// Kotlin Sample Code
...
private fun onGooglePayReady(available: Boolean) {
  if (available) {
      googlePayButton.visibility = View.VISIBLE
  }
}
...
```

### 6. Add the Google Pay Button Click Listener

* Obtain the `paySecret` by creating a PayRequest from your server.
* Invoke `tyroGooglePayClient.launchGooglePay(paySecret)` to start Google Pay.
* Use listeners to obtain the payment result.



```kotlin
// Kotlin Sample Code
  ...
  override fun onCreate(savedInstanceState: Bundle?) {
    ...
    googlePayButton.setOnClickListener {
        tyroGooglePayClient.launchGooglePay(paySecret)
    }
  }
  ...
```

### 7. Implement the PaymentResultListener

This listener is called when payment completes successfully or unsuccessfully. This includes the user cancelling the payment.

* If the payment succeeds, the result will be `TyroGooglePayClient.Result.Success`. Optionally call `tyroGooglePayClient.fetchPayRequest("paySecret")` to get more info on the Pay Request.
* If the payment is cancelled, the result will be `TyroGooglePayClient.Result.Cancelled`.
* If the payment failed, the result will be ` TyroGooglePayClient.Result.Failed`. Inspect the `result.error.errorType` and other fields from the following example to get more details.



```kotlin
// Kotlin Sample Code
  ...
  private fun onPaymentResult(result: TyroGooglePayClient.Result) {
    when(result){
      TyroGooglePayClient.Result.Cancelled -> {
        // User cancelled operation
        showCancelled()
      }
      TyroGooglePayClient.Result.Success -> {
        // Google Pay Success, show success view
        // Optionally call tyroGooglePayClient.fetchPayRequest("paySecret")
        // to get more info on the Pay Request
        showSuccess()
      }
      is TyroGooglePayClient.Result.Failed -> {
        // Transaction failed for some reason
        // inspect the following fields to get more info
        val (errorType, errorMessage, errorCode, gatewayCode) = result.error
        when(errorType) {
          TyroPayRequestErrorType.CLIENT_VALIDATION_ERROR -> showClientValidationError(errorMessage)
          TyroPayRequestErrorType.SERVER_VALIDATION_ERROR -> showServerValidationError(errorMessage, errorCode, gatewayCode)
          TyroPayRequestErrorType.CARD_ERROR -> showCardError(errorMessage, errorCode, gatewayCode)
          TyroPayRequestErrorType.SERVER_ERROR -> showGenericError(errorMessage, errorCode, gatewayCode)
          TyroPayRequestErrorType.THREED_SECURE_ERROR -> show3DSError(errorMessage, errorCode)
          else -> showGenericError(errorMessage)
        }
      }
    }
  }
  ...
```