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?

@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
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
Stripeobject. 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.
Most helpful comment
You'll want to specify
countryCodein theTransactionInfoconstructor.For example, if you are US-based: