Search code examples
androidgoogle-pay

IsReadyToPayRequest.existingPaymentMethodRequired not working as expected


We added Google Pay on our Android app, and the requirement from business it to only show the Google Pay button if the user has supported cards added already in his Google Pay account (on Google.com, not necessarily in the device's Wallet app).

For supported payment methods we only have PAN_ONLY, cards on file on Google.com (device token with CRYTOGRAM_3DS was not added here) For supported payment networks we have AMEX, MASTERCARD, VISA.

The parameter I tried to leverage is "existingPaymentMethodRequired" added to the isReadyToPay JSONObject with a "true" value.

JSONObject isReadyToPayRequest = getBaseRequest();
isReadyToPayRequest.put("allowedPaymentMethods", new JSONArray().put(getBaseCardPaymentMethod()));
isReadyToPayRequest.put("existingPaymentMethodRequired", true);
return Optional.of(isReadyToPayRequest);

The problem:

  • task.getResult() doesn't return the boolean as expected. The documentation mentions that the above parameter would only return true for TEST Environment, but on the contrary for the above options it seems to always return false in TEST Enviroment, and always returns true in PROD Enviroment (our app is already approved) regardless if the user has or doesn't have a card in his Google.com payment methods.

I also tested with strictly CRYPTOGRAM_3DS and cards added directly in the device Wallet, and that seems to work fine, but again stops working when you have both PAN_ONLY and CRYPTOGRAM_3D, regardless, I'm only interested in PAN_ONLY as that was the requirement.

  • The way I implemented this is through this (adjusted from sample app):
IsReadyToPayRequest request = IsReadyToPayRequest.fromJson(isReadyToPayJson.get().toString());
Task<Boolean> task = paymentsClient.isReadyToPay(request);
task.addOnCompleteListener(activity,
    new OnCompleteListener<Boolean>() {
        @Override
        public void onComplete(@NonNull Task<Boolean> task) {
            if (task.isSuccessful()) {
                if (task.getResult()) {
                    Logger.debug(getClass(), "GPay Debug isReadyToPay success");
                    initStatus = InitStatus.SUCCESS;
                } else {
                    Logger.debug(getClass(), "GPay Debug isReadyToPay failed - task result false");
                    initStatus = InitStatus.FAILED;
                }

                onShowGooglePayComplete(task.getResult());

            } else {
                initStatus = InitStatus.FAILED;
                onShowGooglePayComplete(false);
                Logger.debug(getClass(), "GPay Debug isReadyToPay failed" + (task.getException() != null ? task.getException().getMessage() : "null"));

            }
         }
      });

I'm starting to think that this is intended only for payment methods saved on the user's device, and not those that are on Google.com and would show when that Google Pay bottom sheet opens.

The documentation also mentions IsReadyToPayResponse with separate parameter paymentMethodPresent but I don't see any way to access this.

Is there something I'm missing here? Any help would be appreciated, thanks


Solution

  • I ended up using CRYPTOGRAM_3DS only as the allowed payment method to achieve the needed functionality. This comes at the caveat of only allowing payments through Google Pay from cards that are also added in the device's Wallet app, but it was what was needed for this requirement.

    For whoever stumbles upon this, I've tested like this:

    Google Pay ENVIRONMENT_PRODUCTION

    • signed prodRelease apk
    • existingPaymentMethodRequired true

    Payment methods enabled:

    • CRYPTOGRAM_3DS:
      • cards available in Google.com + no cards added to Wallet Button doesn't show
      • cards available in Google.com + card added to Wallet Button shows - card available is the one from Wallet
      • no cards available anywhere Button doesn't show
    • CRYPTOGRAM_3DS + PAN_ONLY:
      • cards available in Google.com + no cards added to Wallet Button shows
      • cards available in Google.com + card added to Wallet Button shows
      • no cards available anywhere Button shows - user is required to add a new card
    • PAN_ONLY: (this is the old/initial implementation)
      • cards available in Google.com + no cards added to Wallet Button shows
      • cards available in Google.com + card added to Wallet Button shows
      • no cards available anywhere Button doesn't show