@stripe/stripe-react-native 0.55.1 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/android/gradle.properties +1 -1
  2. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormView.kt +4 -3
  3. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +7 -6
  4. package/android/src/main/java/com/reactnativestripesdk/CardFormView.kt +11 -11
  5. package/android/src/main/java/com/reactnativestripesdk/{CollectBankAccountLauncherFragment.kt → CollectBankAccountLauncherManager.kt} +21 -44
  6. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +17 -24
  7. package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
  8. package/android/src/main/java/com/reactnativestripesdk/{FinancialConnectionsSheetFragment.kt → FinancialConnectionsSheetManager.kt} +30 -77
  9. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +107 -0
  10. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherManager.kt +37 -0
  11. package/android/src/main/java/com/reactnativestripesdk/{PaymentLauncherFragment.kt → PaymentLauncherManager.kt} +39 -77
  12. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +8 -20
  13. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +366 -483
  14. package/android/src/main/java/com/reactnativestripesdk/{PaymentSheetFragment.kt → PaymentSheetManager.kt} +79 -88
  15. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +3 -2
  16. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +213 -210
  17. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +78 -0
  18. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +48 -35
  19. package/android/src/main/java/com/reactnativestripesdk/customersheet/{CustomerSheetFragment.kt → CustomerSheetManager.kt} +127 -104
  20. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +35 -0
  21. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +47 -12
  22. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +87 -142
  23. package/android/src/main/java/com/reactnativestripesdk/utils/StripeUIManager.kt +62 -0
  24. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +12 -0
  25. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +4 -0
  26. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -64
  27. package/ios/AddressSheet/AddressSheetView.swift +1 -1
  28. package/ios/ApplePayButtonManager.m +1 -1
  29. package/ios/ApplePayButtonView.swift +2 -2
  30. package/ios/FinancialConnections.swift +2 -2
  31. package/ios/Mappers.swift +2 -4
  32. package/ios/NewArch/ApplePayButtonComponentView.mm +1 -1
  33. package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
  34. package/ios/OldArch/StripeSdkEventEmitterCompat.m +12 -0
  35. package/ios/PaymentMethodFactory.swift +0 -17
  36. package/ios/PushProvisioning/AddToWalletButtonView.swift +1 -1
  37. package/ios/StripeSdk.mm +14 -0
  38. package/ios/StripeSdkEmitter.swift +2 -0
  39. package/ios/StripeSdkImpl+CustomerSheet.swift +71 -20
  40. package/ios/StripeSdkImpl+PaymentSheet.swift +29 -13
  41. package/ios/StripeSdkImpl.swift +9 -7
  42. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  43. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  44. package/lib/commonjs/components/AddressSheet.js +1 -1
  45. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  46. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  47. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  48. package/lib/commonjs/components/CardField.js +1 -1
  49. package/lib/commonjs/components/CardField.js.map +1 -1
  50. package/lib/commonjs/components/CardForm.js +1 -1
  51. package/lib/commonjs/components/CardForm.js.map +1 -1
  52. package/lib/commonjs/components/CustomerSheet.js +1 -1
  53. package/lib/commonjs/components/CustomerSheet.js.map +1 -1
  54. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  55. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  56. package/lib/commonjs/components/StripeContainer.js +1 -1
  57. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  58. package/lib/commonjs/events.js.map +1 -1
  59. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  60. package/lib/commonjs/specs/NativeApplePayButton.js.map +1 -1
  61. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  62. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  63. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  64. package/lib/commonjs/types/PaymentIntent.js.map +1 -1
  65. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  66. package/lib/module/components/AddToWalletButton.js +1 -1
  67. package/lib/module/components/AddToWalletButton.js.map +1 -1
  68. package/lib/module/components/AddressSheet.js +1 -1
  69. package/lib/module/components/AddressSheet.js.map +1 -1
  70. package/lib/module/components/AuBECSDebitForm.js +1 -1
  71. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  72. package/lib/module/components/CardField.js +1 -1
  73. package/lib/module/components/CardField.js.map +1 -1
  74. package/lib/module/components/CardForm.js +1 -1
  75. package/lib/module/components/CardForm.js.map +1 -1
  76. package/lib/module/components/CustomerSheet.js +1 -1
  77. package/lib/module/components/CustomerSheet.js.map +1 -1
  78. package/lib/module/components/PlatformPayButton.js +1 -1
  79. package/lib/module/components/PlatformPayButton.js.map +1 -1
  80. package/lib/module/components/StripeContainer.js +1 -1
  81. package/lib/module/components/StripeContainer.js.map +1 -1
  82. package/lib/module/events.js.map +1 -1
  83. package/lib/module/specs/NativeApplePayButton.js +1 -1
  84. package/lib/module/specs/NativeApplePayButton.js.map +1 -1
  85. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  86. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  87. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  88. package/lib/module/types/PaymentIntent.js.map +1 -1
  89. package/lib/module/types/PaymentSheet.js.map +1 -1
  90. package/lib/typescript/src/components/CustomerSheet.d.ts +1 -1
  91. package/lib/typescript/src/components/CustomerSheet.d.ts.map +1 -1
  92. package/lib/typescript/src/events.d.ts +2 -0
  93. package/lib/typescript/src/events.d.ts.map +1 -1
  94. package/lib/typescript/src/specs/NativeApplePayButton.d.ts +1 -1
  95. package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -1
  96. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +3 -1
  97. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  98. package/lib/typescript/src/types/ConfirmationToken.d.ts +0 -3
  99. package/lib/typescript/src/types/ConfirmationToken.d.ts.map +1 -1
  100. package/lib/typescript/src/types/CustomerSheet.d.ts +70 -12
  101. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  102. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +2 -4
  103. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  104. package/lib/typescript/src/types/PaymentIntent.d.ts +1 -9
  105. package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
  106. package/lib/typescript/src/types/PaymentMethod.d.ts +2 -8
  107. package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
  108. package/lib/typescript/src/types/PaymentSheet.d.ts +1 -6
  109. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  110. package/package.json +1 -1
  111. package/src/components/CustomerSheet.tsx +65 -9
  112. package/src/components/PlatformPayButton.tsx +1 -1
  113. package/src/events.ts +2 -0
  114. package/src/specs/NativeApplePayButton.ts +1 -1
  115. package/src/specs/NativeStripeSdkModule.ts +7 -0
  116. package/src/types/ConfirmationToken.ts +0 -3
  117. package/src/types/CustomerSheet.ts +80 -12
  118. package/src/types/EmbeddedPaymentElement.tsx +2 -4
  119. package/src/types/PaymentIntent.ts +0 -10
  120. package/src/types/PaymentMethod.ts +0 -9
  121. package/src/types/PaymentSheet.ts +1 -6
  122. package/stripe-react-native.podspec +1 -1
  123. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherFragment.kt +0 -146
  124. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +0 -68
  125. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherFragment.kt +0 -102
  126. package/android/src/main/java/com/reactnativestripesdk/utils/StripeFragment.kt +0 -52
@@ -4,486 +4,447 @@ import android.annotation.SuppressLint
4
4
  import android.content.Context
5
5
  import android.content.res.Configuration
6
6
  import android.graphics.Color
7
- import android.os.Bundle
7
+ import com.facebook.react.bridge.Arguments
8
+ import com.facebook.react.bridge.ReadableMap
9
+ import com.facebook.react.bridge.ReadableType
8
10
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
11
+ import com.reactnativestripesdk.utils.getBooleanOrNull
12
+ import com.reactnativestripesdk.utils.getDoubleOrNull
13
+ import com.reactnativestripesdk.utils.getFloatOr
14
+ import com.reactnativestripesdk.utils.getFloatOrNull
9
15
  import com.stripe.android.paymentelement.AppearanceAPIAdditionsPreview
10
16
  import com.stripe.android.paymentsheet.PaymentSheet
11
17
  import com.stripe.android.uicore.StripeThemeDefaults
12
18
 
13
19
  @SuppressLint("RestrictedApi")
14
20
  fun buildPaymentSheetAppearance(
15
- userParams: Bundle?,
21
+ userParams: ReadableMap?,
16
22
  context: Context,
17
23
  ): PaymentSheet.Appearance {
18
- val colorParams = userParams?.getBundle(PaymentSheetAppearanceKeys.COLORS)
19
- val lightColorParams = colorParams?.getBundle(PaymentSheetAppearanceKeys.LIGHT) ?: colorParams
20
- val darkColorParams = colorParams?.getBundle(PaymentSheetAppearanceKeys.DARK) ?: colorParams
21
- val insetParams = userParams?.getBundle(PaymentSheetAppearanceKeys.FORM_INSETS)
24
+ val colorParams = userParams?.getMap(PaymentSheetAppearanceKeys.COLORS)
25
+ val lightColorParams = colorParams?.getMap(PaymentSheetAppearanceKeys.LIGHT) ?: colorParams
26
+ val darkColorParams = colorParams?.getMap(PaymentSheetAppearanceKeys.DARK) ?: colorParams
27
+ val insetParams = userParams?.getMap(PaymentSheetAppearanceKeys.FORM_INSETS)
22
28
 
23
29
  val embeddedAppearance =
24
30
  buildEmbeddedAppearance(
25
- userParams?.getBundle(PaymentSheetAppearanceKeys.EMBEDDED_PAYMENT_ELEMENT),
26
- lightColorParams,
31
+ userParams?.getMap(PaymentSheetAppearanceKeys.EMBEDDED_PAYMENT_ELEMENT),
27
32
  context,
28
33
  )
29
34
 
30
- embeddedAppearance?.let {
31
- return PaymentSheet.Appearance(
32
- typography = buildTypography(userParams?.getBundle(PaymentSheetAppearanceKeys.FONT), context),
33
- colorsLight = buildColors(lightColorParams, PaymentSheet.Colors.defaultLight),
34
- colorsDark = buildColors(darkColorParams, PaymentSheet.Colors.defaultDark),
35
- shapes = buildShapes(userParams?.getBundle(PaymentSheetAppearanceKeys.SHAPES)),
36
- primaryButton =
37
- buildPrimaryButton(
38
- userParams?.getBundle(PaymentSheetAppearanceKeys.PRIMARY_BUTTON),
39
- context,
40
- ),
41
- embeddedAppearance = embeddedAppearance,
42
- formInsetValues = buildFormInsets(insetParams),
43
- )
44
- }
45
-
46
- return PaymentSheet.Appearance(
47
- typography = buildTypography(userParams?.getBundle(PaymentSheetAppearanceKeys.FONT), context),
48
- colorsLight = buildColors(lightColorParams, PaymentSheet.Colors.defaultLight),
49
- colorsDark = buildColors(darkColorParams, PaymentSheet.Colors.defaultDark),
50
- shapes = buildShapes(userParams?.getBundle(PaymentSheetAppearanceKeys.SHAPES)),
51
- primaryButton =
52
- buildPrimaryButton(
53
- userParams?.getBundle(PaymentSheetAppearanceKeys.PRIMARY_BUTTON),
54
- context,
55
- ),
56
- formInsetValues = buildFormInsets(insetParams),
35
+ val builder = PaymentSheet.Appearance.Builder()
36
+ builder.typography(buildTypography(userParams?.getMap(PaymentSheetAppearanceKeys.FONT), context))
37
+ builder.colorsLight(buildColorsBuilder(lightColorParams).buildLight())
38
+ builder.colorsDark(buildColorsBuilder(darkColorParams).buildDark())
39
+ builder.shapes(buildShapes(userParams?.getMap(PaymentSheetAppearanceKeys.SHAPES)))
40
+ builder.primaryButton(
41
+ buildPrimaryButton(
42
+ userParams?.getMap(PaymentSheetAppearanceKeys.PRIMARY_BUTTON),
43
+ context,
44
+ ),
57
45
  )
46
+ builder.embeddedAppearance(embeddedAppearance)
47
+ builder.formInsetValues(buildFormInsets(insetParams))
48
+ return builder.build()
58
49
  }
59
50
 
60
51
  @OptIn(AppearanceAPIAdditionsPreview::class)
61
52
  private fun buildTypography(
62
- fontParams: Bundle?,
53
+ fontParams: ReadableMap?,
63
54
  context: Context,
64
55
  ): PaymentSheet.Typography {
65
- val scale = getDoubleOrNull(fontParams, PaymentSheetAppearanceKeys.SCALE)
56
+ val scale = fontParams.getDoubleOrNull(PaymentSheetAppearanceKeys.SCALE)
66
57
  val resId =
67
58
  getFontResId(
68
59
  fontParams,
69
60
  PaymentSheetAppearanceKeys.FAMILY,
70
- PaymentSheet.Typography.default.fontResId,
71
61
  context,
72
62
  )
73
- return PaymentSheet.Typography.default.copy(
74
- sizeScaleFactor = scale?.toFloat() ?: PaymentSheet.Typography.default.sizeScaleFactor,
75
- fontResId = resId,
76
- )
63
+ val builder = PaymentSheet.Typography.Builder()
64
+ scale?.let {
65
+ builder.sizeScaleFactor(it.toFloat())
66
+ }
67
+ resId?.let {
68
+ builder.fontResId(it)
69
+ }
70
+ return builder.build()
77
71
  }
78
72
 
79
73
  @Throws(PaymentSheetAppearanceException::class)
80
- private fun colorFromHexOrDefault(
81
- hexString: String?,
82
- default: Int,
83
- ): Int {
84
- return hexString?.trim()?.replace("#", "")?.let {
74
+ private fun colorFromHex(hexString: String?): Int? =
75
+ hexString?.trim()?.replace("#", "")?.let {
85
76
  if (it.length == 6 || it.length == 8) {
86
- return Color.parseColor("#$it")
77
+ Color.parseColor("#$it")
87
78
  } else {
88
79
  throw PaymentSheetAppearanceException(
89
80
  "Failed to set Payment Sheet appearance. Expected hex string of length 6 or 8, but received: $it",
90
81
  )
91
82
  }
92
83
  }
93
- ?: run {
94
- return default
95
- }
96
- }
97
84
 
98
- private fun buildColors(
99
- colorParams: Bundle?,
100
- default: PaymentSheet.Colors,
101
- ): PaymentSheet.Colors {
102
- if (colorParams == null) {
103
- return default
85
+ private fun buildColorsBuilder(colorParams: ReadableMap?): PaymentSheet.Colors.Builder {
86
+ val builder = PaymentSheet.Colors.Builder()
87
+
88
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.PRIMARY))?.let {
89
+ builder.primary(it)
104
90
  }
105
91
 
106
- return default.copy(
107
- primary =
108
- colorFromHexOrDefault(
109
- colorParams.getString(PaymentSheetAppearanceKeys.PRIMARY),
110
- default.primary,
111
- ),
112
- surface =
113
- colorFromHexOrDefault(
114
- colorParams.getString(PaymentSheetAppearanceKeys.BACKGROUND),
115
- default.surface,
116
- ),
117
- component =
118
- colorFromHexOrDefault(
119
- colorParams.getString(PaymentSheetAppearanceKeys.COMPONENT_BACKGROUND),
120
- default.component,
121
- ),
122
- componentBorder =
123
- colorFromHexOrDefault(
124
- colorParams.getString(PaymentSheetAppearanceKeys.COMPONENT_BORDER),
125
- default.componentBorder,
126
- ),
127
- componentDivider =
128
- colorFromHexOrDefault(
129
- colorParams.getString(PaymentSheetAppearanceKeys.COMPONENT_DIVIDER),
130
- default.componentDivider,
131
- ),
132
- onComponent =
133
- colorFromHexOrDefault(
134
- colorParams.getString(PaymentSheetAppearanceKeys.COMPONENT_TEXT),
135
- default.onComponent,
136
- ),
137
- onSurface =
138
- colorFromHexOrDefault(
139
- colorParams.getString(PaymentSheetAppearanceKeys.PRIMARY_TEXT),
140
- default.onSurface,
141
- ),
142
- subtitle =
143
- colorFromHexOrDefault(
144
- colorParams.getString(PaymentSheetAppearanceKeys.SECONDARY_TEXT),
145
- default.subtitle,
146
- ),
147
- placeholderText =
148
- colorFromHexOrDefault(
149
- colorParams.getString(PaymentSheetAppearanceKeys.PLACEHOLDER_TEXT),
150
- default.placeholderText,
151
- ),
152
- appBarIcon =
153
- colorFromHexOrDefault(
154
- colorParams.getString(PaymentSheetAppearanceKeys.ICON),
155
- default.appBarIcon,
156
- ),
157
- error =
158
- colorFromHexOrDefault(
159
- colorParams.getString(PaymentSheetAppearanceKeys.ERROR),
160
- default.error,
161
- ),
162
- )
92
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.BACKGROUND))?.let {
93
+ builder.surface(it)
94
+ }
95
+
96
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.COMPONENT_BACKGROUND))?.let {
97
+ builder.component(it)
98
+ }
99
+
100
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.COMPONENT_BORDER))?.let {
101
+ builder.componentBorder(it)
102
+ }
103
+
104
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.COMPONENT_DIVIDER))?.let {
105
+ builder.componentDivider(it)
106
+ }
107
+
108
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.COMPONENT_TEXT))?.let {
109
+ builder.onComponent(it)
110
+ }
111
+
112
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.PRIMARY_TEXT))?.let {
113
+ builder.onSurface(it)
114
+ }
115
+
116
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.SECONDARY_TEXT))?.let {
117
+ builder.subtitle(it)
118
+ }
119
+
120
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.PLACEHOLDER_TEXT))?.let {
121
+ builder.placeholderText(it)
122
+ }
123
+
124
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.ICON))?.let {
125
+ builder.appBarIcon(it)
126
+ }
127
+
128
+ colorFromHex(colorParams?.getString(PaymentSheetAppearanceKeys.ERROR))?.let {
129
+ builder.error(it)
130
+ }
131
+
132
+ return builder
163
133
  }
164
134
 
165
- private fun buildShapes(shapeParams: Bundle?): PaymentSheet.Shapes =
166
- PaymentSheet.Shapes.default.copy(
167
- cornerRadiusDp =
168
- getFloatOr(
169
- shapeParams,
170
- PaymentSheetAppearanceKeys.BORDER_RADIUS,
171
- PaymentSheet.Shapes.default.cornerRadiusDp,
172
- ),
173
- borderStrokeWidthDp =
174
- getFloatOr(
175
- shapeParams,
176
- PaymentSheetAppearanceKeys.BORDER_WIDTH,
177
- PaymentSheet.Shapes.default.borderStrokeWidthDp,
178
- ),
179
- )
135
+ private fun buildShapes(shapeParams: ReadableMap?): PaymentSheet.Shapes {
136
+ val builder = PaymentSheet.Shapes.Builder()
137
+
138
+ shapeParams.getFloatOrNull(PaymentSheetAppearanceKeys.BORDER_RADIUS)?.let {
139
+ builder.cornerRadiusDp(it)
140
+ }
141
+
142
+ shapeParams.getFloatOrNull(PaymentSheetAppearanceKeys.BORDER_WIDTH)?.let {
143
+ builder.borderStrokeWidthDp(it)
144
+ }
145
+
146
+ return builder.build()
147
+ }
180
148
 
181
149
  private fun buildPrimaryButton(
182
- params: Bundle?,
150
+ params: ReadableMap?,
183
151
  context: Context,
184
152
  ): PaymentSheet.PrimaryButton {
185
153
  if (params == null) {
186
154
  return PaymentSheet.PrimaryButton()
187
155
  }
188
156
 
189
- val fontParams = params.getBundle(PaymentSheetAppearanceKeys.FONT) ?: Bundle.EMPTY
190
- val shapeParams = params.getBundle(PaymentSheetAppearanceKeys.SHAPES) ?: Bundle.EMPTY
191
- val colorParams = params.getBundle(PaymentSheetAppearanceKeys.COLORS) ?: Bundle.EMPTY
192
- val lightColorParams = colorParams.getBundle(PaymentSheetAppearanceKeys.LIGHT) ?: colorParams
193
- val darkColorParams = colorParams.getBundle(PaymentSheetAppearanceKeys.DARK) ?: colorParams
157
+ val fontParams = params.getMap(PaymentSheetAppearanceKeys.FONT) ?: Arguments.createMap()
158
+ val shapeParams = params.getMap(PaymentSheetAppearanceKeys.SHAPES) ?: Arguments.createMap()
159
+ val colorParams = params.getMap(PaymentSheetAppearanceKeys.COLORS) ?: Arguments.createMap()
160
+ val lightColorParams = colorParams.getMap(PaymentSheetAppearanceKeys.LIGHT) ?: colorParams
161
+ val darkColorParams = colorParams.getMap(PaymentSheetAppearanceKeys.DARK) ?: colorParams
194
162
 
195
163
  return PaymentSheet.PrimaryButton(
196
164
  colorsLight =
197
- buildPrimaryButtonColors(lightColorParams, PaymentSheet.PrimaryButtonColors.defaultLight, context),
165
+ buildPrimaryButtonColors(lightColorParams, context).buildLight(),
198
166
  colorsDark =
199
- buildPrimaryButtonColors(darkColorParams, PaymentSheet.PrimaryButtonColors.defaultDark, context),
167
+ buildPrimaryButtonColors(darkColorParams, context).buildDark(),
200
168
  shape =
201
169
  PaymentSheet.PrimaryButtonShape(
202
170
  cornerRadiusDp =
203
- getFloatOrNull(shapeParams, PaymentSheetAppearanceKeys.BORDER_RADIUS),
171
+ shapeParams.getFloatOrNull(PaymentSheetAppearanceKeys.BORDER_RADIUS),
204
172
  borderStrokeWidthDp =
205
- getFloatOrNull(shapeParams, PaymentSheetAppearanceKeys.BORDER_WIDTH),
206
- heightDp = getFloatOrNull(shapeParams, PaymentSheetAppearanceKeys.HEIGHT),
173
+ shapeParams.getFloatOrNull(PaymentSheetAppearanceKeys.BORDER_WIDTH),
174
+ heightDp = shapeParams.getFloatOrNull(PaymentSheetAppearanceKeys.HEIGHT),
207
175
  ),
208
176
  typography =
209
177
  PaymentSheet.PrimaryButtonTypography(
210
178
  fontResId =
211
- getFontResId(fontParams, PaymentSheetAppearanceKeys.FAMILY, null, context),
179
+ getFontResId(fontParams, PaymentSheetAppearanceKeys.FAMILY, context),
212
180
  ),
213
181
  )
214
182
  }
215
183
 
216
184
  @Throws(PaymentSheetAppearanceException::class)
217
185
  private fun buildPrimaryButtonColors(
218
- colorParams: Bundle,
219
- default: PaymentSheet.PrimaryButtonColors,
186
+ colorParams: ReadableMap,
220
187
  context: Context,
221
- ): PaymentSheet.PrimaryButtonColors =
222
- PaymentSheet.PrimaryButtonColors(
223
- background =
224
- colorParams
225
- .getString(PaymentSheetAppearanceKeys.BACKGROUND)
226
- ?.trim()
227
- ?.replace("#", "")
228
- ?.let {
229
- if (it.length == 6 || it.length == 8) {
230
- Color.parseColor("#$it")
231
- } else {
232
- throw PaymentSheetAppearanceException(
233
- "Failed to set Payment Sheet appearance. Expected hex string of length 6 or 8, but received: $it",
234
- )
235
- }
236
- } ?: run { null },
237
- onBackground =
238
- colorFromHexOrDefault(
239
- colorParams.getString(PaymentSheetAppearanceKeys.TEXT),
240
- default.onBackground,
241
- ),
242
- border =
243
- colorFromHexOrDefault(
244
- colorParams.getString(PaymentSheetAppearanceKeys.BORDER),
245
- default.border,
246
- ),
247
- successBackgroundColor =
248
- dynamicColorFromParams(
249
- context,
250
- colorParams,
251
- PaymentSheetAppearanceKeys.SUCCESS_BACKGROUND,
252
- default.successBackgroundColor,
253
- ),
254
- onSuccessBackgroundColor =
255
- dynamicColorFromParams(
256
- context,
257
- colorParams,
258
- PaymentSheetAppearanceKeys.SUCCESS_TEXT,
259
- default.onSuccessBackgroundColor,
260
- ),
261
- )
188
+ ): PaymentSheet.PrimaryButtonColors.Builder {
189
+ val builder = PaymentSheet.PrimaryButtonColors.Builder()
190
+
191
+ // TODO: Why is background a string but successBackgroundColor a "dynamic" color?
192
+ // https://stripe.dev/stripe-react-native/api-reference/types/PaymentSheet.PrimaryButtonColorConfig.html
193
+ colorFromHex(colorParams.getString(PaymentSheetAppearanceKeys.BACKGROUND))?.let {
194
+ builder.background(it)
195
+ }
196
+
197
+ colorFromHex(colorParams.getString(PaymentSheetAppearanceKeys.TEXT))?.let {
198
+ builder.onBackground(it)
199
+ }
200
+
201
+ colorFromHex(colorParams.getString(PaymentSheetAppearanceKeys.BORDER))?.let {
202
+ builder.border(it)
203
+ }
204
+
205
+ dynamicColorFromParams(
206
+ context,
207
+ colorParams,
208
+ PaymentSheetAppearanceKeys.SUCCESS_BACKGROUND,
209
+ )?.let {
210
+ builder.successBackgroundColor(it)
211
+ }
212
+
213
+ dynamicColorFromParams(
214
+ context,
215
+ colorParams,
216
+ PaymentSheetAppearanceKeys.SUCCESS_TEXT,
217
+ )?.let {
218
+ builder.onSuccessBackgroundColor(it)
219
+ }
220
+ return builder
221
+ }
262
222
 
263
223
  @SuppressLint("RestrictedApi")
264
224
  @Throws(PaymentSheetAppearanceException::class)
265
225
  private fun buildEmbeddedAppearance(
266
- embeddedParams: Bundle?,
267
- defaultColorsBundle: Bundle?,
226
+ embeddedParams: ReadableMap?,
268
227
  context: Context,
269
- ): PaymentSheet.Appearance.Embedded? {
270
- if (embeddedParams == null) {
271
- return null
272
- }
228
+ ): PaymentSheet.Appearance.Embedded {
229
+ val embeddedBuilder = PaymentSheet.Appearance.Embedded.Builder()
230
+ val rowParams = embeddedParams?.getMap(PaymentSheetAppearanceKeys.ROW)
231
+ val styleString = rowParams?.getString(PaymentSheetAppearanceKeys.STYLE)
232
+ when (styleString) {
233
+ "flatWithRadio" -> {
234
+ val flatParams = rowParams.getMap(PaymentSheetAppearanceKeys.FLAT)
235
+ val radioParams = flatParams?.getMap(PaymentSheetAppearanceKeys.RADIO)
236
+ val separatorInsetsParams =
237
+ flatParams?.getMap(PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
238
+
239
+ val flatRadioColorsBuilder =
240
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio.Colors
241
+ .Builder()
242
+
243
+ dynamicColorFromParams(
244
+ context,
245
+ flatParams,
246
+ PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
247
+ )?.let {
248
+ flatRadioColorsBuilder.separatorColor(it)
249
+ }
250
+
251
+ dynamicColorFromParams(
252
+ context,
253
+ radioParams,
254
+ PaymentSheetAppearanceKeys.SELECTED_COLOR,
255
+ )?.let {
256
+ flatRadioColorsBuilder.selectedColor(it)
257
+ }
258
+
259
+ dynamicColorFromParams(
260
+ context,
261
+ radioParams,
262
+ PaymentSheetAppearanceKeys.UNSELECTED_COLOR,
263
+ )?.let {
264
+ flatRadioColorsBuilder.unselectedColor(it)
265
+ }
266
+
267
+ val rowStyleBuilder =
268
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio
269
+ .Builder()
270
+
271
+ flatParams.getFloatOrNull(PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS)?.let {
272
+ rowStyleBuilder.separatorThicknessDp(it)
273
+ }
274
+
275
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.LEFT)?.let {
276
+ rowStyleBuilder.startSeparatorInsetDp(it)
277
+ }
273
278
 
274
- val rowParams =
275
- getBundleOrNull(embeddedParams, PaymentSheetAppearanceKeys.ROW)
276
- ?: return null
277
-
278
- val defaultColors = buildColors(defaultColorsBundle, PaymentSheet.Colors.defaultLight)
279
-
280
- // Default style
281
- val styleString = rowParams.getString(PaymentSheetAppearanceKeys.STYLE, "flatWithRadio")
282
-
283
- val defaultAdditionalInsetsDp = 6.0f
284
- val defaultSeparatorThicknessDp = 1.0f
285
- val defaultSpacingDp = 12.0f
286
- val defaultCheckmarkInsetDp = 0f
287
-
288
- val additionalInsets = getFloatOr(rowParams, PaymentSheetAppearanceKeys.ADDITIONAL_INSETS, defaultAdditionalInsetsDp)
289
-
290
- val rowStyle: PaymentSheet.Appearance.Embedded.RowStyle =
291
- when (styleString) {
292
- "flatWithRadio" -> {
293
- val flatParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLAT)
294
- val radioParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.RADIO)
295
- val separatorInsetsParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
296
-
297
- // Default separator insets specific to FlatWithRadio
298
- val defaultSeparatorStartInsetDp = 30.0f
299
- val defaultSeparatorEndInsetDp = 0.0f
300
-
301
- // Parse dimensions as Floats
302
- val separatorThickness = getFloatOr(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS, defaultSeparatorThicknessDp)
303
- val startSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.LEFT, defaultSeparatorStartInsetDp)
304
- val endSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.RIGHT, defaultSeparatorEndInsetDp)
305
-
306
- // Parse booleans
307
- val topEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED, true)
308
- val bottomEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED, true)
309
-
310
- // Parse individual colors using default colors
311
- val parsedSeparatorColor =
312
- dynamicColorFromParams(
313
- context,
314
- flatParams,
315
- PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
316
- defaultColors.componentBorder,
317
- )
318
-
319
- val parsedSelectedColor =
320
- dynamicColorFromParams(
321
- context,
322
- radioParams,
323
- PaymentSheetAppearanceKeys.SELECTED_COLOR,
324
- defaultColors.primary,
325
- )
326
-
327
- val parsedUnselectedColor =
328
- dynamicColorFromParams(
329
- context,
330
- radioParams,
331
- PaymentSheetAppearanceKeys.UNSELECTED_COLOR,
332
- defaultColors.componentBorder,
333
- )
334
-
335
- val flatRadioColors =
336
- PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio.Colors(
337
- separatorColor = parsedSeparatorColor,
338
- unselectedColor = parsedUnselectedColor,
339
- selectedColor = parsedSelectedColor,
340
- )
341
-
342
- PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio(
343
- separatorThicknessDp = separatorThickness,
344
- startSeparatorInsetDp = startSeparatorInset,
345
- endSeparatorInsetDp = endSeparatorInset,
346
- topSeparatorEnabled = topEnabled,
347
- bottomSeparatorEnabled = bottomEnabled,
348
- additionalVerticalInsetsDp = additionalInsets,
349
- horizontalInsetsDp = 0.0F, // We do not have an iOS equal for this API so it's not configurable in React Native
350
- colorsLight = flatRadioColors,
351
- colorsDark = flatRadioColors,
352
- )
279
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.RIGHT)?.let {
280
+ rowStyleBuilder.endSeparatorInsetDp(it)
353
281
  }
354
- "flatWithCheckmark" -> {
355
- val flatParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLAT)
356
- val checkmarkParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.CHECKMARK)
357
- val separatorInsetsParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
358
-
359
- // Default separator insets specific to FlatWithCheckmark and FlatWithDisclosure
360
- val defaultSeparatorStartInsetDp = 0.0f
361
- val defaultSeparatorEndInsetDp = 0.0f
362
-
363
- // Parse dimensions as Floats
364
- val separatorThickness = getFloatOr(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS, defaultSeparatorThicknessDp)
365
- val startSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.LEFT, defaultSeparatorStartInsetDp)
366
- val endSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.RIGHT, defaultSeparatorEndInsetDp)
367
- val checkmarkInset = getFloatOr(checkmarkParams, PaymentSheetAppearanceKeys.CHECKMARK_INSET, defaultCheckmarkInsetDp)
368
-
369
- // Parse booleans
370
- val topEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED, true)
371
- val bottomEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED, true)
372
-
373
- // Parse individual colors using root defaults
374
- val parsedSeparatorColor =
375
- dynamicColorFromParams(
376
- context,
377
- flatParams,
378
- PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
379
- defaultColors.componentBorder,
380
- )
381
-
382
- val parsedCheckmarkColor =
383
- dynamicColorFromParams(
384
- context,
385
- checkmarkParams,
386
- PaymentSheetAppearanceKeys.COLOR,
387
- defaultColors.primary,
388
- )
389
-
390
- // Create the required Colors object
391
- val flatCheckmarkColors =
392
- PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark.Colors(
393
- separatorColor = parsedSeparatorColor,
394
- checkmarkColor = parsedCheckmarkColor,
395
- )
396
-
397
- PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark(
398
- separatorThicknessDp = separatorThickness,
399
- startSeparatorInsetDp = startSeparatorInset,
400
- endSeparatorInsetDp = endSeparatorInset,
401
- topSeparatorEnabled = topEnabled,
402
- bottomSeparatorEnabled = bottomEnabled,
403
- checkmarkInsetDp = checkmarkInset,
404
- additionalVerticalInsetsDp = additionalInsets,
405
- horizontalInsetsDp = 0.0F, // We do not have an iOS equal for this API so it's not configurable in React Native
406
- colorsLight = flatCheckmarkColors,
407
- colorsDark = flatCheckmarkColors,
408
- )
282
+
283
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED)?.let {
284
+ rowStyleBuilder.topSeparatorEnabled(it)
285
+ }
286
+
287
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED)?.let {
288
+ rowStyleBuilder.bottomSeparatorEnabled(it)
289
+ }
290
+
291
+ rowParams.getFloatOrNull(PaymentSheetAppearanceKeys.ADDITIONAL_INSETS)?.let {
292
+ rowStyleBuilder.additionalVerticalInsetsDp(it)
293
+ }
294
+
295
+ rowStyleBuilder.colorsLight(flatRadioColorsBuilder.buildLight())
296
+ rowStyleBuilder.colorsDark(flatRadioColorsBuilder.buildDark())
297
+
298
+ embeddedBuilder.rowStyle(rowStyleBuilder.build())
299
+ }
300
+
301
+ "flatWithCheckmark" -> {
302
+ val flatParams = rowParams?.getMap(PaymentSheetAppearanceKeys.FLAT)
303
+ val checkmarkParams = flatParams?.getMap(PaymentSheetAppearanceKeys.CHECKMARK)
304
+ val separatorInsetsParams =
305
+ flatParams?.getMap(PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
306
+
307
+ val flatCheckmarkColorsBuilder =
308
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark.Colors
309
+ .Builder()
310
+
311
+ dynamicColorFromParams(
312
+ context,
313
+ flatParams,
314
+ PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
315
+ )?.let {
316
+ flatCheckmarkColorsBuilder.separatorColor(it)
317
+ }
318
+
319
+ dynamicColorFromParams(context, checkmarkParams, PaymentSheetAppearanceKeys.COLOR)?.let {
320
+ flatCheckmarkColorsBuilder.checkmarkColor(it)
321
+ }
322
+
323
+ val rowStyleBuilder =
324
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark
325
+ .Builder()
326
+
327
+ flatParams.getFloatOrNull(PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS)?.let {
328
+ rowStyleBuilder.separatorThicknessDp(it)
409
329
  }
410
- "flatWithDisclosure" -> {
411
- val flatParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLAT)
412
- val disclosureParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.DISCLOSURE)
413
- val separatorInsetsParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
414
-
415
- // Default separator insets specific to FlatWithCheckmark and FlatWithDisclosure
416
- val defaultSeparatorStartInsetDp = 0.0f
417
- val defaultSeparatorEndInsetDp = 0.0f
418
-
419
- // Parse dimensions as Floats
420
- val separatorThickness = getFloatOr(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS, defaultSeparatorThicknessDp)
421
- val startSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.LEFT, defaultSeparatorStartInsetDp)
422
- val endSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.RIGHT, defaultSeparatorEndInsetDp)
423
-
424
- // Parse booleans
425
- val topEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED, true)
426
- val bottomEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED, true)
427
-
428
- val parsedSeparatorColor =
429
- dynamicColorFromParams(
430
- context,
431
- flatParams,
432
- PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
433
- Color.GRAY,
434
- )
435
-
436
- val parsedDisclosureColor =
437
- dynamicColorFromParams(
438
- context,
439
- disclosureParams,
440
- PaymentSheetAppearanceKeys.COLOR,
441
- defaultColors.componentBorder, // Default to component border color like other elements
442
- )
443
-
444
- // Create the required Colors object
445
- val flatDisclosureColors =
446
- PaymentSheet.Appearance.Embedded.RowStyle.FlatWithDisclosure.Colors(
447
- separatorColor = parsedSeparatorColor,
448
- disclosureColor = parsedDisclosureColor,
449
- )
450
330
 
331
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.LEFT)?.let {
332
+ rowStyleBuilder.startSeparatorInsetDp(it)
333
+ }
334
+
335
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.RIGHT)?.let {
336
+ rowStyleBuilder.endSeparatorInsetDp(it)
337
+ }
338
+
339
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED)?.let {
340
+ rowStyleBuilder.topSeparatorEnabled(it)
341
+ }
342
+
343
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED)?.let {
344
+ rowStyleBuilder.bottomSeparatorEnabled(it)
345
+ }
346
+
347
+ checkmarkParams.getFloatOrNull(PaymentSheetAppearanceKeys.CHECKMARK_INSET)?.let {
348
+ rowStyleBuilder.checkmarkInsetDp(it)
349
+ }
350
+
351
+ rowParams.getFloatOrNull(PaymentSheetAppearanceKeys.ADDITIONAL_INSETS)?.let {
352
+ rowStyleBuilder.additionalVerticalInsetsDp(it)
353
+ }
354
+
355
+ // TODO: The theme is so crazy long, why does each Color thing has the same redundant Theme...
356
+ rowStyleBuilder.colorsLight(flatCheckmarkColorsBuilder.buildLight())
357
+ rowStyleBuilder.colorsDark(flatCheckmarkColorsBuilder.buildDark())
358
+ embeddedBuilder.rowStyle(rowStyleBuilder.build())
359
+ }
360
+
361
+ "flatWithDisclosure" -> {
362
+ val flatParams = rowParams?.getMap(PaymentSheetAppearanceKeys.FLAT)
363
+ val disclosureParams = flatParams?.getMap(PaymentSheetAppearanceKeys.DISCLOSURE)
364
+ val separatorInsetsParams =
365
+ flatParams?.getMap(PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
366
+
367
+ val flatDisclosureColorsBuilder =
368
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithDisclosure.Colors
369
+ .Builder()
370
+
371
+ dynamicColorFromParams(
372
+ context,
373
+ flatParams,
374
+ PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
375
+ )?.let {
376
+ flatDisclosureColorsBuilder.separatorColor(it)
377
+ }
378
+
379
+ dynamicColorFromParams(context, disclosureParams, PaymentSheetAppearanceKeys.COLOR)?.let {
380
+ flatDisclosureColorsBuilder.disclosureColor(it)
381
+ }
382
+
383
+ val rowStyleBuilder =
451
384
  PaymentSheet.Appearance.Embedded.RowStyle.FlatWithDisclosure
452
385
  .Builder()
453
- .separatorThicknessDp(separatorThickness)
454
- .startSeparatorInsetDp(startSeparatorInset)
455
- .endSeparatorInsetDp(endSeparatorInset)
456
- .topSeparatorEnabled(topEnabled)
457
- .bottomSeparatorEnabled(bottomEnabled)
458
- .additionalVerticalInsetsDp(additionalInsets)
459
- .horizontalInsetsDp(0.0F) // We do not have an iOS equal for this API so it's not configurable in React Native
460
- .colorsLight(flatDisclosureColors)
461
- .colorsDark(flatDisclosureColors)
462
- .build()
386
+
387
+ flatParams.getFloatOrNull(PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS)?.let {
388
+ rowStyleBuilder.separatorThicknessDp(it)
389
+ }
390
+
391
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.LEFT)?.let {
392
+ rowStyleBuilder.startSeparatorInsetDp(it)
463
393
  }
464
- "floatingButton" -> {
465
- val floatingParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLOATING)
466
- PaymentSheet.Appearance.Embedded.RowStyle.FloatingButton(
467
- additionalInsetsDp = additionalInsets,
468
- spacingDp = getFloatOr(floatingParams, PaymentSheetAppearanceKeys.SPACING, defaultSpacingDp),
469
- )
394
+
395
+ separatorInsetsParams.getFloatOrNull(PaymentSheetAppearanceKeys.RIGHT)?.let {
396
+ rowStyleBuilder.endSeparatorInsetDp(it)
397
+ }
398
+
399
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED)?.let {
400
+ rowStyleBuilder.topSeparatorEnabled(it)
401
+ }
402
+
403
+ flatParams.getBooleanOrNull(PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED)?.let {
404
+ rowStyleBuilder.bottomSeparatorEnabled(it)
405
+ }
406
+
407
+ rowParams.getFloatOrNull(PaymentSheetAppearanceKeys.ADDITIONAL_INSETS)?.let {
408
+ rowStyleBuilder.additionalVerticalInsetsDp(it)
409
+ }
410
+
411
+ rowStyleBuilder.colorsLight(flatDisclosureColorsBuilder.buildLight())
412
+ rowStyleBuilder.colorsDark(flatDisclosureColorsBuilder.buildDark())
413
+
414
+ embeddedBuilder.rowStyle(rowStyleBuilder.build())
415
+ }
416
+
417
+ "floatingButton" -> {
418
+ val floatingParams = rowParams.getMap(PaymentSheetAppearanceKeys.FLOATING)
419
+ val rowStyleBuilder =
420
+ PaymentSheet.Appearance.Embedded.RowStyle.FloatingButton
421
+ .Builder()
422
+
423
+ rowParams.getFloatOrNull(PaymentSheetAppearanceKeys.ADDITIONAL_INSETS)?.let {
424
+ rowStyleBuilder.additionalInsetsDp(it)
470
425
  }
471
- else -> {
472
- System.err.println("WARN: Unsupported embedded payment element row style received: $styleString. Falling back to default.")
473
- return null
426
+
427
+ floatingParams.getFloatOrNull(PaymentSheetAppearanceKeys.SPACING)?.let {
428
+ rowStyleBuilder.spacingDp(it)
474
429
  }
430
+
431
+ embeddedBuilder.rowStyle(rowStyleBuilder.build())
475
432
  }
476
433
 
477
- return PaymentSheet.Appearance.Embedded(style = rowStyle)
434
+ else -> {
435
+ System.err.println("WARN: Unsupported embedded payment element row style received: $styleString. Falling back to default.")
436
+ }
437
+ }
438
+ return embeddedBuilder.build()
478
439
  }
479
440
 
480
441
  @SuppressLint("RestrictedApi")
481
- private fun buildFormInsets(insetParams: Bundle?): PaymentSheet.Insets {
442
+ private fun buildFormInsets(insetParams: ReadableMap?): PaymentSheet.Insets {
482
443
  val defaults = StripeThemeDefaults.formInsets
483
- val left = getFloatOr(insetParams, PaymentSheetAppearanceKeys.LEFT, defaults.start)
484
- val top = getFloatOr(insetParams, PaymentSheetAppearanceKeys.TOP, defaults.top)
485
- val right = getFloatOr(insetParams, PaymentSheetAppearanceKeys.RIGHT, defaults.end)
486
- val bottom = getFloatOr(insetParams, PaymentSheetAppearanceKeys.BOTTOM, defaults.bottom)
444
+ val left = insetParams.getFloatOr(PaymentSheetAppearanceKeys.LEFT, defaults.start)
445
+ val top = insetParams.getFloatOr(PaymentSheetAppearanceKeys.TOP, defaults.top)
446
+ val right = insetParams.getFloatOr(PaymentSheetAppearanceKeys.RIGHT, defaults.end)
447
+ val bottom = insetParams.getFloatOr(PaymentSheetAppearanceKeys.BOTTOM, defaults.bottom)
487
448
 
488
449
  return PaymentSheet.Insets(
489
450
  startDp = left,
@@ -498,21 +459,20 @@ private fun buildFormInsets(insetParams: Bundle?): PaymentSheet.Insets {
498
459
  * - Single hex string: "#RRGGBB"
499
460
  * - Light/dark object: { "light": "#RRGGBB", "dark": "#RRGGBB" }
500
461
  * For light/dark objects, chooses the appropriate color based on current UI mode.
501
- * Falls back to [defaultColor] if no color is provided.
462
+ * Returns null if no color is provided.
502
463
  */
503
464
  private fun dynamicColorFromParams(
504
465
  context: Context,
505
- params: Bundle?,
466
+ params: ReadableMap?,
506
467
  key: String,
507
- defaultColor: Int,
508
- ): Int {
468
+ ): Int? {
509
469
  if (params == null) {
510
- return defaultColor
470
+ return null
511
471
  }
512
472
 
513
- // First check if it's a nested Bundle { "light": "#RRGGBB", "dark": "#RRGGBB" }
514
- val colorBundle = params.getBundle(key)
515
- if (colorBundle != null) {
473
+ // First check if it's a nested map { "light": "#RRGGBB", "dark": "#RRGGBB" }
474
+ if (params.hasKey(key) && params.getType(key) == ReadableType.Map) {
475
+ val colorMap = params.getMap(key)
516
476
  val isDark =
517
477
  (
518
478
  context.resources.configuration.uiMode
@@ -522,108 +482,31 @@ private fun dynamicColorFromParams(
522
482
  // Pick the hex for current mode, or null
523
483
  val hex =
524
484
  if (isDark) {
525
- colorBundle.getString(PaymentSheetAppearanceKeys.DARK)
485
+ colorMap?.getString(PaymentSheetAppearanceKeys.DARK)
526
486
  } else {
527
- colorBundle.getString(PaymentSheetAppearanceKeys.LIGHT)
487
+ colorMap?.getString(PaymentSheetAppearanceKeys.LIGHT)
528
488
  }
529
489
 
530
- return colorFromHexOrDefault(hex, defaultColor)
490
+ return colorFromHex(hex)
531
491
  }
532
492
 
533
493
  // Check if it's a single color string
534
- params.getString(key)?.let { colorString ->
535
- return colorFromHexOrDefault(colorString, defaultColor)
536
- }
537
-
538
- // no override → just use default
539
- return defaultColor
540
- }
541
-
542
- private fun getDoubleOrNull(
543
- bundle: Bundle?,
544
- key: String,
545
- ): Double? {
546
- if (bundle?.containsKey(key) == true) {
547
- val valueOfUnknownType = bundle.get(key)
548
- if (valueOfUnknownType is Double) {
549
- return valueOfUnknownType
550
- } else if (valueOfUnknownType is Int) {
551
- return valueOfUnknownType.toDouble()
552
- } else if (valueOfUnknownType is Float) {
553
- return valueOfUnknownType.toDouble()
554
- }
555
- }
556
-
557
- return null
558
- }
559
-
560
- private fun getFloatOr(
561
- bundle: Bundle?,
562
- key: String,
563
- defaultValue: Float,
564
- ): Float {
565
- if (bundle?.containsKey(key) == true) {
566
- val valueOfUnknownType = bundle.get(key)
567
- if (valueOfUnknownType is Float) {
568
- return valueOfUnknownType
569
- } else if (valueOfUnknownType is Int) {
570
- return valueOfUnknownType.toFloat()
571
- } else if (valueOfUnknownType is Double) {
572
- return valueOfUnknownType.toFloat()
573
- }
574
- }
575
-
576
- return defaultValue
577
- }
578
-
579
- private fun getBundleOrNull(
580
- bundle: Bundle?,
581
- key: String,
582
- ): Bundle? = bundle?.getBundle(key)
583
-
584
- private fun getBooleanOr(
585
- bundle: Bundle?,
586
- key: String,
587
- defaultValue: Boolean,
588
- ): Boolean =
589
- if (bundle?.containsKey(key) == true) {
590
- bundle.getBoolean(key)
591
- } else {
592
- defaultValue
593
- }
594
-
595
- private fun getFloatOrNull(
596
- bundle: Bundle?,
597
- key: String,
598
- ): Float? {
599
- if (bundle?.containsKey(key) == true) {
600
- val valueOfUnknownType = bundle.get(key)
601
- if (valueOfUnknownType is Float) {
602
- return valueOfUnknownType
603
- } else if (valueOfUnknownType is Int) {
604
- return valueOfUnknownType.toFloat()
605
- } else if (valueOfUnknownType is Double) {
606
- return valueOfUnknownType.toFloat()
607
- }
608
- }
609
-
610
- return null
494
+ return colorFromHex(params.getString(key))
611
495
  }
612
496
 
613
497
  @Throws(PaymentSheetAppearanceException::class)
614
498
  private fun getFontResId(
615
- bundle: Bundle?,
499
+ map: ReadableMap?,
616
500
  key: String,
617
- defaultValue: Int?,
618
501
  context: Context,
619
502
  ): Int? {
620
503
  val fontErrorPrefix = "Encountered an error when setting a custom font:"
621
- if (bundle?.containsKey(key) != true) {
622
- return defaultValue
504
+ if (map?.hasKey(key) != true) {
505
+ return null
623
506
  }
624
507
 
625
508
  val fontFileName =
626
- bundle.getString(key)
509
+ map.getString(key)
627
510
  ?: throw PaymentSheetAppearanceException(
628
511
  "$fontErrorPrefix expected String for font.$key, but received null.",
629
512
  )