com.vantiv.android.gms.samples.wallet.CheckoutActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.vantiv.android.gms.samples.wallet.CheckoutActivity.java

Source

/*
 * Copyright Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.vantiv.android.gms.samples.wallet;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.ApiException;
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.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.wallet.AutoResolveHelper;
import com.google.android.gms.wallet.CardRequirements;
import com.google.android.gms.wallet.IsReadyToPayRequest;
import com.google.android.gms.wallet.PaymentData;
import com.google.android.gms.wallet.PaymentDataRequest;
import com.google.android.gms.wallet.PaymentMethodTokenizationParameters;
import com.google.android.gms.wallet.PaymentsClient;
import com.google.android.gms.wallet.MaskedWallet;
import com.google.android.gms.wallet.MaskedWalletRequest;
import com.google.android.gms.wallet.TransactionInfo;
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;

import java.util.Arrays;

/**
 * The checkout page.
 *
 * Handles login and logout, but most of the interesting things happen in the WalletFragment
 * that is hosted by this activity.
 * Other pages further in the checkout process will send users back to this page if an error occurs,
 * so {@link #onNewIntent(Intent)} needs to check to see if an error code has been passed in.
 */
public class CheckoutActivity extends BikestoreFragmentActivity implements View.OnClickListener,
        CompoundButton.OnCheckedChangeListener, GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "CheckoutActivity";
    private static final int REQUEST_CODE_MASKED_WALLET = 1001;

    private SupportWalletFragment mWalletFragment;
    private int mItemId;
    private Button mReturnToShopping;
    private Button mContinueCheckout;
    private CheckBox mStripeCheckbox;
    private CheckBox mVantivCheckbox;
    private boolean mUseStripe = false;
    private boolean mUseVantiv = false;
    private GoogleApiClient mGoogleApiClient;
    private PaymentsClient mPaymentsClient;
    private ProgressDialog mProgressDialog;
    private static final int LOAD_PAYMENT_DATA_REQUEST_CODE = 1313;
    private final Activity activity = (Activity) this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_checkout);

        // [START basic_google_api_client]
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wallet.API,
                        new Wallet.WalletOptions.Builder().setEnvironment(Constants.WALLET_ENVIRONMENT).build())
                .enableAutoManage(this, this).build();
        // [END basic_google_api_client]

        mPaymentsClient = Wallet.getPaymentsClient(this,
                new Wallet.WalletOptions.Builder().setEnvironment(WalletConstants.ENVIRONMENT_TEST).build());

        isReadyToPay();

        mItemId = getIntent().getIntExtra(Constants.EXTRA_ITEM_ID, 0);
        mReturnToShopping = (Button) findViewById(R.id.button_return_to_shopping);
        mReturnToShopping.setOnClickListener(this);
        mContinueCheckout = (Button) findViewById(R.id.button_regular_checkout);
        mContinueCheckout.setOnClickListener(this);

        mStripeCheckbox = (CheckBox) findViewById(R.id.checkbox_stripe);
        mStripeCheckbox.setOnCheckedChangeListener(this);

        mVantivCheckbox = (CheckBox) findViewById(R.id.checkbox_vantiv);
        mVantivCheckbox.setOnCheckedChangeListener(this);

        // Check if user is ready to use Android Pay
        // [START is_ready_to_pay]
        showProgressDialog();
        Wallet.Payments.isReadyToPay(mGoogleApiClient).setResultCallback(new ResultCallback<BooleanResult>() {
            @Override
            public void onResult(@NonNull BooleanResult booleanResult) {
                hideProgressDialog();

                if (booleanResult.getStatus().isSuccess()) {
                    if (booleanResult.getValue()) {
                        // Show Android Pay buttons and hide regular checkout button
                        // [START_EXCLUDE]
                        Log.d(TAG, "isReadyToPay:true");
                        createAndAddWalletFragment();
                        findViewById(R.id.button_regular_checkout).setVisibility(View.GONE);
                        // [END_EXCLUDE]
                    } else {
                        // Hide Android Pay buttons, show a message that Android Pay
                        // cannot be used yet, and display a traditional checkout button
                        // [START_EXCLUDE]
                        Log.d(TAG, "isReadyToPay:false:" + booleanResult.getStatus());
                        findViewById(R.id.layout_android_pay_checkout).setVisibility(View.GONE);
                        findViewById(R.id.android_pay_message).setVisibility(View.VISIBLE);
                        findViewById(R.id.button_regular_checkout).setVisibility(View.VISIBLE);
                        // [END_EXCLUDE]
                    }
                } else {
                    // Error making isReadyToPay call
                    Log.e(TAG, "isReadyToPay:" + booleanResult.getStatus());
                }
            }
        });
        // [END is_ready_to_pay]

        try {
            findViewById(R.id.button_pay_with_google).setOnClickListener(this);
        } catch (Exception e) {
            // This will catch any exception, because they are all descended from Exception
            System.out.println("Error " + e.getMessage());
        }
    }

    private void isReadyToPay() {
        IsReadyToPayRequest request = IsReadyToPayRequest.newBuilder()
                .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
                .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD).build();
        Task<Boolean> task = mPaymentsClient.isReadyToPay(request);
        task.addOnCompleteListener(new OnCompleteListener<Boolean>() {
            public void onComplete(Task<Boolean> task) {
                try {
                    boolean result = task.getResult(ApiException.class);
                    if (result == true) {
                        // Show Google as payment option.
                    } else {
                        // Hide Google as payment option.
                    }
                } catch (ApiException exception) {
                }
            }
        });
    }

    private PaymentDataRequest createPaymentDataRequest() {
        PaymentDataRequest.Builder request = PaymentDataRequest.newBuilder()
                .setTransactionInfo(
                        TransactionInfo.newBuilder().setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
                                .setTotalPrice("10.00").setCurrencyCode("USD").build())
                .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
                .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
                .setCardRequirements(CardRequirements.newBuilder()
                        .addAllowedCardNetworks(Arrays.asList(WalletConstants.CARD_NETWORK_AMEX,
                                WalletConstants.CARD_NETWORK_DISCOVER, WalletConstants.CARD_NETWORK_VISA,
                                WalletConstants.CARD_NETWORK_MASTERCARD))
                        .build());

        PaymentMethodTokenizationParameters params = PaymentMethodTokenizationParameters.newBuilder()
                .setPaymentMethodTokenizationType(WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY)
                .addParameter("gateway", "vantiv")
                //.addParameter("gatewayMerchantId", "yourMerchantIdGivenFromYourGateway")
                .addParameter("vantiv:merchantPayPageId", getString(R.string.vantiv_paypageid))
                .addParameter("vantiv:merchantOrderId", "orderId")
                .addParameter("vantiv:merchantTransactionId", "tranId")
                .addParameter("vantiv:merchantReportGroup", "reportGroup").build();

        request.setPaymentMethodTokenizationParameters(params);
        return request.build();
    }

    // [START on_activity_result]
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // retrieve the error code, if available
        int errorCode = -1;
        if (data != null) {
            errorCode = data.getIntExtra(WalletConstants.EXTRA_ERROR_CODE, -1);
        }
        switch (requestCode) {
        case REQUEST_CODE_MASKED_WALLET:
            switch (resultCode) {
            case Activity.RESULT_OK:
                if (data != null) {
                    MaskedWallet maskedWallet = data.getParcelableExtra(WalletConstants.EXTRA_MASKED_WALLET);
                    launchConfirmationPage(maskedWallet);
                }
                break;
            case Activity.RESULT_CANCELED:
                break;
            default:
                handleError(errorCode);
                break;
            }
            break;
        case WalletConstants.RESULT_ERROR:
            handleError(errorCode);
            break;
        case LOAD_PAYMENT_DATA_REQUEST_CODE:
            switch (resultCode) {
            case Activity.RESULT_OK:
                PaymentData paymentData = PaymentData.getFromIntent(data);
                String token = paymentData.getPaymentMethodToken().getToken();
                break;
            case Activity.RESULT_CANCELED:
                break;
            case AutoResolveHelper.RESULT_ERROR:
                Status status = AutoResolveHelper.getStatusFromIntent(data);
                // Log the status for debugging.
                // Generally, there is no need to show an error to
                // the user as the Google Payment API will do that.
                break;
            default:
                // Do nothing.
            }
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
            break;
        }
    }
    // [END on_activity_result]

    /**
     * If the confirmation page encounters an error it can't handle, it will send the customer back
     * to this page.  The intent should include the error code as an {@code int} in the field
     * {@link WalletConstants#EXTRA_ERROR_CODE}.
     */
    @Override
    protected void onNewIntent(Intent intent) {
        if (intent.hasExtra(WalletConstants.EXTRA_ERROR_CODE)) {
            int errorCode = intent.getIntExtra(WalletConstants.EXTRA_ERROR_CODE, 0);
            handleError(errorCode);
        }
    }

    private void goToItemListActivity() {
        Intent intent = new Intent(this, ItemListActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }

    private void continueCheckout() {
        Toast.makeText(this, R.string.checkout_bikestore_message, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onClick(View v) {
        if (v == mReturnToShopping) {
            goToItemListActivity();
        } else if (v == mContinueCheckout) {
            continueCheckout();
        } else if (v == findViewById(R.id.button_pay_with_google)) {
            PaymentDataRequest request = createPaymentDataRequest();
            if (request != null) {
                AutoResolveHelper.resolveTask(mPaymentsClient.loadPaymentData(request), this,
                        // LOAD_PAYMENT_DATA_REQUEST_CODE is a constant value
                        // you define.
                        LOAD_PAYMENT_DATA_REQUEST_CODE);
            }
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView.getId() == R.id.checkbox_stripe) {
            mUseStripe = isChecked;

            // Re-create the buy-button with the proper processor
            createAndAddWalletFragment();
        }
        if (buttonView.getId() == R.id.checkbox_vantiv) {
            mUseVantiv = isChecked;

            // Re-create the buy-button with the proper processor
            createAndAddWalletFragment();
        }
    }

    private void createAndAddWalletFragment() {
        // [START fragment_style_and_options]
        WalletFragmentStyle walletFragmentStyle = new WalletFragmentStyle()
                .setBuyButtonText(WalletFragmentStyle.BuyButtonText.BUY_WITH)
                .setBuyButtonAppearance(WalletFragmentStyle.BuyButtonAppearance.ANDROID_PAY_DARK)
                .setBuyButtonWidth(WalletFragmentStyle.Dimension.MATCH_PARENT);

        WalletFragmentOptions walletFragmentOptions = WalletFragmentOptions.newBuilder()
                .setEnvironment(Constants.WALLET_ENVIRONMENT).setFragmentStyle(walletFragmentStyle)
                .setTheme(WalletConstants.THEME_LIGHT).setMode(WalletFragmentMode.BUY_BUTTON).build();
        mWalletFragment = SupportWalletFragment.newInstance(walletFragmentOptions);
        // [END fragment_style_and_options]

        // Now initialize the Wallet Fragment
        String accountName = ((BikestoreApplication) getApplication()).getAccountName();
        MaskedWalletRequest maskedWalletRequest;
        if (mUseStripe) {
            // Stripe integration
            maskedWalletRequest = WalletUtil.createStripeMaskedWalletRequest(Constants.ITEMS_FOR_SALE[mItemId],
                    getString(R.string.stripe_publishable_key), getString(R.string.stripe_version));
        } else if (mUseVantiv) {
            // Vantiv integration
            maskedWalletRequest = WalletUtil.createVantivMaskedWalletRequest(Constants.ITEMS_FOR_SALE[mItemId],
                    getString(R.string.vantiv_paypageid), "orderId", "tranId", "reportGroup");
        } else {
            // Direct integration
            maskedWalletRequest = WalletUtil.createMaskedWalletRequest(Constants.ITEMS_FOR_SALE[mItemId],
                    getString(R.string.public_key));
        }

        // [START params_builder]
        WalletFragmentInitParams.Builder startParamsBuilder = WalletFragmentInitParams.newBuilder()
                .setMaskedWalletRequest(maskedWalletRequest).setMaskedWalletRequestCode(REQUEST_CODE_MASKED_WALLET)
                .setAccountName(accountName);
        mWalletFragment.initialize(startParamsBuilder.build());

        // add Wallet fragment to the UI
        getSupportFragmentManager().beginTransaction().replace(R.id.dynamic_wallet_button_fragment, mWalletFragment)
                .commit();
        // [END params_builder]
    }

    private void launchConfirmationPage(MaskedWallet maskedWallet) {
        Intent intent = new Intent(this, ConfirmationActivity.class);
        intent.putExtra(Constants.EXTRA_ITEM_ID, mItemId);
        intent.putExtra(Constants.EXTRA_MASKED_WALLET, maskedWallet);
        startActivity(intent);
    }

    @Override
    public Fragment getResultTargetFragment() {
        return null;
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e(TAG, "onConnectionFailed:" + connectionResult.getErrorMessage());
        Toast.makeText(this, "Google Play Services error", Toast.LENGTH_SHORT).show();
    }

    private void showProgressDialog() {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setIndeterminate(true);
            mProgressDialog.setMessage("Loading...");
        }

        mProgressDialog.show();
    }

    private void hideProgressDialog() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.hide();
        }
    }
}