Collecting payment information through Pay with Google

    Allow customers to securely make payments using Pay with Google on their Android devices. Pay with Google allows customers to securely make payments using any options saved to a customer's Google Account—including Google Play, YouTube, Chrome, or Android Pay.

    To use Pay with Google, first enable the Android Pay API by adding the following to the <application> tag of your AndroidManifest.xml:

    <application
      ...
      <meta-data
        android:name="com.google.android.gms.wallet.api.enabled"
        android:value="true" />
    </application>
    You must also be using Google Play Services 11.4.0 or later:
    dependencies {
      compile 'com.google.android.gms:play-services-wallet:11.4.2'
      // You'll also need the support-v4 and appcompat-v7 libraries
      compile 'com.android.support:support-v4:26.0.1'
      compile 'com.android.support:appcompat-v7:26.0.1'
    }
    

    Next, create an instance of PaymentsClient in your Activity. This allows you to access the Payments APIs. Do this before you start the payment flow, such as in onCreate.

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

    After creatingPaymentsClient, create an instance of IsReadyToPayRequest to see whether or not to display Pay with Google as an option.

    private void isReadyToPay() {
      IsReadyToPayRequest request = IsReadyToPayRequest.newBuilder()
        .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
        .addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
        .build();
      Task<Boolean> task = paymentsClient.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) { }
            }
          });
    }
    

    When the user is ready to pay, create a PaymentDataRequest object. The PaymentDataRequest object is a Parcelable representing a request for methods of payment (such as a credit card) and other details. It provides the necessary information to support a payment.

    To create a PaymentDataRequest object using Stripe as your gateway, create a PaymentMethodTokenizationParameters object with your credentials.

    private PaymentMethodTokenizationParameters createTokenizationParameters() {
      return PaymentMethodTokenizationParameters.newBuilder()
        .setPaymentMethodTokenizationType(WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY)
        .addParameter("gateway", "stripe")
        .addParameter("stripe:publishableKey", "pk_test_6pRNASCoBOKtIshFeQd4XMUh")
        .addParameter("stripe:version", "5.1.0")
        .build();
    }

    Once you have your tokenization parameters, create the PaymentDataRequest object with the information relevant to the purchase.

    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());
    
      request.setPaymentMethodTokenizationParameters(createTokenizationParameters());
      return request.build();
    }
    

    Now that you’ve established a way to create the payment data request, hook up that method to your “Buy” button’s click handler.

    findViewById(R.id.buy_button).setOnClickListener(
      new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          PaymentDataRequest request = createPaymentDataRequest();
          if (request != null) {
            AutoResolveHelper.resolveTask(
              paymentsClient.loadPaymentData(request),
              this,
              LOAD_PAYMENT_DATA_REQUEST_CODE);
              // LOAD_PAYMENT_DATA_REQUEST_CODE is a constant integer of your choice,
              // similar to what you would use in startActivityForResult
          }
        }
      });
    

    Invoking the AutoResolveHelper’s resolveTask function with a PaymentDataRequest will launch Pay with Google. In order to handle the result of this action, listen for it in the onActivityResult function of your Activity.

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      switch (requestCode) {
        case LOAD_PAYMENT_DATA_REQUEST_CODE:
          switch (resultCode) {
            case Activity.RESULT_OK:
              PaymentData paymentData = PaymentData.getFromIntent(data);
              // You can get some data on the user's card, such as the brand and last 4 digits
              CardInfo info = paymentData.getCardInfo();
              // You can also pull the user address from the PaymentData object.
              UserAddress address = paymentData.getShippingAddress();
              // This is the raw JSON string version of your Stripe token.
              String rawToken = paymentData.getPaymentMethodToken().getToken();
    
              // Now that you have a Stripe token object, charge that by using the id
              Token stripeToken = Token.fromString(rawToken);
              if (stripeToken != null) {
                  // This chargeToken function is a call to your own server, which should then connect
                  // to Stripe's API to finish the charge.
                  chargeToken(stripeToken.getId());
              }
              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; // Breaks the case LOAD_PAYMENT_DATA_REQUEST_CODE
          // Handle any other startActivityForResult calls you may have made.
        default:
          // Do nothing.
        }
    }