Google Pay

Google Pay

The Google Pay offers a quick and easy path to enable secure, one touch payments in your app.
This guide explains how to process payments with our SDK.

Requirements

  • A Mobile SDK integration (Ready-to-Use UI or SDK & Your Own UI)
  • A Google account, when you're ready to deploy your Google Pay integration, sign-up to get access and test with production credentials.

Configuration

Open the build.gradle file in the app module and add the following to the dependencies block:

implementation "com.google.android.gms:play-services-wallet:x.x.x"

Adding the Google Pay to your app must be done in one of two ways, depending on whether you are using the Ready-to-Use UI or the SDK & Your Own UI. These two ways are covered in the sections below. Please follow the instructions relevant to the approach you have chosen.

Ready-to-Use UI

Add GOOGLEPAY payment brand

Create the CheckoutSettings, and add the GOOGLEPAY to the payment brands list:

Set<String> paymentBrands = new HashSet<String>();
paymentBrands.add("GOOGLEPAY");

CheckoutSettings checkoutSettings = new CheckoutSettings(checkoutId, paymentBrands, Connect.ProviderMode.TEST);
val paymentBrands = hashSetOf("GOOGLEPAY") 
 
val checkoutSettings = CheckoutSettings(checkoutId, paymentBrands, Connect.ProviderMode.TEST)

If you integrate the Google Pay using our drop-in buttons, set the GOOGLEPAY payment brand in the PaymentButtonFragment.

paymentButtonFragment.setPaymentBrand("GOOGLEPAY");
paymentButtonFragment.paymentBrand = "GOOGLEPAY"

Configure PaymentDataRequest

Create JSONObject to configure Google Pay widget with the transaction info, allowed payment methods and card networks.
Use PaymentDataRequestJsonBuilder to easily create base paymentDataRequestJson object with all required parameters.

Then you can add some optional configurations, e.g. enable requesting shipping info in the widget. Please refer to the Google Pay Payments API documentation for more options.

JSONArray allowedPaymentMethodsJson = new JSONArray()
        .put(new CardPaymentMethodJsonBuilder()
                    .setAllowedAuthMethods(new JSONArray()
                            .put("PAN_ONLY")
                            .put("CRYPTOGRAM_3DS")
                    )
                    .setAllowedCardNetworks(new JSONArray()
                            .put("VISA")
                            .put("MASTERCARD")
                            .put("AMEX")
                            .put("DISCOVER")
                            .put("JCB")
                    )
                    .setGatewayMerchantId("yourEntityId")
                    .toJson()
        );

JSONObject transactionInfoJson = new TransactionInfoJsonBuilder()
        .setCurrencyCode("USD")
        .setTotalPriceStatus("FINAL")
        .setTotalPrice("100.00")
        .toJson();

JSONObject paymentDataRequestJson = new PaymentDataRequestJsonBuilder()
        .setAllowedPaymentMethods(allowedPaymentMethodsJson)
        .setTransactionInfo(transactionInfoJson)
        .toJson();
val allowedPaymentMethodsJson = JSONArray()
        .put(CardPaymentMethodJsonBuilder()
                    .setAllowedAuthMethods(JSONArray()
                            .put("PAN_ONLY")
                            .put("CRYPTOGRAM_3DS")
                    )
                    .setAllowedCardNetworks(JSONArray()
                            .put("VISA")
                            .put("MASTERCARD")
                            .put("AMEX")
                            .put("DISCOVER")
                            .put("JCB")
                    )
                    .setGatewayMerchantId("yourEntityId")
                    .toJson()
        )

val transactionInfoJson = TransactionInfoJsonBuilder()
        .setCurrencyCode("USD")
        .setTotalPriceStatus("FINAL")
        .setTotalPrice("100.00")
        .toJson()

val paymentDataRequestJson = PaymentDataRequestJsonBuilder()
        .setAllowedPaymentMethods(allowedPaymentMethodsJson)
        .setTransactionInfo(transactionInfoJson)
        .toJson()

Set it to the CheckoutSettings.

checkoutSettings.setGooglePayPaymentDataRequestJson(paymentDataRequestJson.toString());
checkoutSettings.googlePayPaymentDataRequestJson = paymentDataRequestJson.toString()

Collecting shopper information

You can collect additional information with the Google Pay widget before submitting the transaction, e.g. shipping information.

Configure payment data request

In addition to the previous steps complete configuration of the paymentDataRequestJson object to request additional information from the shopper. Refer to the Payments API to see the full list of options.

JSONObject paymentDataRequestJson = new PaymentDataRequestJsonBuilder()
        .setAllowedPaymentMethods(allowedPaymentMethodsJson)
        .setTransactionInfo(transactionInfoJson)
        .setShippingAddressRequired(true)
        .setEmailRequired(true)
        .toJson();
val paymentDataRequestJson = PaymentDataRequestJsonBuilder()
        .setAllowedPaymentMethods(allowedPaymentMethodsJson)
        .setTransactionInfo(transactionInfoJson)
        .setShippingAddressRequired(true)
        .setEmailRequired(true)
        .toJson()
 

Configure receiving callbacks from the checkout

The CheckoutActivity may send the callback CheckoutActivity.ACTION_ON_BEFORE_SUBMIT when shopper submits the payment.
To receive it you should complete the following steps:

1. Create your broadcast receiver to listen the intents from CheckoutActivity.
See below how to receive PaymentData object with the requested data from the Google Pay widget. Refer to the Payments API for the class definition.

public class CheckoutBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (CheckoutActivity.ACTION_ON_BEFORE_SUBMIT.equals(action)) {
            /* Collect shopper information from the Google Pay */
            PaymentData paymentData = intent.getParcelableExtra(CheckoutActivity.EXTRA_GOOGLE_PAY_PAYMENT_DATA);

            String paymentBrand = intent.getStringExtra(CheckoutActivity.EXTRA_PAYMENT_BRAND);
            String checkoutId = intent.getStringExtra(CheckoutActivity.EXTRA_CHECKOUT_ID);
            ComponentName senderComponentName = intent.getParcelableExtra(CheckoutActivity.EXTRA_SENDER_COMPONENT_NAME);

            /* Return control back to the CheckoutActivity to submit the payment */
            Intent checkoutIntent = new Intent(CheckoutActivity.ACTION_ON_BEFORE_SUBMIT);
            checkoutIntent.setComponent(senderComponentName);
            checkoutIntent.setPackage(senderComponentName.getPackageName());
            checkoutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            checkoutIntent.putExtra(CheckoutActivity.EXTRA_CHECKOUT_ID, checkoutId);

            context.startActivity(checkoutIntent);
        }
    }
}
class BroadcastReceiver : BroadcastReceiver() { 
     
    override fun onReceive(context: Context, intent: Intent?) { 
        val action = intent?.action 
         
        if (CheckoutActivity.ACTION_ON_BEFORE_SUBMIT == action) { 
            /* Collect shopper information from the Google Pay */ 
            val paymentData: PaymentData? = intent.getParcelableExtra(CheckoutActivity.EXTRA_GOOGLE_PAY_PAYMENT_DATA) 
 
            val paymentBrand = intent.getStringExtra(CheckoutActivity.EXTRA_PAYMENT_BRAND) 
            val checkoutId = intent.getStringExtra(CheckoutActivity.EXTRA_CHECKOUT_ID) 
            val senderComponent = intent.getParcelableExtra<ComponentName>(CheckoutActivity.EXTRA_SENDER_COMPONENT_NAME) 
 
            /* Return control back to the CheckoutActivity to submit the payment */ 
            val checkoutIntent = Intent(CheckoutActivity.ACTION_ON_BEFORE_SUBMIT) 
            checkoutIntent.component = senderComponent 
            checkoutIntent.setPackage(senderComponent!!.packageName) 
            checkoutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 
            checkoutIntent.putExtra(CheckoutActivity.EXTRA_CHECKOUT_ID, checkoutId) 
 
            context.startActivity(checkoutIntent) 
        } 
    } 
}

2. Declare your broadcast receiver in AndroidManifest.xml.

<receiver
    android:name=".CheckoutBroadcastReceiver"
    android:exported="false" />

NOTE: It is important to set android:exported="false" to your broadcast receiver. In this case the only messages the broadcast receiver can receive are those sent by components of the same application or applications with the same user ID.

3. To provide the best security our SDK uses directed broadcasts. This way our broadcast is received only by the specified BroadcastReceiver. For this reason you should add ComponentName of your receiver to CheckoutActivity intent.

CheckoutSettings settings = new CheckoutSettings(...);
ComponentName receiverComponentName = new ComponentName("yourPackageName", "yourReceiverClassName");
Intent intent = checkoutSettings.createCheckoutActivityIntent(this, receiverComponentName);

startActivityForResult(intent, CheckoutActivity.REQUEST_CODE_CHECKOUT);
val checkoutSettings = CheckoutSettings(...)  
val receiverComponent = ComponentName("yourPackageName", "yourReceiverClassName") 
val intent: Intent = checkoutSettings.createCheckoutActivityIntent(this, receiverComponent) 
 
startActivityForResult(intent, CheckoutActivity.REQUEST_CODE_CHECKOUT)

Confirmation page

Google Pay Confirmation Page

A final price must be displayed to the shopper before processing the transaction. If the amount to be charged has varied based on data received from the Google Pay widget you are expected to show a confirmation page with a final price. You can configure it in CheckoutActivity.ACTION_ON_BEFORE_SUBMIT callback.

1. Initialize OrderSummary object with order details, total amount and Google Pay PaymentData response object.

PaymentData paymentData = intent.getParcelableExtra(CheckoutActivity.EXTRA_GOOGLE_PAY_PAYMENT_DATA);

if (paymentData != null) {
    LinkedHashMap<String, Double> orderItems = new LinkedHashMap<String, Double>() {{
        put("Subtotal", 200.00);
        put("Shipping", 10.00);
    }};

    OrderSummary orderSummary = new OrderSummary(orderItems, 210.00, paymentData);
}
val paymentData: PaymentData? = intent.getParcelableExtra(CheckoutActivity.EXTRA_GOOGLE_PAY_PAYMENT_DATA) 
 
if (paymentData != null) { 
    val orderItems = linkedMapOf( 
            "Subtotal" to 200.00, 
            "Shipping" to 10.00 
    ) 
    val orderSummary = OrderSummary(orderItems, 210.00, paymentData) 
}

2. Add OrderSummary extra to the CheckoutActivity intent.

checkoutIntent.putExtra(CheckoutActivity.EXTRA_ORDER_SUMMARY, orderSummary);
checkoutIntent.putExtra(CheckoutActivity.EXTRA_ORDER_SUMMARY, orderSummary)

3. Start checkout activity to return control back to the sdk and show confirmation page.


SDK & Your Own UI

Follow this tutorial to integrate the Google Pay into your UI.
Use PaymentDataRequestJsonBuilder to easily create base paymentDataRequestJson object with all required parameters.

To make a transaction create the GooglePayPaymentParams with a received token and actual card brand:

PaymentParams paymentParams = new GooglePayPaymentParams(checkoutId, token, cardBrand);
val paymentParams = GooglePayPaymentParams(checkoutId, token, cardBrand)

NOTE: The actual card brand should be taken from com.google.android.gms.wallet.PaymentData. If it's 'MASTERCARD' then 'MASTER' should be used as a card brand.

And submit the transaction:

Transaction transaction = null;

try {
    transaction = new Transaction(paymentParams);
    binder.submitTransaction(transaction);
} catch (PaymentException ee) {
    /* error occurred */
}
try { 
    val transaction = Transaction(paymentParams) 
    providerBinder.submitTransaction(transaction) 
} catch (ee: PaymentException) { 
    /* error occurred */ 
}