Stripe-android: Google Pay - Strong Customer Authentication

Created on 8 Jan 2021  路  10Comments  路  Source: stripe/stripe-android

We are using Google Pay via the Stripe SDK, and just receive from Google the email shown below.
What do we need to do to comply with this?

Screenshot at Jan 08 12-21-40

triaged

Most helpful comment

You'll want to specify countryCode in the TransactionInfo constructor.

For example, if you are US-based:

GooglePayJsonFactory.TransactionInfo(
    countryCode = "US",
    // other properties
)

All 10 comments

@odedharth thanks for filing this issue. Can you share the code you're using to configure Google Pay?

@mshafrir-stripe Here is the code we are using to configure google play.
```
private fun createPaymentDataRequest(shippableCountries: List): PaymentDataRequest {
return PaymentDataRequest.fromJson(
googlePayJsonFactory.createPaymentDataRequest(
transactionInfo = GooglePayJsonFactory.TransactionInfo(
currencyCode = "USD",
totalPrice = 10000,
totalPriceStatus = GooglePayJsonFactory.TransactionInfo.TotalPriceStatus.Final
),
merchantInfo = GooglePayJsonFactory.MerchantInfo(
merchantName = "MDacne"
),
shippingAddressParameters = GooglePayJsonFactory.ShippingAddressParameters(
isRequired = true,
allowedCountryCodes = shippableCountries.toSet(),
phoneNumberRequired = true
),
billingAddressParameters = GooglePayJsonFactory.BillingAddressParameters(
isRequired = true,
format = GooglePayJsonFactory.BillingAddressParameters.Format.Full,
isPhoneNumberRequired = true
)
).toString()
)
}

You'll want to specify countryCode in the TransactionInfo constructor.

For example, if you are US-based:

GooglePayJsonFactory.TransactionInfo(
    countryCode = "US",
    // other properties
)

@mshafrir-stripe
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.stripe.android.Stripe.createPaymentMethod(com.stripe.android.model.PaymentMethodCreateParams, com.stripe.android.ApiResultCallback)' on a null object reference
How to fix this.
PaymentMethodCreateParams(type=Card, card=Card(number=null, expiryMonth=null, expiryYear=null, cvc=null, token=tok_1IFvBNKxupsjK3gAwqIq2xXz, attribution=[GooglePay]), ideal=null, fpx=null, sepaDebit=null, auBecsDebit=null, bacsDebit=null, sofort=null, upi=null, netbanking=null, billingDetails=BillingDetails(address=null, [email protected], name=null, phone=null), metadata=null, productUsage=[])

@Irfanhaidermomin can you provide some code that shows how you are integrating?

@Irfanhaidermomin can you provide some code that shows how you are integrating?

https://stripe.com/docs/google-pay as per your doc.

private PaymentsClient paymentsClient;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    PaymentConfiguration.init(this, STRIPE_KEY);

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

    isReadyToPay();
}

private void isReadyToPay() {
    try {
        final IsReadyToPayRequest request = createIsReadyToPayRequest();
        paymentsClient.isReadyToPay(request)
                .addOnCompleteListener(
                        new OnCompleteListener<Boolean>() {
                            public void onComplete(Task<Boolean> task) {
                                try {
                                    if (task.isSuccessful()) {
                                        clPayWithGpay.setEnabled(true);
                                        // show Google Pay as payment option
                                    } else {
                                        clPayWithGpay.setEnabled(false);
                                        // hide Google Pay as payment option
                                    }
                                } catch (Exception exception) {
                                    //tvError.setText("isReadyToPay: " + exception.getMessage());
                                }
                            }
                        }
                );
    } catch (Exception ex) {
        // tvError.setText("isReadyToPayFinal: " + ex.getMessage());
    }
}

@NonNull
private IsReadyToPayRequest createIsReadyToPayRequest() throws JSONException {
    final JSONArray allowedAuthMethods = new JSONArray();
    allowedAuthMethods.put("PAN_ONLY");
    allowedAuthMethods.put("CRYPTOGRAM_3DS");

    final JSONArray allowedCardNetworks = new JSONArray();
    allowedCardNetworks.put("AMEX");
    allowedCardNetworks.put("DISCOVER");
    allowedCardNetworks.put("MASTERCARD");
    allowedCardNetworks.put("VISA");
    allowedCardNetworks.put("INTERAC");
    allowedCardNetworks.put("JCB");

    final JSONObject cardParameters = new JSONObject();
    cardParameters.put("allowedAuthMethods", allowedAuthMethods);
    cardParameters.put("allowedCardNetworks", allowedCardNetworks);

    final JSONObject cardPaymentMethod = new JSONObject();
    cardPaymentMethod.put("type", "CARD");
    cardPaymentMethod.put("parameters", cardParameters);

    final JSONArray allowedPaymentMethods = new JSONArray();
    allowedPaymentMethods.put(cardPaymentMethod);

    final JSONObject isReadyToPayRequestJson = new JSONObject();
    isReadyToPayRequestJson.put("apiVersion", 2);
    isReadyToPayRequestJson.put("apiVersionMinor", 0);
    isReadyToPayRequestJson.put("allowedPaymentMethods", allowedPaymentMethods);

    return IsReadyToPayRequest.fromJson(isReadyToPayRequestJson.toString());
}

private void payWithGoogle() {
    try {

        isConnected = ConnectivityReceiver.isConnected();
        if (!isConnected) {
            showAlertDialog(this, getString(R.string.internetTitle),
                    getString(R.string.internetMsg), getString(R.string.fromCheckout));
        } else {
            PaymentDataRequest request = createPaymentDataRequest();
            AutoResolveHelper.resolveTask(
                    paymentsClient.loadPaymentData(request),
                    this,
                    LOAD_PAYMENT_DATA_REQUEST_CODE
            );
        }
    } catch (Exception ex) {
        //tvError.setText("payWithGoogle: " + ex.getMessage());
    }
}

@NonNull
private PaymentDataRequest createPaymentDataRequest() throws JSONException {
    final JSONObject tokenizationSpec =
            new GooglePayConfig(STRIPE_KEY,stripeAccountID).getTokenizationSpecification();
    final JSONObject cardPaymentMethod = new JSONObject()
            .put("type", "CARD")
            .put(
                    "parameters",
                    new JSONObject()
                            .put("allowedAuthMethods", new JSONArray()
                                    .put("PAN_ONLY")
                                    .put("CRYPTOGRAM_3DS"))
                            .put("allowedCardNetworks",
                                    new JSONArray()
                                            .put("AMEX")
                                            .put("DISCOVER")
                                            .put("MASTERCARD")
                                            .put("VISA"))

                            // require billing address
                            .put("billingAddressRequired", false)
                            .put(
                                    "billingAddressParameters",
                                    new JSONObject()
                                            // require full billing address
                                            .put("format", "MIN")

                                            // require phone number
                                            .put("phoneNumberRequired", true)
                            )
            )
            .put("tokenizationSpecification", tokenizationSpec);

    // create PaymentDataRequest
    final JSONObject paymentDataRequest = new JSONObject()
            .put("apiVersion", 2)
            .put("apiVersionMinor", 0)
            .put("allowedPaymentMethods",
                    new JSONArray().put(cardPaymentMethod))
            .put("transactionInfo",
                    new JSONObject()
                            .put("totalPrice", "1.00")
                            .put("totalPriceStatus", "FINAL")
                            .put("currencyCode", "AUD")
                            .put("countryCode", "AU")
            )
            .put("merchantInfo",
                    new JSONObject()
                            .put("merchantId", merchantId)
                            .put("merchantName", merchantName))

            // require email address
            .put("emailRequired", true);
    // .toString();

    return PaymentDataRequest.fromJson(String.valueOf(paymentDataRequest));
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    paymentSession.handlePaymentData(requestCode, resultCode, data);

     if (requestCode == LOAD_PAYMENT_DATA_REQUEST_CODE) {
        if (data != null) {
            onGooglePayResult(data);
        }
    }

private void onGooglePayResult(@NonNull Intent data) {
    try {
        final PaymentData paymentData = PaymentData.getFromIntent(data);
        if (paymentData == null) {
            return;
        }

        final PaymentMethodCreateParams paymentMethodCreateParams =
                PaymentMethodCreateParams.createFromGooglePay(new JSONObject(paymentData.toJson()));

             // There was an error 
            stripe.createPaymentMethod(paymentMethodCreateParams, new ApiResultCallback<PaymentMethod>() {
            @Override
            public void onSuccess(@NotNull PaymentMethod paymentMethod) {
                paymentMethodID=paymentMethod.id;
            }

            @Override
            public void onError(@NotNull Exception e) {

            }
        });

    } catch (JSONException exception) {
        Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show();

    }
}

@mshafrir-stripe Have you checked?

@Irfanhaidermomin can you provide some code that shows how you are integrating?

https://stripe.com/docs/google-pay as per your doc.

private PaymentsClient paymentsClient;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    PaymentConfiguration.init(this, STRIPE_KEY);

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

    isReadyToPay();
}

private void isReadyToPay() {
    try {
        final IsReadyToPayRequest request = createIsReadyToPayRequest();
        paymentsClient.isReadyToPay(request)
                .addOnCompleteListener(
                        new OnCompleteListener<Boolean>() {
                            public void onComplete(Task<Boolean> task) {
                                try {
                                    if (task.isSuccessful()) {
                                        clPayWithGpay.setEnabled(true);
                                        // show Google Pay as payment option
                                    } else {
                                        clPayWithGpay.setEnabled(false);
                                        // hide Google Pay as payment option
                                    }
                                } catch (Exception exception) {
                                    //tvError.setText("isReadyToPay: " + exception.getMessage());
                                }
                            }
                        }
                );
    } catch (Exception ex) {
        // tvError.setText("isReadyToPayFinal: " + ex.getMessage());
    }
}

@NonNull
private IsReadyToPayRequest createIsReadyToPayRequest() throws JSONException {
    final JSONArray allowedAuthMethods = new JSONArray();
    allowedAuthMethods.put("PAN_ONLY");
    allowedAuthMethods.put("CRYPTOGRAM_3DS");

    final JSONArray allowedCardNetworks = new JSONArray();
    allowedCardNetworks.put("AMEX");
    allowedCardNetworks.put("DISCOVER");
    allowedCardNetworks.put("MASTERCARD");
    allowedCardNetworks.put("VISA");
    allowedCardNetworks.put("INTERAC");
    allowedCardNetworks.put("JCB");

    final JSONObject cardParameters = new JSONObject();
    cardParameters.put("allowedAuthMethods", allowedAuthMethods);
    cardParameters.put("allowedCardNetworks", allowedCardNetworks);

    final JSONObject cardPaymentMethod = new JSONObject();
    cardPaymentMethod.put("type", "CARD");
    cardPaymentMethod.put("parameters", cardParameters);

    final JSONArray allowedPaymentMethods = new JSONArray();
    allowedPaymentMethods.put(cardPaymentMethod);

    final JSONObject isReadyToPayRequestJson = new JSONObject();
    isReadyToPayRequestJson.put("apiVersion", 2);
    isReadyToPayRequestJson.put("apiVersionMinor", 0);
    isReadyToPayRequestJson.put("allowedPaymentMethods", allowedPaymentMethods);

    return IsReadyToPayRequest.fromJson(isReadyToPayRequestJson.toString());
}

private void payWithGoogle() {
    try {

        isConnected = ConnectivityReceiver.isConnected();
        if (!isConnected) {
            showAlertDialog(this, getString(R.string.internetTitle),
                    getString(R.string.internetMsg), getString(R.string.fromCheckout));
        } else {
            PaymentDataRequest request = createPaymentDataRequest();
            AutoResolveHelper.resolveTask(
                    paymentsClient.loadPaymentData(request),
                    this,
                    LOAD_PAYMENT_DATA_REQUEST_CODE
            );
        }
    } catch (Exception ex) {
        //tvError.setText("payWithGoogle: " + ex.getMessage());
    }
}

@NonNull
private PaymentDataRequest createPaymentDataRequest() throws JSONException {
    final JSONObject tokenizationSpec =
            new GooglePayConfig(STRIPE_KEY,stripeAccountID).getTokenizationSpecification();
    final JSONObject cardPaymentMethod = new JSONObject()
            .put("type", "CARD")
            .put(
                    "parameters",
                    new JSONObject()
                            .put("allowedAuthMethods", new JSONArray()
                                    .put("PAN_ONLY")
                                    .put("CRYPTOGRAM_3DS"))
                            .put("allowedCardNetworks",
                                    new JSONArray()
                                            .put("AMEX")
                                            .put("DISCOVER")
                                            .put("MASTERCARD")
                                            .put("VISA"))

                            // require billing address
                            .put("billingAddressRequired", false)
                            .put(
                                    "billingAddressParameters",
                                    new JSONObject()
                                            // require full billing address
                                            .put("format", "MIN")

                                            // require phone number
                                            .put("phoneNumberRequired", true)
                            )
            )
            .put("tokenizationSpecification", tokenizationSpec);

    // create PaymentDataRequest
    final JSONObject paymentDataRequest = new JSONObject()
            .put("apiVersion", 2)
            .put("apiVersionMinor", 0)
            .put("allowedPaymentMethods",
                    new JSONArray().put(cardPaymentMethod))
            .put("transactionInfo",
                    new JSONObject()
                            .put("totalPrice", "1.00")
                            .put("totalPriceStatus", "FINAL")
                            .put("currencyCode", "AUD")
                            .put("countryCode", "AU")
            )
            .put("merchantInfo",
                    new JSONObject()
                            .put("merchantId", merchantId)
                            .put("merchantName", merchantName))

            // require email address
            .put("emailRequired", true);
    // .toString();

    return PaymentDataRequest.fromJson(String.valueOf(paymentDataRequest));
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    paymentSession.handlePaymentData(requestCode, resultCode, data);

     if (requestCode == LOAD_PAYMENT_DATA_REQUEST_CODE) {
        if (data != null) {
            onGooglePayResult(data);
        }
    }

private void onGooglePayResult(@NonNull Intent data) {
    try {
        final PaymentData paymentData = PaymentData.getFromIntent(data);
        if (paymentData == null) {
            return;
        }

        final PaymentMethodCreateParams paymentMethodCreateParams =
                PaymentMethodCreateParams.createFromGooglePay(new JSONObject(paymentData.toJson()));

             // There was an error 
            stripe.createPaymentMethod(paymentMethodCreateParams, new ApiResultCallback<PaymentMethod>() {
            @Override
            public void onSuccess(@NotNull PaymentMethod paymentMethod) {
                paymentMethodID=paymentMethod.id;
            }

            @Override
            public void onError(@NotNull Exception e) {

            }
        });

    } catch (JSONException exception) {
        Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show();

    }
}

@mshafrir-stripe Have you checked?

@mshafrir-stripe Please check this and give me reply.

@Irfanhaidermomin looks like our docs aren't specifying that you need to instantiate the Stripe object. I can fix that.

@Irfanhaidermomin looks like our docs aren't specifying that you need to instantiate the Stripe object. I can fix that.

@mshafrir Thanks a lot.

The docs should be updated now. Let me know if you need any other help with this issue.

Was this page helpful?
0 / 5 - 0 ratings