Search code examples
javaandroidcordovaandroid-fragmentsandroid-pay

Cordova Android Pay Wallet Request Returns Nothing


I am trying to write a plugin that will check if Android Pay is setup on the users phone. I have followed the Android tutorial with their sample code but can't get it to work with Cordova. When the function canMakePayments is called from the sample below, nothing happens. I do not see a failure or success come back from the call to Wallet.Payments.isReadyToPay. Any advise would be much appreciated.

package com.myapp.test;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface; 
import org.apache.cordova.CordovaWebView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;

import android.util.Log;
import android.support.annotation.NonNull;
import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.app.ProgressDialog;  

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.BooleanResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wallet.MaskedWallet;
import com.google.android.gms.wallet.MaskedWalletRequest;
import com.google.android.gms.wallet.Wallet;
import com.google.android.gms.wallet.WalletConstants;
import com.google.android.gms.wallet.fragment.SupportWalletFragment;
import com.google.android.gms.wallet.fragment.WalletFragmentInitParams;
import com.google.android.gms.wallet.fragment.WalletFragmentMode;
import com.google.android.gms.wallet.fragment.WalletFragmentOptions;
import com.google.android.gms.wallet.fragment.WalletFragmentStyle;

public class AndroidPay extends CordovaPlugin implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
    // actions
    private static final String CAN_MAKE_PAYMENTS = "canMakePayments";

    // Plugin tag name
    private static final String TAG = "AndroidPay";

    // Cordova callbacks
    CallbackContext canMakePaymentCallback = null;

    // Android Pay
    private SupportWalletFragment mWalletFragment;
    private GoogleApiClient mGoogleApiClient;
    public static final int WALLET_ENVIRONMENT = WalletConstants.ENVIRONMENT_TEST;


    /*
     *  Public function calls
     */


    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView); 
        Log.d(TAG, "Plugin initialized");
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        boolean validAction = true;

        if (action.equals(CAN_MAKE_PAYMENTS)) {
            canMakePayments(callbackContext);
        }
        else {
            validAction = false;
        }       
        return validAction;
    }

    /*
     *  Private function calls
     */

    private void canMakePayments(CallbackContext callbackContext) {
        Log.d(TAG, "canMakePayments");
        canMakePaymentCallback = callbackContext;       

        try {
            // Setup Google client
            mGoogleApiClient = new GoogleApiClient.Builder(this.cordova.getActivity())
                                .addApi(Wallet.API, new Wallet.WalletOptions.Builder()
                                    .setEnvironment(WALLET_ENVIRONMENT)
                                    .build())
                                .addConnectionCallbacks(this)
                                .addOnConnectionFailedListener(this)                            
                            .build();           

            // Check if user is ready to use Android Pay
            Wallet.Payments.isReadyToPay(mGoogleApiClient).setResultCallback(
                    new ResultCallback<BooleanResult>() {                   
                        @Override
                        public void onResult(@NonNull BooleanResult booleanResult) {    
                            if (booleanResult.getStatus().isSuccess()) {
                                if (booleanResult.getValue()) {
                                    // Show Android Pay buttons and user can make payments
                                    Log.d(TAG, "isReadyToPay:true");

                                    // TODO: Add logic
                                    canMakePaymentCallback.success();
                                } else {
                                    // Hide Android Pay buttons, user can't make payments
                                    Log.d(TAG, "isReadyToPay:false:" + booleanResult.getStatus());

                                    // TODO: Add logic
                                    canMakePaymentCallback.failure();
                                }
                            } else {
                                // Error making isReadyToPay call
                                Log.e(TAG, "isReadyToPay:" + booleanResult.getStatus());
                                canMakePaymentCallback.failure();
                            }
                        }
                    });         
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Exception: " + e.getMessage());
        }       

    }

    /**
     * Runs when a GoogleApiClient object successfully connects.
     */

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d(TAG, "***** onConnectionFailed:" + connectionResult.getErrorMessage());
    }

    @Override
    public void onConnectionSuspended(int cause) {
        Log.d(TAG, "***** Connection suspended *****");
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.d(TAG, "***** Connected to GoogleApiClient *****");
    }
}

Solution

  • It wasn't in the developer documentation but what fixed this for me was to make a connect call to the google client before calling Wallet.Payments.isReadyToPay

    mGoogleApiClient = new GoogleApiClient.Builder(this.cordova.getActivity())
                                    .addApi(Wallet.API, new Wallet.WalletOptions.Builder()
                                        .setEnvironment(WALLET_ENVIRONMENT)
                                        .build())
                                    .addConnectionCallbacks(this)
                                    .addOnConnectionFailedListener(this)                            
                                    .build();               
    
    // Connect to google api client
    mGoogleApiClient.connect();