You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PaymentSheet cannot show the Google Pay button in GooglePayEnvironment.Test, because it probes Google with existingPaymentMethodRequired = true and offers no way to change that. On a physical device with a Google account holding eligible cards, Google answers false to that request in Test — and true to the identical request in Production.
Removing only that flag makes the Test-environment request answer true, the button renders, and a test payment completes. That is the advice given in #7230, but PaymentSheet provides no way to follow it.
This is the same problem as #9548 (closed after the reporter switched Google accounts) and flutter-stripe/flutter_stripe#2108 (closed as an emulator limitation). Neither explanation applies here: real device, and the same account works in Production.
Environment
stripe-android 23.1.0 (via flutter_stripe 12.6.0, which pins ext.stripe_version = '23.1.+')
Physical Pixel 6a, Google Play services present, Google account signed in
Google account holds Visa + Mastercard → allowedCardNetworks["AMEX","DISCOVER","MASTERCARD","VISA"] satisfied, no JCB dependency
Stripe account: US, charges_enabled, google_payavailable with display_preference = on (verified via GET /v1/payment_method_configurations)
Flow: PaymentSheet, non-deferred, PaymentIntent with payment_method_types: ["card"], server-created CustomerSession
Steps to reproduce
Configure PaymentSheet with PaymentSheet.GooglePayConfiguration(environment = Environment.Test, …) and a pk_test key.
Present the sheet on a real device signed into a Google account that has a Visa/Mastercard.
No Google Pay row. Logcat (app is debuggable, so RealUserFacingLogger prints):
W/StripeSdk: Google Pay API check failed.
W/StripeSdk: Possible reasons:
W/StripeSdk: - Google Play service is not available on this device.
W/StripeSdk: - Google account is not signed in on this device.
Both stated reasons are false on this device.
Change only environment to Environment.Production, keeping everything else identical → the row renders. (The payment then fails with OR_BIBED_06 "Invalid stripe:publishableKey for current environment", as expected for a test key — but the readiness answer flipped.)
Evidence that the flag is the cause
Swapping the availability client — the same seam used by FakeGooglePayRepositoryRule in your instrumentation tests — and re-sending the request with existingPaymentMethodRequired removed:
Result on the same device, same account, still Environment.Test and pk_test:
isReadyToPay → true
Google Pay row renders in PaymentSheet
Test payment completes successfully
So nothing about the account, the device, the cards or the Stripe account is at fault; the single differing input is that one flag.
Why this matters beyond dev convenience
Google requires screenshots of a working integration in the Test environment to grant production access. With PaymentSheet unable to render the button in Test, and Production refusing test keys, an integration can end up unable to produce the screenshots needed to be allowed into Production. #9548 raised exactly this loop.
Requests
Let PaymentSheet.GooglePayConfiguration set existingPaymentMethodRequired, or send it as false when environment == Test (per your own guidance in [BUG] [Google Pay] Google pay no show in test environment #7230). Test-environment readiness has no bearing on whether a real user can pay.
Surface the underlying failure. DefaultGooglePayRepository.isReadyAsync() funnels every failure through runCatching { … }.getOrDefault(false) and logs the reason with Logger.getInstance(BuildConfig.DEBUG), which is off in the released AAR — so integrators only ever see the generic two-reason UserFacingLogger message, neither reason being the actual cause. Routing GOOGLE_PAY_IS_READY_API_CALL / GOOGLE_PAY_JSON_REQUEST_PARSING through UserFacingLogger would turn a multi-day investigation into one log line.
Summary
PaymentSheetcannot show the Google Pay button inGooglePayEnvironment.Test, because it probes Google withexistingPaymentMethodRequired = trueand offers no way to change that. On a physical device with a Google account holding eligible cards, Google answersfalseto that request in Test — andtrueto the identical request in Production.Removing only that flag makes the Test-environment request answer
true, the button renders, and a test payment completes. That is the advice given in #7230, butPaymentSheetprovides no way to follow it.This is the same problem as #9548 (closed after the reporter switched Google accounts) and flutter-stripe/flutter_stripe#2108 (closed as an emulator limitation). Neither explanation applies here: real device, and the same account works in Production.
Environment
ext.stripe_version = '23.1.+')allowedCardNetworks["AMEX","DISCOVER","MASTERCARD","VISA"]satisfied, no JCB dependencycharges_enabled,google_payavailablewithdisplay_preference = on(verified viaGET /v1/payment_method_configurations)PaymentSheet, non-deferred, PaymentIntent withpayment_method_types: ["card"], server-created CustomerSessionSteps to reproduce
PaymentSheetwithPaymentSheet.GooglePayConfiguration(environment = Environment.Test, …)and apk_testkey.RealUserFacingLoggerprints):Both stated reasons are false on this device.
environmenttoEnvironment.Production, keeping everything else identical → the row renders. (The payment then fails withOR_BIBED_06"Invalid stripe:publishableKey for current environment", as expected for a test key — but the readiness answer flipped.)Evidence that the flag is the cause
Swapping the availability client — the same seam used by
FakeGooglePayRepositoryRulein your instrumentation tests — and re-sending the request withexistingPaymentMethodRequiredremoved:Result on the same device, same account, still
Environment.Testandpk_test:isReadyToPay→truePaymentSheetSo nothing about the account, the device, the cards or the Stripe account is at fault; the single differing input is that one flag.
Why this matters beyond dev convenience
Google requires screenshots of a working integration in the Test environment to grant production access. With
PaymentSheetunable to render the button in Test, and Production refusing test keys, an integration can end up unable to produce the screenshots needed to be allowed into Production. #9548 raised exactly this loop.Requests
PaymentSheet.GooglePayConfigurationsetexistingPaymentMethodRequired, or send it asfalsewhenenvironment == Test(per your own guidance in [BUG] [Google Pay] Google pay no show in test environment #7230). Test-environment readiness has no bearing on whether a real user can pay.DefaultGooglePayRepository.isReadyAsync()funnels every failure throughrunCatching { … }.getOrDefault(false)and logs the reason withLogger.getInstance(BuildConfig.DEBUG), which is off in the released AAR — so integrators only ever see the generic two-reasonUserFacingLoggermessage, neither reason being the actual cause. RoutingGOOGLE_PAY_IS_READY_API_CALL/GOOGLE_PAY_JSON_REQUEST_PARSINGthroughUserFacingLoggerwould turn a multi-day investigation into one log line.Related
PaymentSheet does not work with GooglePay environment = Test(closed via a different Google account)existingPaymentMethodRequired = falsein Test