flutter_stripe
flutter_stripe copied to clipboard
Custom payment sheet appearance on android doesn't work (iOS ok)
Describe the bug
We are using the built-in PaymentSheetAppearance
class to style the sheet when presenting it to users. On iOS this works fine and is styled correctly, but on Android we receive platform errors where the parameters such as border radius can't be parsed because the incorrect data types are being sent over the platform channel.
It appears that borderRadius and borderWidth are the main offenders here. The shadows and other colors appear to be having problems as well though
To Reproduce
- Create a payment sheet with custom styling
- See errors in the console as well as the styling failing to be applied
Expected behavior The styling should be applied properly via the styling configuration object
Smartphone / tablet
- Device: Pixel 4A
- OS: Android 12
- Package version: 4.0.0
- Flutter version 3.0.5
Additional context Our styling object:
PaymentSheetAppearance(
colors: PaymentSheetAppearanceColors(
background: theme.neutral.shade0,
primary: theme.primary,
componentBorder: theme.neutral.shade200,
componentDivider: theme.neutral.shade300,
componentText: theme.neutral.shade800,
primaryText: theme.neutral.shade900,
error: theme.red,
icon: theme.neutral.shade600,
),
shapes: PaymentSheetShape(
borderWidth: 1.0,
borderRadius: 11.0,
shadow: PaymentSheetShadowParams(
offset: const PaymentSheetShadowOffset(
x: 0.0,
y: -2.0,
),
opacity: 0.1,
color: theme.neutral.shade900,
),
),
primaryButton: PaymentSheetPrimaryButtonAppearance(
shapes: PaymentSheetPrimaryButtonShape(
blurRadius: 4.0,
shadow: PaymentSheetShadowParams(
opacity: 0.1,
color: theme.neutral.shade900,
),
),
colors: PaymentSheetPrimaryButtonTheme(
light: PaymentSheetPrimaryButtonThemeColors(
background: theme.blue,
text: Colors.white,
),
dark: PaymentSheetPrimaryButtonThemeColors(
background: theme.blue,
text: Colors.white,
),
),
),
);
Stack Traces
W/Bundle (20050): Key borderRadius expected Integer but value was a java.lang.Double. The default value 0 was returned.
W/Bundle (20050): Attempt to cast generated internal exception:
W/Bundle (20050): java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
W/Bundle (20050): at android.os.BaseBundle.getInt(BaseBundle.java:1077)
W/Bundle (20050): at android.os.BaseBundle.getInt(BaseBundle.java:1059)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.getFloatOr(PaymentSheetAppearance.kt:108)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildShapes(PaymentSheetAppearance.kt:62)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildPaymentSheetAppearance(PaymentSheetAppearance.kt:17)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetFragment.onViewCreated(PaymentSheetFragment.kt:67)
W/Bundle (20050): at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
W/Bundle (20050): at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:488)
W/Bundle (20050): at android.os.Handler.handleCallback(Handler.java:938)
W/Bundle (20050): at android.os.Handler.dispatchMessage(Handler.java:99)
W/Bundle (20050): at android.os.Looper.loopOnce(Looper.java:201)
W/Bundle (20050): at android.os.Looper.loop(Looper.java:288)
W/Bundle (20050): at android.app.ActivityThread.main(ActivityThread.java:7870)
W/Bundle (20050): at java.lang.reflect.Method.invoke(Native Method)
W/Bundle (20050): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/Bundle (20050): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
W/Bundle (20050): Key borderRadius expected Float but value was a java.lang.Double. The default value 0.0 was returned.
W/Bundle (20050): Attempt to cast generated internal exception:
W/Bundle (20050): java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float
W/Bundle (20050): at android.os.BaseBundle.getFloat(BaseBundle.java:1145)
W/Bundle (20050): at android.os.Bundle.getFloat(Bundle.java:892)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.getFloatOr(PaymentSheetAppearance.kt:108)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildShapes(PaymentSheetAppearance.kt:62)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildPaymentSheetAppearance(PaymentSheetAppearance.kt:17)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetFragment.onViewCreated(PaymentSheetFragment.kt:67)
W/Bundle (20050): at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
W/Bundle (20050): at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:488)
W/Bundle (20050): at android.os.Handler.handleCallback(Handler.java:938)
W/Bundle (20050): at android.os.Handler.dispatchMessage(Handler.java:99)
W/Bundle (20050): at android.os.Looper.loopOnce(Looper.java:201)
W/Bundle (20050): at android.os.Looper.loop(Looper.java:288)
W/Bundle (20050): at android.app.ActivityThread.main(ActivityThread.java:7870)
W/Bundle (20050): at java.lang.reflect.Method.invoke(Native Method)
W/Bundle (20050): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/Bundle (20050): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
W/Bundle (20050): Key borderWidth expected Integer but value was a java.lang.Double. The default value 0 was returned.
W/Bundle (20050): Attempt to cast generated internal exception:
W/Bundle (20050): java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
W/Bundle (20050): at android.os.BaseBundle.getInt(BaseBundle.java:1077)
W/Bundle (20050): at android.os.BaseBundle.getInt(BaseBundle.java:1059)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.getFloatOr(PaymentSheetAppearance.kt:108)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildShapes(PaymentSheetAppearance.kt:63)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildPaymentSheetAppearance(PaymentSheetAppearance.kt:17)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetFragment.onViewCreated(PaymentSheetFragment.kt:67)
W/Bundle (20050): at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
W/Bundle (20050): at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:488)
W/Bundle (20050): at android.os.Handler.handleCallback(Handler.java:938)
W/Bundle (20050): at android.os.Handler.dispatchMessage(Handler.java:99)
W/Bundle (20050): at android.os.Looper.loopOnce(Looper.java:201)
W/Bundle (20050): at android.os.Looper.loop(Looper.java:288)
W/Bundle (20050): at android.app.ActivityThread.main(ActivityThread.java:7870)
W/Bundle (20050): at java.lang.reflect.Method.invoke(Native Method)
W/Bundle (20050): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/Bundle (20050): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
W/Bundle (20050): Key borderWidth expected Float but value was a java.lang.Double. The default value 0.0 was returned.
W/Bundle (20050): Attempt to cast generated internal exception:
W/Bundle (20050): java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float
W/Bundle (20050): at android.os.BaseBundle.getFloat(BaseBundle.java:1145)
W/Bundle (20050): at android.os.Bundle.getFloat(Bundle.java:892)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.getFloatOr(PaymentSheetAppearance.kt:108)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildShapes(PaymentSheetAppearance.kt:63)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetAppearanceKt.buildPaymentSheetAppearance(PaymentSheetAppearance.kt:17)
W/Bundle (20050): at com.reactnativestripesdk.PaymentSheetFragment.onViewCreated(PaymentSheetFragment.kt:67)
W/Bundle (20050): at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3019)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
W/Bundle (20050): at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
W/Bundle (20050): at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
W/Bundle (20050): at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:488)
W/Bundle (20050): at android.os.Handler.handleCallback(Handler.java:938)
W/Bundle (20050): at android.os.Handler.dispatchMessage(Handler.java:99)
W/Bundle (20050): at android.os.Looper.loopOnce(Looper.java:201)
W/Bundle (20050): at android.os.Looper.loop(Looper.java:288)
W/Bundle (20050): at android.app.ActivityThread.main(ActivityThread.java:7870)
W/Bundle (20050): at java.lang.reflect.Method.invoke(Native Method)
W/Bundle (20050): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/Bundle (20050): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Screenshot showing failed styling application:
Thanks - it will be fixed in the next version. Please note that the warnings will still appear but the styling will work.