flutter-stripe / flutter_stripe

Flutter SDK for Stripe.
https://pub.dev/packages/flutter_stripe
930 stars 514 forks source link

[BLOCKER] App crashes on all Android phones (including an emulator) when payment sheet is displayed in Release build #1909

Open lokus1980 opened 1 week ago

lokus1980 commented 1 week ago

Hello,

As the title suggests, this Stripe library does not work on any of my Android phones (for example, the Pixel 6 with Android 14).

Detailed log from the crash in Release build: crash.log

I have tested on multiple phones with Android 10 and Android 14. It always works in Debug mode but crashes instantly in Release mode. Please help.

Flutter: 3.24.1 (latest version)
flutter_stripe: 11.0.0 (latest version)

Also, I have done every single installation step as described here: https://pub.dev/packages/flutter_stripe

That's the piece of code that shows the payment sheet:

payment sheet

Video from Debug build (works): https://github.com/user-attachments/assets/ef3eba99-6180-4f5a-8a09-0933f76e5641

Video from Release build (crashes): https://github.com/user-attachments/assets/bc5daedd-4ef3-4fcf-9116-17815776cddc

This blocks me from releasing the app to production as the payment feature is the core functionality here. The only thing I need for my MVP is to allow customers to pay by card. Nothing else is required at this stage and even this scenario does not work. And I don't want to publish a Debug version to production...

Please help. I have invested lots of time integrating Stripe with my backend but it's not usable end to end as the mobile app (currently my only API client) is not working at all. Thank you.

remonh87 commented 1 week ago

so deadobject exception means the paymentsheetactivity got killed by the android OS. Can it be that you do not have applied all the steps for android as described here?

I am using paymentsheet as well and do not have this issue

lokus1980 commented 1 week ago

Yes @remonh87, I have done all the steps like in the instruction and getting:

09-04 06:41:30.289   719   885 D EGL_emulation: app_time_stats: avg=20.57ms min=9.28ms max=216.36ms count=49
09-04 06:41:30.307   374   448 W VsyncModulator: setTransactionSchedule: Unexpected EarlyEnd
09-04 06:41:30.412   511   531 W ActivityTaskManager: Activity top resumed state loss timeout for ActivityRecord{9568b9 u0 com.gameos.goxp.dev/com.stripe.android.paymentsheet.PaymentSheetActivity t54 f} isExiting}
09-04 06:41:30.469  1155  1200 W .gms.persistent: Couldn't lock the profile file /data/misc/profiles/cur/0/com.google.android.gms/primary.prof: Failed to lock file '/data/misc/profiles/cur/0/com.google.android.gms/primary.prof': Try again
09-04 06:41:30.479  1155  1200 W .gms.persistent: Could not forcefully load profile /data/misc/profiles/cur/0/com.google.android.gms/primary.prof
09-04 06:41:30.624   719   820 V WindowManagerShell: Transition animation finished (aborted=false), notifying core (#25)android.os.BinderProxy@5b8c221@0
09-04 06:41:30.625   511   528 V WindowManager: Finish Transition #25: created at 09-04 06:41:29.910 collect-started=0.016ms request-sent=0.033ms started=5.287ms ready=59.43ms sent=93.22ms finished=714.556ms
09-04 06:41:30.625   511   525 W WindowManager: Exception thrown during dispatchAppVisibility Window{19ad775 u0 com.gameos.goxp.dev/com.stripe.android.paymentsheet.PaymentSheetActivity EXITING}
09-04 06:41:30.625   511   525 W WindowManager: android.os.DeadObjectException
09-04 06:41:30.625   511   525 W WindowManager:     at android.os.BinderProxy.transactNative(Native Method)
09-04 06:41:30.625   511   525 W WindowManager:     at android.os.BinderProxy.transact(BinderProxy.java:584)
09-04 06:41:30.625   511   525 W WindowManager:     at android.view.IWindow$Stub$Proxy.dispatchAppVisibility(IWindow.java:546)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.WindowState.sendAppVisibilityToClients(WindowState.java:3271)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.WindowContainer.sendAppVisibilityToClients(WindowContainer.java:1221)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.WindowToken.setClientVisible(WindowToken.java:409)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.setClientVisible(ActivityRecord.java:6946)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.postApplyAnimation(ActivityRecord.java:5637)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5580)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.Transition.finishTransition(Transition.java:1151)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.TransitionController.finishTransition(TransitionController.java:868)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.WindowOrganizerController.finishTransition(WindowOrganizerController.java:396)
09-04 06:41:30.625   511   525 W WindowManager:     at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:286)
09-04 06:41:30.625   511   525 W WindowManager:     at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:181)
09-04 06:41:30.625   511   525 W WindowManager:     at android.os.Binder.execTransactInternal(Binder.java:1339)
09-04 06:41:30.625   511   525 W WindowManager:     at android.os.Binder.execTransact(Binder.java:1275)
09-04 06:41:30.627   511   525 I Process : Sending signal. PID: 6297 SIG: 9
09-04 06:41:30.627   511   525 W WindowManager: Exception thrown during dispatchAppVisibility Window{717fed8 u0 com.gameos.goxp.dev/com.gameos.goxp.dev.MainActivity EXITING}
09-04 06:41:30.627   511   525 W WindowManager: android.os.DeadObjectException
09-04 06:41:30.627   511   525 W WindowManager:     at android.os.BinderProxy.transactNative(Native Method)
09-04 06:41:30.627   511   525 W WindowManager:     at android.os.BinderProxy.transact(BinderProxy.java:584)
09-04 06:41:30.627   511   525 W WindowManager:     at android.view.IWindow$Stub$Proxy.dispatchAppVisibility(IWindow.java:546)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.WindowState.sendAppVisibilityToClients(WindowState.java:3271)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.WindowContainer.sendAppVisibilityToClients(WindowContainer.java:1221)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.WindowToken.setClientVisible(WindowToken.java:409)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.setClientVisible(ActivityRecord.java:6946)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.postApplyAnimation(ActivityRecord.java:5637)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5580)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.Transition.finishTransition(Transition.java:1151)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.TransitionController.finishTransition(TransitionController.java:868)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.WindowOrganizerController.finishTransition(WindowOrganizerController.java:396)
09-04 06:41:30.627   511   525 W WindowManager:     at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:286)
09-04 06:41:30.627   511   525 W WindowManager:     at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:181)
09-04 06:41:30.627   511   525 W WindowManager:     at android.os.Binder.execTransactInternal(Binder.java:1339)
09-04 06:41:30.627   511   525 W WindowManager:     at android.os.Binder.execTransact(Binder.java:1275)
09-04 06:41:30.627   511   525 I Process : Sending signal. PID: 6297 SIG: 9
09-04 06:41:30.631   511   531 W ActivityManager: setHasOverlayUi called on unknown pid: 6297
09-04 06:41:30.633   719   820 V WindowManagerShell: Track 0 became idle
09-04 06:41:30.634   719   820 V WindowManagerShell: All active transition animations finished
09-04 06:41:30.654   374   374 E BpTransactionCompletedListener: Failed to transact (-32)
09-04 06:41:30.654   374   374 E BpTransactionCompletedListener: Failed to transact (-32)
09-04 06:41:30.654   374   374 E BpTransactionCompletedListener: Failed to transact (-32)
09-04 06:41:31.290   719   885 D EGL_emulation: app_time_stats: avg=17.25ms min=8.51ms max=32.39ms count=58

Now, please look at my configuration and see if you can spot anything:

Flutter: 3.24.1 (latest stable version)
flutter_stripe: 11.0.0 (latest version)

Flutter Doctor report:
[✓] Flutter (Channel stable, 3.24.1, on macOS 14.6.1 23G93 darwin-arm64, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] VS Code (version 1.92.2)
[✓] Connected device (4 available)
[✓] Network resources

Pubspec.yaml:

name: goxp
description: GoXP app
publish_to: 'none'
version: 0.2.0+154

environment:
  sdk: '>=3.5.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  amplify_api: ^2.3.0
  amplify_auth_cognito: ^2.3.0
  amplify_authenticator: ^2.1.1
  amplify_flutter: ^2.3.0
  badges: ^3.1.1
  collection: ^1.18.0
  cupertino_icons: ^1.0.2
  equatable: ^2.0.5
  flutter_native_splash: ^2.3.1
  flutter_rating_bar: ^4.0.1
  flutter_redux: ^0.10.0
  flutter_stripe: ^11.0.0
  form_builder_validators: ^11.0.0
  go_router: ^14.2.0
  http_parser: ^4.0.2
  http: ^1.1.0
  image_picker: ^1.0.4
  mocktail: ^1.0.3
  redux: ^5.0.0
  settings_ui: ^2.0.2
  url_launcher: ^6.3.0
  uuid: ^4.3.3

dev_dependencies:
  integration_test:
    sdk: flutter
  flutter_test:
    sdk: flutter

  flutter_launcher_icons: ^0.13.1
  flutter_lints: ^4.0.0
  change_app_package_name: ^1.2.0

flutter:
  uses-material-design: true

  assets:
    - assets/images/
    - assets/images/initialisation/
    - assets/icons/

  fonts:
    - family: Poppins
      fonts:
        - asset: assets/fonts/poppins/Poppins-Thin.ttf
          weight: 100
        - asset: assets/fonts/poppins/Poppins-ThinItalic.ttf
          weight: 100
          style: italic
        - asset: assets/fonts/poppins/Poppins-ExtraLight.ttf
          weight: 200
        - asset: assets/fonts/poppins/Poppins-ExtraLightItalic.ttf
          weight: 200
          style: italic
        - asset: assets/fonts/poppins/Poppins-Light.ttf
          weight: 300
        - asset: assets/fonts/poppins/Poppins-LightItalic.ttf
          weight: 300
          style: italic
        - asset: assets/fonts/poppins/Poppins-Regular.ttf
        - asset: assets/fonts/poppins/Poppins-Italic.ttf
          style: italic
        - asset: assets/fonts/poppins/Poppins-Medium.ttf
          weight: 500
        - asset: assets/fonts/poppins/Poppins-MediumItalic.ttf
          weight: 500
          style: italic
        - asset: assets/fonts/poppins/Poppins-SemiBold.ttf
          weight: 600
        - asset: assets/fonts/poppins/Poppins-SemiBoldItalic.ttf
          weight: 600
          style: italic
        - asset: assets/fonts/poppins/Poppins-Bold.ttf
          weight: 700
        - asset: assets/fonts/poppins/Poppins-BoldItalic.ttf
          weight: 700
          style: italic
        - asset: assets/fonts/poppins/Poppins-ExtraBold.ttf
          weight: 800
        - asset: assets/fonts/poppins/Poppins-ExtraBoldItalic.ttf
          weight: 800
          style: italic
        - asset: assets/fonts/poppins/Poppins-Black.ttf
          weight: 800
        - asset: assets/fonts/poppins/Poppins-BlackItalic.ttf
          weight: 800
          style: italic

flutter_launcher_icons:
  image_path: "assets/icons/app_icon.png"
  android: true
  ios: true
  adaptive_icon_background: "assets/icons/background.png"
  adaptive_icon_foreground: "assets/icons/foreground.png"

flutter_native_splash:
  color: "#0D0160"
  color_dark: "#0D0160"
  image_ios: assets/images/splash/splash.png
  ios_content_mode: scaleAspectFill
  android_12:
    image: android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  image_android: assets/images/splash/splash.png
  android_gravity: center

main.dart:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  Stripe.publishableKey =
      "pk_test_*********";
  Stripe.merchantIdentifier = 'merchant.flutter.stripe.test';
  Stripe.urlScheme = 'goxpdev';
  await Stripe.instance.applySettings();
  ...
  runApp(...);
}

styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Show a splash screen on the activity. Automatically removed when
             Flutter draws its first frame -->
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
    <!-- Theme applied to the Android Window as soon as the process has started.
         This theme determines the color of the Android Window while your
         Flutter UI initializes, as well as behind your Flutter UI while its
         running.
         This Theme is only used starting with V2 of Flutter's Android embedding. -->
    <style name="NormalTheme" parent="Theme.MaterialComponents">
        <item name="android:windowBackground">?android:colorBackground</item>
    </style>
</resources>

styles.xml (values-night):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
    <!-- TODO document the necessary change -->
    <style name="LaunchTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- Show a splash screen on the activity. Automatically removed when
             Flutter draws its first frame -->
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
    <!-- Theme applied to the Android Window as soon as the process has started.
         This theme determines the color of the Android Window while your
         Flutter UI initializes, as well as behind your Flutter UI while its
         running.

         This Theme is only used starting with V2 of Flutter's Android embedding. -->
    <style name="NormalTheme" parent="Theme.MaterialComponents">
        <item name="android:windowBackground">?android:colorBackground</item>
    </style>
</resources>

android/build.gradle:

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

android/app/build.gradle:

plugins {
    id "com.android.application"
    id "kotlin-android"
    id "dev.flutter.flutter-gradle-plugin"
    id "com.google.gms.google-services"
    id "com.google.firebase.crashlytics"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

android {
    namespace "com.gameos.goxp.dev"
    compileSdk 34

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.gameos.goxp.dev"
        // You can update the following values to match your application needs.
        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
        minSdkVersion 24
        targetSdkVersion 33
        // targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation 'com.google.firebase:firebase-iid:21.1.0'
    implementation 'com.google.android.gms:play-services-base:18.1.0'
}

proguard-rules.pro:

-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivity$g
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider

gradle-wraper.properties:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

MainActivity.kt:

package com.gameos.goxp.dev

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterFragmentActivity() {
}

and the code that is presenting the payment sheet:

  Future<void> _bookCurrentExperience(Store<AppState> store, BookCurrentExperience action, NextDispatcher next) async {
    store.dispatch(const ShowLoader());
    try {
      final experienceId = store.state.experienceState.currentExperience!.id;
      final priceOptionId = action.priceOptionId;
      final experienceModifiedAt = store.state.experienceState.currentExperience!.modifiedAt;
      // 1. create payment intent on the server
      final paymentIntent = await _createPaymentIntent(experienceId, priceOptionId, experienceModifiedAt);
      // 2. set publishable key
      // Stripe.publishableKey = paymentIntent.publishableKey;
      // 3. initialize the payment sheet
      await Stripe.instance.initPaymentSheet(
        paymentSheetParameters: SetupPaymentSheetParameters(
          customFlow: false,
          merchantDisplayName: 'GoXP',
          paymentIntentClientSecret: paymentIntent.clientSecret,
          customerEphemeralKeySecret: paymentIntent.ephemeralKey,
          customerId: paymentIntent.stripeCustomerId,
        ),
      );
      // 4. present payment sheet
      await Stripe.instance.presentPaymentSheet();
      safePrint("Payment completed!!!");
      // TODO: navigate to "Thank for booking your experience. Check your inbox for a confirmation email"
      next(action);
    } catch (e) {
      // TODO: show a popup with an error message
      safePrint(e);
    } finally {
      store.dispatch(const HideLoader());
    }
  }

I am running out of ideas. I tried lots of things like fiddling with customFlow, targetSdkVersion, flutter-stripe version and still getting the android.os.DeadObjectException. Also, I disabled my loader animation thinking that maybe it would come in the way but it also didn't help. My app is very simple, just a few screens for now and no crazy stuff except for a few calls to our REST API.

Once again, the Debug build works, but the Release/Prod build fails, as shown in the log at the top.

Please help.

ibrahimMobileArts commented 1 week ago

@lokus1980 can u please provide an image for settings.gradle file, and there are 3 things to try android/build.gradle:

lokus1980 commented 6 days ago

Hi @ibrahimMobileArts, I have applied your suggested changes and the app is still crashing.

Here's the content of my settings.gradle:

pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "8.2.2" apply false
    id "org.jetbrains.kotlin.android" version "1.9.0" apply false
    id "com.google.gms.google-services" version "4.4.0" apply false
    id "com.google.firebase.crashlytics" version "2.9.9" apply false
}

include ":app"

I think there must be some weird bug in this library as, like I said, the app works in a Debug build (so all settings, libs and things are like they should) but in a Release build it crashes when I try to shoe the Payment Sheet. I don't know what else I can do to make it work in Release build. I'll try to run the demo app included in this library whether it works in Release build as if it suffers from the same problem, you would have a case that is easy to reproduce on your end.

Also, what did you mean exactly by "first you should know that there is an updated syntax for this whole file"? Can you please send an example of the correct syntax so I can try it?

lokus1980 commented 6 days ago

OK, the demo app (that is included in this library) crashes at the same point as my app.

I just launched the server and then the app, went to the payment sheet screen and it crashes with my test Stripe keys:

Here's the video of the crash: https://github.com/user-attachments/assets/5b6d5453-94c3-4d9e-85ed-05dcfe1303fa

So the problem seems to be in the library, not in my app.

Please launch the demo app in a Release mode and you will see the crash on your end too :)

Just try flutter run --release.

ibrahimMobileArts commented 6 days ago

Hi @ibrahimMobileArts, I have applied your suggested changes and the app is still crashing.

Here's the content of my settings.gradle:

pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "8.2.2" apply false
    id "org.jetbrains.kotlin.android" version "1.9.0" apply false
    id "com.google.gms.google-services" version "4.4.0" apply false
    id "com.google.firebase.crashlytics" version "2.9.9" apply false
}

include ":app"

I think there must be some weird bug in this library as, like I said, the app works in a Debug build (so all settings, libs and things are like they should) but in a Release build it crashes when I try to shoe the Payment Sheet. I don't know what else I can do to make it work in Release build. I'll try to run the demo app included in this library whether it works in Release build as if it suffers from the same problem, you would have a case that is easy to reproduce on your end.

Also, what did you mean exactly by "first you should know that there is an updated syntax for this whole file"? Can you please send an example of the correct syntax so I can try it?

this is an example, even though i don't think its the problem anymore: plugins { id "com.android.application" id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" id 'com.google.gms.google-services' id "com.google.firebase.crashlytics" }

def localProperties = new Properties() def localPropertiesFile = rootProject.file("local.properties") if (localPropertiesFile.exists()) { localPropertiesFile.withReader("UTF-8") { reader -> localProperties.load(reader) } }

def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { flutterVersionCode = "1" }

def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { flutterVersionName = "1.0" }

android { namespace = "app.app.app" compileSdk = 34 ndkVersion = flutter.ndkVersion

compileOptions {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

defaultConfig {
    // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
    applicationId = "app.app.app"
    // You can update the following values to match your application needs.
    // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
    minSdk = 23
    targetSdk = 34
    versionCode = flutterVersionCode.toInteger()
    versionName = flutterVersionName
}

buildTypes {
    release {
        // TODO: Add your own signing config for the release build.
        // Signing with the debug keys for now, so `flutter run --release` works.
        signingConfig = signingConfigs.debug
    }
}

}

flutter { source = "../.." }

dependencies { // Import the Firebase BoM implementation platform('com.google.firebase:firebase-bom:33.1.1') implementation 'com.google.firebase:firebase-analytics' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.stripe:stripe-android:20.37.2' implementation 'com.google.android.gms:play-services-wallet:19.3.0'

// Add the dependencies for any other desired Firebase products // https://firebase.google.com/docs/android/setup#available-libraries }

lokus1980 commented 6 days ago

Hi @ibrahimMobileArts and @remonh87.

As in my previous message, the demo app included in this library crashes the same way as my app in Release mode. Video: https://github.com/user-attachments/assets/5b6d5453-94c3-4d9e-85ed-05dcfe1303fa Below is the log from the crash.

I have tested it both with Stripe test and live API keys. That's a serious bug I think. It crashes the same way on emulators and real devices (like a stock Google Pixel 6 with Android 14). This makes this Flutter library unusable in production.

Can you please run the demo app in Release mode (flutter run --release or deploy the apk build by flutter build apk) to reproduce the error on your end and see if you can fix it please?

09-10 05:06:34.893   722   866 D EGL_emulation: app_time_stats: avg=6526.96ms min=14.81ms max=103900.69ms count=16
09-10 05:06:35.028   509   529 W ActivityTaskManager: Activity top resumed state loss timeout for ActivityRecord{2f79811 u0 com.flutter.stripe.example/com.stripe.android.customersheet.CustomerSheetActivity t65 f} isExiting}
09-10 05:06:35.110   722   793 V WindowManagerShell: Transition animation finished (aborted=false), notifying core (#10)android.os.BinderProxy@8f21c5d@0
09-10 05:06:35.111   509   526 V WindowManager: Finish Transition #10: created at 09-10 05:06:34.449 collect-started=0.032ms request-sent=4.088ms started=5.79ms ready=176.244ms sent=269.208ms finished=661.281ms
09-10 05:06:35.113   509  1885 W WindowManager: Exception thrown during dispatchAppVisibility Window{433c4f u0 com.flutter.stripe.example/com.flutter.stripe.example.MainActivity EXITING}
09-10 05:06:35.113   509  1885 W WindowManager: android.os.DeadObjectException
09-10 05:06:35.113   509  1885 W WindowManager:     at android.os.BinderProxy.transactNative(Native Method)
09-10 05:06:35.113   509  1885 W WindowManager:     at android.os.BinderProxy.transact(BinderProxy.java:584)
09-10 05:06:35.113   509  1885 W WindowManager:     at android.view.IWindow$Stub$Proxy.dispatchAppVisibility(IWindow.java:546)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.WindowState.sendAppVisibilityToClients(WindowState.java:3271)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.WindowContainer.sendAppVisibilityToClients(WindowContainer.java:1221)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.WindowToken.setClientVisible(WindowToken.java:409)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.ActivityRecord.setClientVisible(ActivityRecord.java:6946)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.ActivityRecord.postApplyAnimation(ActivityRecord.java:5637)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5580)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.Transition.finishTransition(Transition.java:1151)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.TransitionController.finishTransition(TransitionController.java:868)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.WindowOrganizerController.finishTransition(WindowOrganizerController.java:396)
09-10 05:06:35.113   509  1885 W WindowManager:     at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:286)
09-10 05:06:35.113   509  1885 W WindowManager:     at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:181)
09-10 05:06:35.113   509  1885 W WindowManager:     at android.os.Binder.execTransactInternal(Binder.java:1344)
09-10 05:06:35.113   509  1885 W WindowManager:     at android.os.Binder.execTransact(Binder.java:1275)
09-10 05:06:35.115   509  1885 I Process : Sending signal. PID: 12454 SIG: 9
09-10 05:06:35.118   722   793 V WindowManagerShell: Track 0 became idle
09-10 05:06:35.118   722   793 V WindowManagerShell: All active transition animations finished
09-10 05:06:35.120   509   891 D ActivityManager: sync unfroze 10020 com.google.android.gms for 6

And that's my flutter doctor report again if that helps:

Flutter Doctor report:
[✓] Flutter (Channel stable, 3.24.1, on macOS 14.6.1 23G93 darwin-arm64, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] VS Code (version 1.92.2)
[✓] Connected device (4 available)
[✓] Network resources

Also, my Java (as maybe here there's something wrong?):

openjdk 22.0.1 2024-04-16
OpenJDK Runtime Environment Homebrew (build 22.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 22.0.1, mixed mode, sharing)
ibrahimMobileArts commented 5 days ago

@lokus1980 hello, sorry am not sure about your problem exactly, however please try few things i foundx while comparing to my working code:

lokus1980 commented 5 days ago

Hi @ibrahimMobileArts, before I try your suggestions, can you please check a few things for me?

The video you saw in my previous message is not from my app but the demo app included in this library. It's crashing on all my Android phones too. Please download it here: https://github.com/flutter-stripe/flutter_stripe/tree/main/example

  1. Can you please run your app in release mode and see if it's not crashing when making a payment? (flutter run --release)? Are you using Payment Sheet in your app? This one is crashing on the demo app.
  2. Can you please run the demo app (included in the flutter_stripe library) and run it in release mode (flutter run --release) and select Customer Sheet and then "Init customer sheet" and "Select payment method now"? Screenshot 2024-09-10 at 6 43 32 PM Screenshot 2024-09-10 at 6 44 39 PM
ibrahimMobileArts commented 5 days ago

@lokus1980 i just finished running my app using flutter run --release and i made a payment and everything works fine, did you try the library's demo app on android 12 or below?

lokus1980 commented 5 days ago

Thank you @ibrahimMobileArts for checking this!

Are you making payments in your app via Payment Sheet (https://docs.page/flutter-stripe/flutter_stripe/sheet)?

Can you please share what Flutter and Java version you have on your machine?

Are you running everything on Mac or Windows?

ibrahimMobileArts commented 5 days ago

Flutter 3.24.1 / Dart 3.5.1 java version "1.8.0_421" running on Mac

lokus1980 commented 5 days ago

Thank you, I'll try your Java version and see if that helps. The rest is the same as on my machine.

lokus1980 commented 5 days ago

I tried some older versions of Java, and also a phone with Android 12. Tried different versions of Gradle (8.2 and 8.7).

It is still crashing when showing a Payment Sheet.

I am running out of ideas 😬

Is there an alternative method of making a payment by card in this library?

remonh87 commented 5 days ago

I can reproduce it on the example app. Will spend some time tonight to see if I can fix something. Can you try an older version of Flutter Stripe.

The interesting thing is that I cannot reproduce it in my other production app so it has to be some config somewhere

CC: @jonasbark

remonh87 commented 5 days ago

@lokus1980 so it looks like some gradle / android dependency issue. I didn't came further in our repo but I was able to run release with a paymentsheet with a fresh flutter project. Feel free to have a look and compare: https://github.com/remonh87/test_app_stripe . I will look a bit further later this week to triage it further but it is a needle in a haystack

lokus1980 commented 5 days ago

Thanks @remonh87 so much for being able to reproduce the issue on your end. It's a relief that it's not only happening on my machine/phones only. I'll try to compare the demo app with your one (that works in the release build) to understand what is causing this issue. If we find it, let's fix the demo app for others 😉

lokus1980 commented 5 days ago

Hi @remonh87 - great success! By comparing your app with the demo one, I have found the issue. It all comes down to this change to make the app work in release mode.

Screenshot 2024-09-11 at 12 13 34 PM

So it was com.android.application not working with the flutter_stripe library and I had to downgrade this plugin's version to 7.3.0. My app works as intended. Thanks a lot for your time and effort to help save the day!

jonasbark commented 5 days ago

Thanks for investigating @remonh87 @lokus1980 ! I'll dig deeper the next few days as that required change is a bit concerning

jonasbark commented 4 days ago

I did get another crash when running the latest example app in release mode:

E/AndroidRuntime(30058): FATAL EXCEPTION: main
E/AndroidRuntime(30058): Process: com.flutter.stripe.example, PID: 30058
E/AndroidRuntime(30058): L.l: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (pending composition has not been applied). Please report to Google or use https://goo.gle/compose-feedback
E/AndroidRuntime(30058):    at L.o.v(SourceFile:30)
E/AndroidRuntime(30058):    at L.s.A(SourceFile:82)
...

and using the latest stripe-android 20.49.0 version:

E/AndroidRuntime(30663): java.lang.IncompatibleClassChangeError: Class 'android.content.res.XmlBlock$Parser' does not implement interface 'N8.a' in call to 'int N8.a.next()' (declaration of 'g0.a' appears in /data/app/~~jM-88922nRTEcjnOKtLMqg==/com.flutter.stripe.example-9S2AjNxzCruXSVtE3OOZag==/base.apk)
E/AndroidRuntime(30663):    at g0.a.a(SourceFile:6)
E/AndroidRuntime(30663):    at t0.f.c(SourceFile:46)

Downgrading com.android.application is indeed the only fix I found.

lokus1980 commented 4 days ago

Yes, that is a bit concerning @jonasbark but because a freshly generated Flutter app with the latest Flutter version uses com.android.application in version 7.3.0, I'm sure the Flutter team is aware of some issues related to version 8.x.x.

So it does not necessarily mean that flutter_stripe has some bug but it's a general Flutter issue that is not really compatible with com.android.application v8+. I would stick to version 7.3.0 and move on as that's the default version that Flutter is supporting right now by looking into a freshly generated app. Once they release a Flutter version supporting com.android.application v8+, we can try it with flutter_stripe again. For now I would not worry too much about it.

The only things I would do for now are to:

lokus1980 commented 4 days ago

@jonasbark - I have created a branch with the fixes mentioned above but I don't have permissions to push that branch and create a pull request. Can you please help?