Google Pay for Android app

The right choice of a payment method proposed to the client is an important condition of success in the e-commerce. When talking about mobile apps, the statistic says you may lose up to 80 % of your clients just because the payment service is inconvenient or untrustworthy. Just think of all those attempts to enter all data with the help of a touchscreen — not to mention multiple shifts and fear of data leaks. In this situation, the integration of Google Pay service is a win-win solution for all parties.

Business Advantages of Google Pay

Google Pay (previously known as Android Pay) enables mobile payments just in two steps. The users registered in Google, when it comes to payment, tap the button «Buy with G Pay», choose one of their payment cards, and submit. Shipping mode being attached once, they dispose of necessity to enter the same contact data again and again.

No wonder that such an easy payment method is really popular among the users: as at September 2018, Google Pay app was downloaded 100 mln times. What are the business benefits? AirBnB after the service integration reported 11 times increase in the number of online payments. Google does not charge for the service use, so everything you get from integration is the growth in conversions and income.

Google Pay is available for all goods and services providers in the countries where the service is supported. It’s a perfect way to connect the user with several dozens of payment systems all over the world by means of a unified interface. It is easily integrated into the Android app. How? Read further to learn in details.

Google Pay Integration

The first thing you need to do is to import a library. In the project file gradle, you need to add a dependency: implementation 'com.google.android.gms:play-services-wallet:$play_service_wallet_version' where $play_service_wallet_version is a version of the library we are going to use. The current version is 16.0.0. The more detailed instruction for the library importation and information about Google Pay Services libraries can be found here.

Assuming the product or the service has already been formed and everything is ready for it to pass into your ownership. What we still need is adjusting the purchase process itself. For this, let’s initialize the payment client:

private lateinit var mPaymentsClient: PaymentsClient
 
mPaymentsClient = GooglePayUtil.createPaymentsClient(this)
 
fun createPaymentsClient(activity: Activity): PaymentsClient {
   val walletOptions = Wallet.WalletOptions.Builder()
       .setEnvironment(PAYMENTS_ENVIRONMENT)
       .build()
   return Wallet.getPaymentsClient(activity, walletOptions)
}

For PAYMENTS_ENVIRONMENT, we will specify the environment type WalletConstants.ENVIRONMENT_TEST.

Next, I propose first to check the possibility of purchasing with Google Pay:

GooglePayUtil.isReadyToPay(mPaymentsClient).addOnCompleteListener { task ->
   try {
       setGooglePayButtonAvailable(task.getResult(ApiException::class.java))
   } catch (exception: ApiException) {
       mGooglePayStatusText.text = "Payment status: Error init"
       Log.d("isReadyToPay failed", exception.statusCode.toString())
   }
}
 
 
fun isReadyToPay(client: PaymentsClient): Task<Boolean> {
   val request = IsReadyToPayRequest.newBuilder()
   for (allowedMethod in SUPPORTED_METHODS) {
       request.addAllowedPaymentMethod(allowedMethod)
   }
   return client.isReadyToPay(request.build())
}

Depending upon the result, we need either to display or to hide the button:

private fun setGooglePayButtonAvailable(available: Boolean) {
   if (available) {
       mGooglePayStatusText.text = "Payment status: Supported"
       mGooglePayButton.visibility = View.VISIBLE
   } else {
       mGooglePayStatusText.text = "Payment status: Not supported"
   }
}

Payment methods are specified in advance:

private val SUPPORTED_METHODS = Arrays.asList(
   WalletConstants.PAYMENT_METHOD_CARD,
   WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD
)

Google Pay In the Android App: Further Steps of Integration

We have gone through all preparatory stages related to our payment systems usage. Now we have come to the most complicated stage, payment committing:

mGooglePayButton.setOnClickListener{
   requestPayment()
}

An important note: most of payment systems use the minimal possible currency value. Consequently, in the case of a kopeck or penny, for example, when indicating the write-off sum equal 17852, we confirm that we want to write off 178.52.

The currency type:

private fun requestPayment() {
   mGooglePayButton.isClickable = false
 
   val price = GooglePayUtil.microsToString(17852)
   val transaction = GooglePayUtil.createTransaction(price)
   val request = GooglePayUtil.createPaymentDataRequest(transaction)
   val futurePaymentData = mPaymentsClient.loadPaymentData(request)
 
   AutoResolveHelper.resolveTask(futurePaymentData, this, LOAD_PAYMENT_DATA_REQUEST_CODE)
}

Next, prepare the transaction. Don’t forget to indicate the currency type:

fun createTransaction(price: String): TransactionInfo {
   return TransactionInfo.newBuilder()
       .setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
       .setTotalPrice(price)
       .setCurrencyCode("USD")
       .build()
}

Form the request. Right away add the specifications for the merchant and the website link:

fun createPaymentDataRequest(transactionInfo: TransactionInfo): PaymentDataRequest {
   val paramsBuilder = PaymentMethodTokenizationParameters.newBuilder()
       .setPaymentMethodTokenizationType(
           WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY
       )
       .addParameter("gateway", “http://www.example.com”)
       .addParameter("gatewayMerchantId", "Example Merchant Name")
   return createPaymentDataRequest(transactionInfo, paramsBuilder.build())
}

Next, the request itself. Here, specify all the necessary fields and ordering parameters. For example, we may specify if we need to request a phone number, an e-mail, and whether we need a delivery option at all. Here and now, we also specify countries where the goods can be delivered, payment options, and payment systems (VISA, MASTERCARD):

private fun createPaymentDataRequest(
   transactionInfo: TransactionInfo,
   params: PaymentMethodTokenizationParameters
): PaymentDataRequest {
 
   return PaymentDataRequest.newBuilder()
       .setPhoneNumberRequired(false)
       .setEmailRequired(true)
       .setShippingAddressRequired(true)
       .setShippingAddressRequirements(
           ShippingAddressRequirements.newBuilder()
               .addAllowedCountryCodes(SHIPPING_SUPPORTED_COUNTRIES)
               .build()
       )
       .setTransactionInfo(transactionInfo)
       .addAllowedPaymentMethods(SUPPORTED_METHODS)
       .setCardRequirements(
           CardRequirements.newBuilder()
               .addAllowedCardNetworks(SUPPORTED_NETWORKS)
               .setAllowPrepaidCards(true)
               .setBillingAddressFormat(WalletConstants.BILLING_ADDRESS_FORMAT_FULL)
               .build()
       )
       .setPaymentMethodTokenizationParameters(params)
       .setUiRequired(true)
       .build()
}
 
private val SHIPPING_SUPPORTED_COUNTRIES = Arrays.asList("UA, US, DE, GB")
 
private val SUPPORTED_NETWORKS = Arrays.asList(
   WalletConstants.CARD_NETWORK_VISA,
   WalletConstants.CARD_NETWORK_MASTERCARD
)

So, the request is formed. Next, we need to process the result of this request:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
   when (requestCode) {
       LOAD_PAYMENT_DATA_REQUEST_CODE -> {
           when (resultCode) {
               Activity.RESULT_OK -> {
                   data?.let {
                       onPaymentSuccess(PaymentData.getFromIntent(data))
                   }
               }
               Activity.RESULT_CANCELED -> {
               }
               AutoResolveHelper.RESULT_ERROR -> {
                   onError(AutoResolveHelper.getStatusFromIntent(data)?.statusCode)
               }
           }
           mGooglePayButton.isClickable = true
       }
   }
}

Then goes the transaction processing. Here, a lot of various logic can be added, including screen shifts, congratulations of just service-based data, but in our version, we will just check the result and show it. This is just a trial version, so, we will not dwell into the business logic:

private fun onPaymentSuccess(paymentData: PaymentData?) {
     Toast.makeText(this, “Payment Success”, Toast.LENGTH_LONG).show()
}
 
private fun onError(statusCode: Int?) {
   Log.w("loadPaymentData failed", String.format("Error code: %d", statusCode))
}

Integration Outcome: What the User Sees

As a result, the users at the checkout stage will see the Google Pay button:

Google Pay button

After tapping it, they will see the checkout form:

google pay checkout form

Let’s Sum It Up

Google Pay is a handy and safe payment service for the mobile app with the possibility of integration of numerous payment systems. It makes purchases easier for clients and boosts online sales for the merchants. With the help of the algorithm described above, you will easily integrate Google Pay into your Android app.

And if programming is not your professional field, contact Stfalcon.com — and our specialists will quickly and qualitatively develop and implement any functionality for your mobile app.

Related posts

Return to list Return to list