@stripe/stripe-react-native 0.65.0 → 0.65.1

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 (203) hide show
  1. package/README.md +2 -2
  2. package/android/detekt/detekt-baseline.xml +1 -66
  3. package/android/gradle.properties +3 -3
  4. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormView.kt +3 -1
  5. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormViewManager.kt +2 -1
  6. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +5 -1
  7. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementView.kt +26 -0
  8. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +42 -0
  9. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +105 -49
  10. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +72 -12
  11. package/android/src/main/java/com/reactnativestripesdk/FinancialConnectionsSheetManager.kt +8 -4
  12. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonManager.kt +2 -1
  13. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonView.kt +26 -11
  14. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +2 -1
  15. package/android/src/main/java/com/reactnativestripesdk/NavigationBarView.kt +14 -5
  16. package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +6 -2
  17. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherManager.kt +2 -1
  18. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +2 -1
  19. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +6 -2
  20. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +2 -1
  21. package/android/src/main/java/com/reactnativestripesdk/PaymentOptionDisplayDataMapper.kt +8 -4
  22. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +9 -3
  23. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +110 -29
  24. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +190 -24
  25. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
  26. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +2 -1
  27. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +3 -1
  28. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +6 -2
  29. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerAdapter.kt +3 -1
  30. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +2 -1
  31. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +2 -1
  32. package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutAddressUpdate.kt +45 -0
  33. package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutMappers.kt +101 -0
  34. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +4 -2
  35. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +5 -1
  36. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +29 -13
  37. package/android/src/main/java/com/reactnativestripesdk/utils/PostalCodeUtilities.kt +2 -1
  38. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +6 -0
  39. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +2 -0
  40. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerDelegate.java +35 -0
  41. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerInterface.java +18 -0
  42. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -0
  43. package/android/src/test/java/com/reactnativestripesdk/mappers/MappersTest.kt +60 -0
  44. package/android/src/test/java/com/reactnativestripesdk/mappers/OnrampMappersTest.kt +38 -0
  45. package/android/src/test/java/com/reactnativestripesdk/mappers/PaymentOptionDisplayDataMapperTest.kt +9 -4
  46. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutMappersTest.kt +89 -0
  47. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutTestFixtures.java +49 -0
  48. package/ios/ConnectAccountOnboarding/ConnectAccountOnboardingViewController.swift +6 -8
  49. package/ios/CurrencySelectorElementManager.m +9 -0
  50. package/ios/CurrencySelectorElementManager.swift +12 -0
  51. package/ios/CurrencySelectorElementView.swift +24 -0
  52. package/ios/Mappers+Checkout.swift +193 -0
  53. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +16 -2
  54. package/ios/NewArch/StripeCurrencySelectorElementComponentView.h +10 -0
  55. package/ios/NewArch/StripeCurrencySelectorElementComponentView.mm +75 -0
  56. package/ios/StripeSdk.mm +123 -0
  57. package/ios/StripeSdkImpl+Checkout.swift +308 -0
  58. package/ios/StripeSdkImpl+Embedded.swift +108 -27
  59. package/ios/StripeSdkImpl+PaymentSheet.swift +18 -2
  60. package/ios/StripeSdkImpl.swift +3 -1
  61. package/jest/mock.js +13 -1
  62. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  63. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  64. package/lib/commonjs/components/AddressSheet.js +1 -1
  65. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  66. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  67. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  68. package/lib/commonjs/components/CardField.js +1 -1
  69. package/lib/commonjs/components/CardField.js.map +1 -1
  70. package/lib/commonjs/components/CardForm.js +1 -1
  71. package/lib/commonjs/components/CardForm.js.map +1 -1
  72. package/lib/commonjs/components/CurrencySelectorElement.js +2 -0
  73. package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -0
  74. package/lib/commonjs/components/PaymentMethodMessagingElement.js +1 -1
  75. package/lib/commonjs/components/PaymentMethodMessagingElement.js.map +1 -1
  76. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  77. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  78. package/lib/commonjs/components/StripeContainer.js +1 -1
  79. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  80. package/lib/commonjs/connect/Components.js +1 -1
  81. package/lib/commonjs/connect/Components.js.map +1 -1
  82. package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
  83. package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
  84. package/lib/commonjs/connect/EmbeddedComponent.js +1 -1
  85. package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
  86. package/lib/commonjs/connect/ModalCloseButton.js +1 -1
  87. package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
  88. package/lib/commonjs/connect/NavigationBar.js +1 -1
  89. package/lib/commonjs/connect/NavigationBar.js.map +1 -1
  90. package/lib/commonjs/events.js.map +1 -1
  91. package/lib/commonjs/functions.js +1 -1
  92. package/lib/commonjs/functions.js.map +1 -1
  93. package/lib/commonjs/helpers.js +1 -1
  94. package/lib/commonjs/hooks/useCheckout.js +1 -1
  95. package/lib/commonjs/hooks/useCheckout.js.map +1 -1
  96. package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
  97. package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
  98. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  99. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
  100. package/lib/commonjs/specs/NativeCardField.js +1 -1
  101. package/lib/commonjs/specs/NativeCardField.js.map +1 -1
  102. package/lib/commonjs/specs/NativeCardForm.js +1 -1
  103. package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
  104. package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
  105. package/lib/commonjs/specs/NativeCurrencySelectorElement.js +2 -0
  106. package/lib/commonjs/specs/NativeCurrencySelectorElement.js.map +1 -0
  107. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
  108. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  109. package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
  110. package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
  111. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +1 -1
  112. package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
  113. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  114. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  115. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  116. package/lib/module/components/AddToWalletButton.js +1 -1
  117. package/lib/module/components/AddToWalletButton.js.map +1 -1
  118. package/lib/module/components/AddressSheet.js +1 -1
  119. package/lib/module/components/AddressSheet.js.map +1 -1
  120. package/lib/module/components/AuBECSDebitForm.js +1 -1
  121. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  122. package/lib/module/components/CardField.js +1 -1
  123. package/lib/module/components/CardField.js.map +1 -1
  124. package/lib/module/components/CardForm.js +1 -1
  125. package/lib/module/components/CardForm.js.map +1 -1
  126. package/lib/module/components/CurrencySelectorElement.js +2 -0
  127. package/lib/module/components/CurrencySelectorElement.js.map +1 -0
  128. package/lib/module/components/PaymentMethodMessagingElement.js +1 -1
  129. package/lib/module/components/PaymentMethodMessagingElement.js.map +1 -1
  130. package/lib/module/components/PlatformPayButton.js +1 -1
  131. package/lib/module/components/PlatformPayButton.js.map +1 -1
  132. package/lib/module/components/StripeContainer.js +1 -1
  133. package/lib/module/components/StripeContainer.js.map +1 -1
  134. package/lib/module/connect/Components.js +1 -1
  135. package/lib/module/connect/Components.js.map +1 -1
  136. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  137. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  138. package/lib/module/connect/EmbeddedComponent.js +1 -1
  139. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  140. package/lib/module/connect/ModalCloseButton.js +1 -1
  141. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  142. package/lib/module/connect/NavigationBar.js +1 -1
  143. package/lib/module/connect/NavigationBar.js.map +1 -1
  144. package/lib/module/events.js.map +1 -1
  145. package/lib/module/functions.js +1 -1
  146. package/lib/module/functions.js.map +1 -1
  147. package/lib/module/helpers.js +1 -1
  148. package/lib/module/hooks/useCheckout.js +1 -1
  149. package/lib/module/hooks/useCheckout.js.map +1 -1
  150. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  151. package/lib/module/specs/NativeAddressSheet.js +1 -1
  152. package/lib/module/specs/NativeApplePayButton.js +1 -1
  153. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  154. package/lib/module/specs/NativeCardField.js +1 -1
  155. package/lib/module/specs/NativeCardField.js.map +1 -1
  156. package/lib/module/specs/NativeCardForm.js +1 -1
  157. package/lib/module/specs/NativeCardForm.js.map +1 -1
  158. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  159. package/lib/module/specs/NativeCurrencySelectorElement.js +2 -0
  160. package/lib/module/specs/NativeCurrencySelectorElement.js.map +1 -0
  161. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  162. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  163. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  164. package/lib/module/specs/NativeNavigationBar.js +1 -1
  165. package/lib/module/specs/NativePaymentMethodMessagingElement.js +1 -1
  166. package/lib/module/specs/NativeStripeContainer.js +1 -1
  167. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  168. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  169. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  170. package/lib/typescript/src/components/CurrencySelectorElement.d.ts +62 -0
  171. package/lib/typescript/src/components/CurrencySelectorElement.d.ts.map +1 -0
  172. package/lib/typescript/src/events.d.ts +11 -0
  173. package/lib/typescript/src/events.d.ts.map +1 -1
  174. package/lib/typescript/src/functions.d.ts.map +1 -1
  175. package/lib/typescript/src/hooks/useCheckout.d.ts.map +1 -1
  176. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts +25 -0
  177. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts.map +1 -0
  178. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +5 -1
  179. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -1
  180. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +3 -1
  181. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  182. package/lib/typescript/src/types/Checkout.d.ts +2 -2
  183. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +36 -1
  184. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  185. package/package.json +14 -3
  186. package/src/components/CurrencySelectorElement.tsx +95 -0
  187. package/src/events.ts +11 -0
  188. package/src/functions.ts +30 -1
  189. package/src/hooks/useCheckout.tsx +114 -75
  190. package/src/specs/NativeCurrencySelectorElement.ts +35 -0
  191. package/src/specs/NativeEmbeddedPaymentElement.ts +12 -2
  192. package/src/specs/NativeStripeSdkModule.ts +8 -1
  193. package/src/types/Checkout.ts +2 -2
  194. package/src/types/EmbeddedPaymentElement.tsx +117 -26
  195. package/android/.idea/AndroidProjectSystem.xml +0 -6
  196. package/android/.idea/caches/deviceStreaming.xml +0 -835
  197. package/android/.idea/compiler.xml +0 -6
  198. package/android/.idea/gradle.xml +0 -17
  199. package/android/.idea/migrations.xml +0 -10
  200. package/android/.idea/misc.xml +0 -10
  201. package/android/.idea/runConfigurations.xml +0 -17
  202. package/android/.idea/vcs.xml +0 -6
  203. package/android/local.properties +0 -8
@@ -77,23 +77,23 @@ class GooglePayButtonView(
77
77
 
78
78
  private fun getButtonType(): Int? =
79
79
  when (this.type) {
80
- 0,
81
- 1,
80
+ BUTTON_TYPE_BUY_DEFAULT,
81
+ BUTTON_TYPE_BUY_ALT,
82
82
  -> ButtonType.BUY
83
- 6 -> ButtonType.BOOK
84
- 5 -> ButtonType.CHECKOUT
85
- 4 -> ButtonType.DONATE
86
- 11 -> ButtonType.ORDER
87
- 7 -> ButtonType.SUBSCRIBE
88
- 1000 -> ButtonType.PAY
89
- 1001 -> ButtonType.PLAIN
83
+ BUTTON_TYPE_BOOK -> ButtonType.BOOK
84
+ BUTTON_TYPE_CHECKOUT -> ButtonType.CHECKOUT
85
+ BUTTON_TYPE_DONATE -> ButtonType.DONATE
86
+ BUTTON_TYPE_ORDER -> ButtonType.ORDER
87
+ BUTTON_TYPE_SUBSCRIBE -> ButtonType.SUBSCRIBE
88
+ BUTTON_TYPE_PAY -> ButtonType.PAY
89
+ BUTTON_TYPE_PLAIN -> ButtonType.PLAIN
90
90
  else -> null
91
91
  }
92
92
 
93
93
  private fun getButtonTheme(): Int? =
94
94
  when (this.appearance) {
95
- 0, 1 -> ButtonTheme.LIGHT
96
- 2 -> ButtonTheme.DARK
95
+ BUTTON_THEME_LIGHT_DEFAULT, BUTTON_THEME_LIGHT_ALT -> ButtonTheme.LIGHT
96
+ BUTTON_THEME_DARK -> ButtonTheme.DARK
97
97
  else -> null
98
98
  }
99
99
 
@@ -122,4 +122,19 @@ class GooglePayButtonView(
122
122
  fun setBorderRadius(borderRadius: Int) {
123
123
  this.borderRadius = borderRadius
124
124
  }
125
+
126
+ private companion object {
127
+ const val BUTTON_TYPE_BUY_DEFAULT = 0
128
+ const val BUTTON_TYPE_BUY_ALT = 1
129
+ const val BUTTON_TYPE_DONATE = 4
130
+ const val BUTTON_TYPE_CHECKOUT = 5
131
+ const val BUTTON_TYPE_BOOK = 6
132
+ const val BUTTON_TYPE_SUBSCRIBE = 7
133
+ const val BUTTON_TYPE_ORDER = 11
134
+ const val BUTTON_TYPE_PAY = 1000
135
+ const val BUTTON_TYPE_PLAIN = 1001
136
+ const val BUTTON_THEME_LIGHT_DEFAULT = 0
137
+ const val BUTTON_THEME_LIGHT_ALT = 1
138
+ const val BUTTON_THEME_DARK = 2
139
+ }
125
140
  }
@@ -76,7 +76,8 @@ class GooglePayLauncherManager(
76
76
  null,
77
77
  createError(
78
78
  GooglePayErrorType.Failed.toString(),
79
- "Google Pay is not available on this device. You can use isPlatformPaySupported to preemptively check for Google Pay support.",
79
+ "Google Pay is not available on this device. You can use isPlatformPaySupported " +
80
+ "to preemptively check for Google Pay support.",
80
81
  ),
81
82
  )
82
83
  }
@@ -35,13 +35,13 @@ class NavigationBarView(
35
35
  LayoutParams.WRAP_CONTENT,
36
36
  )
37
37
  setBackgroundColor(Color.WHITE)
38
- elevation = 4f
38
+ elevation = TOOLBAR_ELEVATION
39
39
  }
40
40
 
41
41
  // Create title TextView
42
42
  titleTextView =
43
43
  TextView(context).apply {
44
- textSize = 17f
44
+ textSize = TITLE_TEXT_SIZE
45
45
  setTextColor(Color.BLACK)
46
46
  gravity = Gravity.CENTER
47
47
  }
@@ -67,7 +67,9 @@ class NavigationBarView(
67
67
  ),
68
68
  )
69
69
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
70
- drawable?.setColorFilter(android.graphics.BlendModeColorFilter(Color.BLACK, android.graphics.BlendMode.SRC_IN))
70
+ drawable?.setColorFilter(
71
+ android.graphics.BlendModeColorFilter(Color.BLACK, android.graphics.BlendMode.SRC_IN)
72
+ )
71
73
  } else {
72
74
  @Suppress("DEPRECATION")
73
75
  drawable?.setColorFilter(PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN))
@@ -86,7 +88,7 @@ class NavigationBarView(
86
88
  Toolbar.LayoutParams.WRAP_CONTENT,
87
89
  ).apply {
88
90
  gravity = Gravity.END or Gravity.CENTER_VERTICAL
89
- marginEnd = 16
91
+ marginEnd = CLOSE_BUTTON_MARGIN_END
90
92
  }
91
93
  toolbar.addView(closeButton, buttonParams)
92
94
 
@@ -115,7 +117,7 @@ class NavigationBarView(
115
117
  ) {
116
118
  super.onMeasure(widthMeasureSpec, heightMeasureSpec)
117
119
  // Set a fixed height for the navigation bar
118
- val desiredHeight = (56 * resources.displayMetrics.density).toInt()
120
+ val desiredHeight = (NAV_BAR_HEIGHT_DP * resources.displayMetrics.density).toInt()
119
121
  val newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(desiredHeight, MeasureSpec.EXACTLY)
120
122
  super.onMeasure(widthMeasureSpec, newHeightMeasureSpec)
121
123
  }
@@ -128,4 +130,11 @@ class NavigationBarView(
128
130
 
129
131
  override fun getEventData() = Arguments.createMap()
130
132
  }
133
+
134
+ private companion object {
135
+ const val TOOLBAR_ELEVATION = 4f
136
+ const val TITLE_TEXT_SIZE = 17f
137
+ const val CLOSE_BUTTON_MARGIN_END = 16
138
+ const val NAV_BAR_HEIGHT_DP = 56
139
+ }
131
140
  }
@@ -186,7 +186,9 @@ internal fun buildBillingDetails(map: ReadableMap?): PaymentSheet.BillingDetails
186
186
  )
187
187
  }
188
188
 
189
- internal fun buildBillingDetailsCollectionConfiguration(map: ReadableMap?): PaymentSheet.BillingDetailsCollectionConfiguration =
189
+ internal fun buildBillingDetailsCollectionConfiguration(
190
+ map: ReadableMap?
191
+ ): PaymentSheet.BillingDetailsCollectionConfiguration =
190
192
  PaymentSheet.BillingDetailsCollectionConfiguration(
191
193
  name = mapToCollectionMode(map?.getString("name")),
192
194
  phone = mapToCollectionMode(map?.getString("phone")),
@@ -203,7 +205,9 @@ internal fun mapToCollectionMode(str: String?): PaymentSheet.BillingDetailsColle
203
205
  else -> PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Automatic
204
206
  }
205
207
 
206
- internal fun mapToAddressCollectionMode(str: String?): PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode =
208
+ internal fun mapToAddressCollectionMode(
209
+ str: String?
210
+ ): PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode =
207
211
  when (str) {
208
212
  "automatic" ->
209
213
  PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Automatic
@@ -165,7 +165,8 @@ class PaymentLauncherManager(
165
165
  paymentLauncher.handleNextActionForSetupIntent(handleNextActionSetupIntentClientSecret!!)
166
166
  } else {
167
167
  throw Exception(
168
- "Invalid parameters provided to PaymentLauncher. Ensure that you are providing the correct client secret and setup params (if necessary).",
168
+ "Invalid parameters provided to PaymentLauncher. Ensure that you are providing the correct client " +
169
+ "secret and setup params (if necessary).",
169
170
  )
170
171
  }
171
172
  }
@@ -234,7 +234,8 @@ class PaymentMethodCreateParamsFactory(
234
234
  )
235
235
 
236
236
  @Throws(PaymentMethodCreateParamsException::class)
237
- private fun createPayPalParams(): PaymentMethodCreateParams = PaymentMethodCreateParams.createPayPal(metadata = metadataParams)
237
+ private fun createPayPalParams(): PaymentMethodCreateParams =
238
+ PaymentMethodCreateParams.createPayPal(metadata = metadataParams)
238
239
 
239
240
  @Throws(PaymentMethodCreateParamsException::class)
240
241
  private fun createAffirmParams(): PaymentMethodCreateParams =
@@ -77,7 +77,7 @@ private fun parseFont(
77
77
  "family",
78
78
  context,
79
79
  )
80
- val size = map.getDoubleOrNull("size") ?: 16.0
80
+ val size = map.getDoubleOrNull("size") ?: DEFAULT_FONT_SIZE
81
81
 
82
82
  val font =
83
83
  PaymentMethodMessagingElement.Appearance
@@ -136,7 +136,7 @@ private fun dynamicColorFromParams(
136
136
  @Throws(PaymentMethodMessagingElementAppearanceException::class)
137
137
  private fun colorFromHex(hexString: String?): Int? =
138
138
  hexString?.trim()?.replace("#", "")?.let {
139
- if (it.length == 6 || it.length == 8) {
139
+ if (it.length == HEX_COLOR_LENGTH_RGB || it.length == HEX_COLOR_LENGTH_ARGB) {
140
140
  "#$it".toColorInt()
141
141
  } else {
142
142
  throw PaymentMethodMessagingElementAppearanceException(
@@ -144,3 +144,7 @@ private fun colorFromHex(hexString: String?): Int? =
144
144
  )
145
145
  }
146
146
  }
147
+
148
+ private const val DEFAULT_FONT_SIZE = 16.0
149
+ private const val HEX_COLOR_LENGTH_RGB = 6
150
+ private const val HEX_COLOR_LENGTH_ARGB = 8
@@ -25,7 +25,8 @@ class PaymentMethodMessagingElementViewManager :
25
25
 
26
26
  override fun getDelegate() = delegate
27
27
 
28
- override fun createViewInstance(ctx: ThemedReactContext): PaymentMethodMessagingElementView = PaymentMethodMessagingElementView(ctx)
28
+ override fun createViewInstance(ctx: ThemedReactContext): PaymentMethodMessagingElementView =
29
+ PaymentMethodMessagingElementView(ctx)
29
30
 
30
31
  override fun onDropViewInstance(view: PaymentMethodMessagingElementView) {
31
32
  super.onDropViewInstance(view)
@@ -39,7 +39,7 @@ suspend fun EmbeddedPaymentElement.PaymentOptionDisplayData.toWritableMap(): Wri
39
39
  try {
40
40
  withContext(Dispatchers.Default) {
41
41
  val drawable =
42
- withTimeout(5_000L) {
42
+ withTimeout(IMAGE_LOAD_TIMEOUT_MS) {
43
43
  withContext(Dispatchers.IO) {
44
44
  imageLoader()
45
45
  }
@@ -164,12 +164,12 @@ private fun getHtmlTagsForSpanStyle(spanStyle: SpanStyle): List<Pair<String, Str
164
164
  }
165
165
 
166
166
  spanStyle.color.takeIf { it != Color.Unspecified }?.let { color ->
167
- val hexColor = String.format("#%06X", 0xFFFFFF and color.toArgb())
167
+ val hexColor = String.format("#%06X", RGB_MASK and color.toArgb())
168
168
  tags.add("<font color=\"$hexColor\">" to "</font>")
169
169
  }
170
170
 
171
171
  spanStyle.fontSize.takeIf { it != TextUnit.Unspecified }?.let { fontSize ->
172
- val emSize = fontSize.value / 16f
172
+ val emSize = fontSize.value / DEFAULT_FONT_SIZE_SP
173
173
  tags.add("<span style=\"font-size: ${emSize}em;\">" to "</span>")
174
174
  }
175
175
 
@@ -183,7 +183,7 @@ private fun getHtmlTagsForSpanStyle(spanStyle: SpanStyle): List<Pair<String, Str
183
183
  }
184
184
 
185
185
  spanStyle.background.takeIf { it != Color.Unspecified }?.let { bgColor ->
186
- val hexBgColor = String.format("#%06X", 0xFFFFFF and bgColor.toArgb())
186
+ val hexBgColor = String.format("#%06X", RGB_MASK and bgColor.toArgb())
187
187
  tags.add("<span style=\"background-color: $hexBgColor;\">" to "</span>")
188
188
  }
189
189
 
@@ -215,3 +215,7 @@ private data class TagInfo(
215
215
  val end: Int,
216
216
  val closeTag: String,
217
217
  )
218
+
219
+ private const val IMAGE_LOAD_TIMEOUT_MS = 5_000L
220
+ private const val RGB_MASK = 0xFFFFFF
221
+ private const val DEFAULT_FONT_SIZE_SP = 16f
@@ -74,7 +74,7 @@ private fun buildTypography(
74
74
  @Throws(PaymentSheetAppearanceException::class)
75
75
  private fun colorFromHex(hexString: String?): Int? =
76
76
  hexString?.trim()?.replace("#", "")?.let {
77
- if (it.length == 6 || it.length == 8) {
77
+ if (it.length == HEX_COLOR_LENGTH_RGB || it.length == HEX_COLOR_LENGTH_ARGB) {
78
78
  "#$it".toColorInt()
79
79
  } else {
80
80
  throw PaymentSheetAppearanceException(
@@ -474,7 +474,9 @@ private fun buildEmbeddedAppearance(
474
474
  }
475
475
 
476
476
  else -> {
477
- System.err.println("WARN: Unsupported embedded payment element row style received: $styleString. Falling back to default.")
477
+ System.err.println(
478
+ "WARN: Unsupported embedded payment element row style received: $styleString. Falling back to default."
479
+ )
478
480
  }
479
481
  }
480
482
  return embeddedBuilder.build()
@@ -554,7 +556,8 @@ internal fun getFontResId(
554
556
  )
555
557
  if (Regex("[^a-z0-9]").containsMatchIn(fontFileName)) {
556
558
  throw PaymentSheetAppearanceException(
557
- "$fontErrorPrefix appearance.font.$key should only contain lowercase alphanumeric characters on Android, but received '$fontFileName'. This value must match the filename in android/app/src/main/res/font",
559
+ "$fontErrorPrefix appearance.font.$key should only contain lowercase alphanumeric characters on Android," +
560
+ " but received '$fontFileName'. This value must match the filename in android/app/src/main/res/font",
558
561
  )
559
562
  }
560
563
 
@@ -567,6 +570,9 @@ internal fun getFontResId(
567
570
  }
568
571
  }
569
572
 
573
+ private const val HEX_COLOR_LENGTH_RGB = 6
574
+ private const val HEX_COLOR_LENGTH_ARGB = 8
575
+
570
576
  private class PaymentSheetAppearanceKeys {
571
577
  companion object {
572
578
  const val COLORS = "colors"
@@ -39,8 +39,10 @@ import com.reactnativestripesdk.utils.mapFromPaymentMethod
39
39
  import com.reactnativestripesdk.utils.mapToPreferredNetworks
40
40
  import com.reactnativestripesdk.utils.parseCustomPaymentMethods
41
41
  import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
42
+ import com.stripe.android.checkout.Checkout
42
43
  import com.stripe.android.core.reactnative.ReactNativeSdkInternal
43
44
  import com.stripe.android.model.PaymentMethod
45
+ import com.stripe.android.paymentelement.CheckoutSessionPreview
44
46
  import com.stripe.android.paymentelement.ConfirmCustomPaymentMethodCallback
45
47
  import com.stripe.android.paymentelement.CreateIntentWithConfirmationTokenCallback
46
48
  import com.stripe.android.paymentelement.CustomPaymentMethodResult
@@ -68,11 +70,13 @@ import kotlin.coroutines.resume
68
70
  ReactNativeSdkInternal::class,
69
71
  ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class,
70
72
  CardFundingFilteringPrivatePreview::class,
73
+ CheckoutSessionPreview::class,
71
74
  )
72
75
  class PaymentSheetManager(
73
76
  context: ReactApplicationContext,
74
77
  private val arguments: ReadableMap,
75
78
  private val initPromise: Promise,
79
+ private val checkoutInstances: Map<String, Checkout>,
76
80
  ) : StripeUIManager(context),
77
81
  ConfirmCustomPaymentMethodCallback {
78
82
  private var paymentSheet: PaymentSheet? = null
@@ -80,6 +84,7 @@ class PaymentSheetManager(
80
84
  private var paymentIntentClientSecret: String? = null
81
85
  private var setupIntentClientSecret: String? = null
82
86
  private var intentConfiguration: PaymentSheet.IntentConfiguration? = null
87
+ private var checkoutSessionKey: String? = null
83
88
  private lateinit var paymentSheetConfiguration: PaymentSheet.Configuration
84
89
  private var confirmPromise: Promise? = null
85
90
  private var paymentSheetTimedOut = false
@@ -97,6 +102,7 @@ class PaymentSheetManager(
97
102
  super.onDestroy()
98
103
  flowController = null
99
104
  paymentSheet = null
105
+ checkoutSessionKey = null
100
106
  }
101
107
 
102
108
  fun configure(
@@ -110,6 +116,10 @@ class PaymentSheetManager(
110
116
  )
111
117
  return
112
118
  }
119
+ if (!resolveCheckoutSessionOrReturn(args, promise)) {
120
+ return
121
+ }
122
+
113
123
  val primaryButtonLabel = args.getString("primaryButtonLabel")
114
124
  val googlePayConfig = buildGooglePayConfig(args.getMap("googlePay"))
115
125
  val linkConfig = buildLinkConfig(args.getMap("link"))
@@ -121,31 +131,23 @@ class PaymentSheetManager(
121
131
  args.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
122
132
  val opensCardScannerAutomatically =
123
133
  args.getBooleanOr("opensCardScannerAutomatically", false)
134
+
124
135
  paymentIntentClientSecret = args.getString("paymentIntentClientSecret").orEmpty()
125
136
  setupIntentClientSecret = args.getString("setupIntentClientSecret").orEmpty()
126
137
  intentConfiguration =
127
- try {
138
+ resolvePaymentSheetValue(promise) {
128
139
  buildIntentConfiguration(args.getMap("intentConfiguration"))
129
- } catch (error: PaymentSheetException) {
130
- promise.resolve(createError(ErrorType.Failed.toString(), error))
131
- return
132
- }
140
+ }.getOrElse { return }
133
141
 
134
142
  val appearance =
135
- try {
143
+ resolveAppearanceValue(promise) {
136
144
  buildPaymentSheetAppearance(args.getMap("appearance"), context)
137
- } catch (error: PaymentSheetAppearanceException) {
138
- promise.resolve(createError(ErrorType.Failed.toString(), error))
139
- return
140
- }
145
+ }.getOrElse { return }
141
146
 
142
147
  val customerConfiguration =
143
- try {
148
+ resolvePaymentSheetValue(promise) {
144
149
  buildCustomerConfiguration(args)
145
- } catch (error: PaymentSheetException) {
146
- promise.resolve(createError(ErrorType.Failed.toString(), error))
147
- return
148
- }
150
+ }.getOrElse { return }
149
151
 
150
152
  val shippingDetails =
151
153
  args.getMap("defaultShippingDetails")?.let {
@@ -185,19 +187,64 @@ class PaymentSheetManager(
185
187
  mapToTermsDisplay(args)?.let { configurationBuilder.termsDisplay(it) }
186
188
 
187
189
  paymentSheetConfiguration = configurationBuilder.build()
190
+ configureMode(args, promise)
191
+ }
192
+
193
+ private fun resolveCheckoutSessionOrReturn(
194
+ args: ReadableMap,
195
+ promise: Promise,
196
+ ): Boolean {
197
+ checkoutSessionKey = args.getMap("checkout")?.getString("sessionKey")
198
+ val checkoutSessionKey = checkoutSessionKey ?: return true
199
+ checkoutInstances[checkoutSessionKey] ?: run {
200
+ promise.resolve(
201
+ createError(ErrorType.Failed.toString(), "Checkout session not found."),
202
+ )
203
+ return false
204
+ }
205
+ return true
206
+ }
207
+
208
+ private inline fun <T> resolvePaymentSheetValue(
209
+ promise: Promise,
210
+ builder: () -> T,
211
+ ): Result<T> =
212
+ try {
213
+ Result.success(builder())
214
+ } catch (error: PaymentSheetException) {
215
+ promise.resolve(createError(ErrorType.Failed.toString(), error))
216
+ Result.failure(error)
217
+ }
218
+
219
+ private inline fun <T> resolveAppearanceValue(
220
+ promise: Promise,
221
+ builder: () -> T,
222
+ ): Result<T> =
223
+ try {
224
+ Result.success(builder())
225
+ } catch (error: PaymentSheetAppearanceException) {
226
+ promise.resolve(createError(ErrorType.Failed.toString(), error))
227
+ Result.failure(error)
228
+ }
229
+
230
+ private fun configureMode(
231
+ args: ReadableMap,
232
+ promise: Promise,
233
+ ) {
188
234
  if (args.getBooleanOr("customFlow", false)) {
189
235
  lastConfigureWasCustomFlow = true
190
236
  if (flowController == null) {
191
237
  initFlowController(args, promise)
192
238
  }
193
239
  configureFlowController(promise)
194
- } else {
195
- lastConfigureWasCustomFlow = false
196
- if (paymentSheet == null) {
197
- initPaymentSheet(args, promise)
198
- }
199
- promise.resolve(Arguments.createMap())
240
+ return
241
+ }
242
+
243
+ lastConfigureWasCustomFlow = false
244
+ if (paymentSheet == null) {
245
+ initPaymentSheet(args, promise)
200
246
  }
247
+ promise.resolve(Arguments.createMap())
201
248
  }
202
249
 
203
250
  private fun initPaymentSheet(
@@ -391,7 +438,10 @@ class PaymentSheetManager(
391
438
  override fun onPresent() {
392
439
  keepJsAwake = KeepJsAwakeTask(context).apply { start() }
393
440
  if (lastConfigureWasCustomFlow == false) {
394
- if (!paymentIntentClientSecret.isNullOrEmpty()) {
441
+ val checkout = getCheckoutInstanceOrResolveError(promise)
442
+ if (checkout != null) {
443
+ paymentSheet?.presentWithCheckout(checkout, paymentSheetConfiguration)
444
+ } else if (!paymentIntentClientSecret.isNullOrEmpty()) {
395
445
  paymentSheet?.presentWithPaymentIntent(
396
446
  paymentIntentClientSecret!!,
397
447
  paymentSheetConfiguration,
@@ -423,7 +473,11 @@ class PaymentSheetManager(
423
473
  activity: Activity,
424
474
  savedInstanceState: Bundle?,
425
475
  ) {
426
- paymentSheetActivity = activity
476
+ if (activity.javaClass.name == PAYMENT_SHEET_ACTIVITY ||
477
+ activity.javaClass.name == PAYMENT_OPTIONS_ACTIVITY
478
+ ) {
479
+ paymentSheetActivity = activity
480
+ }
427
481
  }
428
482
 
429
483
  override fun onActivityStarted(activity: Activity) {}
@@ -441,8 +495,12 @@ class PaymentSheetManager(
441
495
  }
442
496
 
443
497
  override fun onActivityDestroyed(activity: Activity) {
444
- paymentSheetActivity = null
445
- context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
498
+ if (activity.javaClass.name == PAYMENT_SHEET_ACTIVITY ||
499
+ activity.javaClass.name == PAYMENT_OPTIONS_ACTIVITY
500
+ ) {
501
+ paymentSheetActivity = null
502
+ context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
503
+ }
446
504
  }
447
505
  }
448
506
 
@@ -475,7 +533,14 @@ class PaymentSheetManager(
475
533
  handleFlowControllerConfigured(success, error, promise, flowController)
476
534
  }
477
535
 
478
- if (!paymentIntentClientSecret.isNullOrEmpty()) {
536
+ val checkout = getCheckoutInstanceOrResolveError(promise)
537
+ if (checkout != null) {
538
+ flowController?.configureWithCheckout(
539
+ checkout = checkout,
540
+ configuration = paymentSheetConfiguration,
541
+ callback = onFlowControllerConfigure,
542
+ )
543
+ } else if (!paymentIntentClientSecret.isNullOrEmpty()) {
479
544
  flowController?.configureWithPaymentIntent(
480
545
  paymentIntentClientSecret = paymentIntentClientSecret!!,
481
546
  configuration = paymentSheetConfiguration,
@@ -504,6 +569,14 @@ class PaymentSheetManager(
504
569
  }
505
570
  }
506
571
 
572
+ private fun getCheckoutInstanceOrResolveError(promise: Promise?): Checkout? {
573
+ val checkoutSessionKey = checkoutSessionKey ?: return null
574
+ return checkoutInstances[checkoutSessionKey] ?: run {
575
+ promise?.resolve(createError(ErrorType.Failed.toString(), "Checkout session not found."))
576
+ null
577
+ }
578
+ }
579
+
507
580
  private fun resolvePresentPromise(value: Any?) {
508
581
  keepJsAwake?.stop()
509
582
  promise?.resolve(value)
@@ -550,7 +623,7 @@ class PaymentSheetManager(
550
623
  CoroutineScope(Dispatchers.Main).launch {
551
624
  try {
552
625
  // Give the CustomPaymentMethodActivity a moment to fully initialize
553
- delay(100)
626
+ delay(CUSTOM_PAYMENT_METHOD_INIT_DELAY_MS)
554
627
 
555
628
  // Emit event so JS can show the Alert and eventually respond via `customPaymentMethodResultCallback`.
556
629
  stripeSdkModule.eventEmitter.emitOnCustomPaymentMethodConfirmHandlerCallback(
@@ -596,6 +669,8 @@ class PaymentSheetManager(
596
669
  PaymentSheetErrorType.Failed.toString(),
597
670
  "No payment sheet has been initialized yet. You must call `initPaymentSheet` before `presentPaymentSheet`.",
598
671
  )
672
+
673
+ private const val CUSTOM_PAYMENT_METHOD_INIT_DELAY_MS = 100L
599
674
  }
600
675
  }
601
676
 
@@ -687,7 +762,7 @@ fun getBase64FromBitmap(bitmap: Bitmap?): String? {
687
762
  return null
688
763
  }
689
764
  val stream = ByteArrayOutputStream()
690
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
765
+ bitmap.compress(Bitmap.CompressFormat.PNG, BITMAP_COMPRESS_QUALITY, stream)
691
766
  val imageBytes: ByteArray = stream.toByteArray()
692
767
  return Base64.encodeToString(imageBytes, Base64.DEFAULT)
693
768
  }
@@ -716,7 +791,9 @@ internal fun mapToCaptureMethod(type: String?): PaymentSheet.IntentConfiguration
716
791
  }
717
792
 
718
793
  @OptIn(PaymentMethodOptionsSetupFutureUsagePreview::class)
719
- internal fun mapToPaymentMethodOptions(options: ReadableMap?): PaymentSheet.IntentConfiguration.Mode.Payment.PaymentMethodOptions? {
794
+ internal fun mapToPaymentMethodOptions(
795
+ options: ReadableMap?
796
+ ): PaymentSheet.IntentConfiguration.Mode.Payment.PaymentMethodOptions? {
720
797
  val sfuMap = options?.getMap("setupFutureUsageValues")
721
798
  val paymentMethodToSfuMap = mutableMapOf<PaymentMethod.Type, PaymentSheet.IntentConfiguration.SetupFutureUse>()
722
799
  sfuMap?.forEachKey { code ->
@@ -775,3 +852,7 @@ internal fun handleFlowControllerConfigured(
775
852
  promise.resolve(Arguments.createMap())
776
853
  }
777
854
  }
855
+
856
+ private const val BITMAP_COMPRESS_QUALITY = 100
857
+ private const val PAYMENT_SHEET_ACTIVITY = "com.stripe.android.paymentsheet.PaymentSheetActivity"
858
+ private const val PAYMENT_OPTIONS_ACTIVITY = "com.stripe.android.paymentsheet.PaymentOptionsActivity"