@stripe/stripe-react-native 0.64.0 → 0.64.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 (242) hide show
  1. package/README.md +2 -2
  2. package/android/build.gradle +2 -2
  3. package/android/detekt/detekt-baseline.xml +81 -0
  4. package/android/detekt/detekt.gradle +45 -0
  5. package/android/detekt/detekt.yml +722 -0
  6. package/android/gradle.properties +4 -4
  7. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormView.kt +3 -1
  8. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormViewManager.kt +2 -1
  9. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +5 -1
  10. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementView.kt +26 -0
  11. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +42 -0
  12. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +105 -49
  13. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +72 -12
  14. package/android/src/main/java/com/reactnativestripesdk/FinancialConnectionsSheetManager.kt +8 -4
  15. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonManager.kt +2 -1
  16. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonView.kt +26 -11
  17. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +2 -1
  18. package/android/src/main/java/com/reactnativestripesdk/NavigationBarView.kt +14 -5
  19. package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +6 -2
  20. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherManager.kt +2 -2
  21. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +2 -1
  22. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +7 -4
  23. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +2 -1
  24. package/android/src/main/java/com/reactnativestripesdk/PaymentOptionDisplayDataMapper.kt +8 -4
  25. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +9 -3
  26. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +110 -29
  27. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +250 -12
  28. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
  29. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +2 -1
  30. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +3 -1
  31. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +6 -2
  32. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerAdapter.kt +3 -1
  33. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +2 -1
  34. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +2 -1
  35. package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutAddressUpdate.kt +45 -0
  36. package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutMappers.kt +101 -0
  37. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +4 -2
  38. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +5 -1
  39. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +29 -17
  40. package/android/src/main/java/com/reactnativestripesdk/utils/PostalCodeUtilities.kt +2 -1
  41. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +6 -0
  42. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +2 -0
  43. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerDelegate.java +35 -0
  44. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerInterface.java +18 -0
  45. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +44 -0
  46. package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt +3 -3
  47. package/android/src/test/java/com/reactnativestripesdk/mappers/MappersTest.kt +60 -0
  48. package/android/src/test/java/com/reactnativestripesdk/mappers/OnrampMappersTest.kt +38 -0
  49. package/android/src/test/java/com/reactnativestripesdk/mappers/PaymentOptionDisplayDataMapperTest.kt +9 -4
  50. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutMappersTest.kt +89 -0
  51. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutTestFixtures.java +49 -0
  52. package/ios/ConnectAccountOnboarding/ConnectAccountOnboardingViewController.swift +6 -8
  53. package/ios/CurrencySelectorElementManager.m +9 -0
  54. package/ios/CurrencySelectorElementManager.swift +12 -0
  55. package/ios/CurrencySelectorElementView.swift +24 -0
  56. package/ios/Mappers+Checkout.swift +193 -0
  57. package/ios/Mappers.swift +0 -5
  58. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +16 -2
  59. package/ios/NewArch/StripeCurrencySelectorElementComponentView.h +10 -0
  60. package/ios/NewArch/StripeCurrencySelectorElementComponentView.mm +75 -0
  61. package/ios/PaymentMethodMessagingElementConfig.swift +6 -3
  62. package/ios/PaymentMethodMessagingElementView.swift +19 -0
  63. package/ios/StripeSdk.mm +123 -0
  64. package/ios/StripeSdkImpl+Checkout.swift +308 -0
  65. package/ios/StripeSdkImpl+Embedded.swift +108 -27
  66. package/ios/StripeSdkImpl+PaymentSheet.swift +18 -2
  67. package/ios/StripeSdkImpl.swift +3 -93
  68. package/jest/mock.js +14 -1
  69. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  70. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  71. package/lib/commonjs/components/AddressSheet.js +1 -1
  72. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  73. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  74. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  75. package/lib/commonjs/components/CardField.js +1 -1
  76. package/lib/commonjs/components/CardField.js.map +1 -1
  77. package/lib/commonjs/components/CardForm.js +1 -1
  78. package/lib/commonjs/components/CardForm.js.map +1 -1
  79. package/lib/commonjs/components/CurrencySelectorElement.js +2 -0
  80. package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -0
  81. package/lib/commonjs/components/PaymentMethodMessagingElement.js +2 -0
  82. package/lib/commonjs/components/PaymentMethodMessagingElement.js.map +1 -0
  83. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  84. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  85. package/lib/commonjs/components/StripeContainer.js +1 -1
  86. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  87. package/lib/commonjs/connect/Components.js +1 -1
  88. package/lib/commonjs/connect/Components.js.map +1 -1
  89. package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
  90. package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
  91. package/lib/commonjs/connect/EmbeddedComponent.js +1 -1
  92. package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
  93. package/lib/commonjs/connect/ModalCloseButton.js +1 -1
  94. package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
  95. package/lib/commonjs/connect/NavigationBar.js +1 -1
  96. package/lib/commonjs/connect/NavigationBar.js.map +1 -1
  97. package/lib/commonjs/events.js.map +1 -1
  98. package/lib/commonjs/functions.js +1 -1
  99. package/lib/commonjs/functions.js.map +1 -1
  100. package/lib/commonjs/helpers.js +1 -1
  101. package/lib/commonjs/hooks/useCheckout.js +2 -0
  102. package/lib/commonjs/hooks/useCheckout.js.map +1 -0
  103. package/lib/commonjs/hooks/useOnramp.js +1 -1
  104. package/lib/commonjs/hooks/useOnramp.js.map +1 -1
  105. package/lib/commonjs/index.js +1 -1
  106. package/lib/commonjs/index.js.map +1 -1
  107. package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
  108. package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
  109. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  110. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
  111. package/lib/commonjs/specs/NativeCardField.js +1 -1
  112. package/lib/commonjs/specs/NativeCardField.js.map +1 -1
  113. package/lib/commonjs/specs/NativeCardForm.js +1 -1
  114. package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
  115. package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
  116. package/lib/commonjs/specs/NativeCurrencySelectorElement.js +2 -0
  117. package/lib/commonjs/specs/NativeCurrencySelectorElement.js.map +1 -0
  118. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
  119. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  120. package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
  121. package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
  122. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +1 -1
  123. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js.map +1 -1
  124. package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
  125. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  126. package/lib/commonjs/types/Checkout.js +2 -0
  127. package/lib/commonjs/types/Checkout.js.map +1 -0
  128. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  129. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  130. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  131. package/lib/module/components/AddToWalletButton.js +1 -1
  132. package/lib/module/components/AddToWalletButton.js.map +1 -1
  133. package/lib/module/components/AddressSheet.js +1 -1
  134. package/lib/module/components/AddressSheet.js.map +1 -1
  135. package/lib/module/components/AuBECSDebitForm.js +1 -1
  136. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  137. package/lib/module/components/CardField.js +1 -1
  138. package/lib/module/components/CardField.js.map +1 -1
  139. package/lib/module/components/CardForm.js +1 -1
  140. package/lib/module/components/CardForm.js.map +1 -1
  141. package/lib/module/components/CurrencySelectorElement.js +2 -0
  142. package/lib/module/components/CurrencySelectorElement.js.map +1 -0
  143. package/lib/module/components/PaymentMethodMessagingElement.js +2 -0
  144. package/lib/module/components/PaymentMethodMessagingElement.js.map +1 -0
  145. package/lib/module/components/PlatformPayButton.js +1 -1
  146. package/lib/module/components/PlatformPayButton.js.map +1 -1
  147. package/lib/module/components/StripeContainer.js +1 -1
  148. package/lib/module/components/StripeContainer.js.map +1 -1
  149. package/lib/module/connect/Components.js +1 -1
  150. package/lib/module/connect/Components.js.map +1 -1
  151. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  152. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  153. package/lib/module/connect/EmbeddedComponent.js +1 -1
  154. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  155. package/lib/module/connect/ModalCloseButton.js +1 -1
  156. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  157. package/lib/module/connect/NavigationBar.js +1 -1
  158. package/lib/module/connect/NavigationBar.js.map +1 -1
  159. package/lib/module/events.js.map +1 -1
  160. package/lib/module/functions.js +1 -1
  161. package/lib/module/functions.js.map +1 -1
  162. package/lib/module/helpers.js +1 -1
  163. package/lib/module/hooks/useCheckout.js +2 -0
  164. package/lib/module/hooks/useCheckout.js.map +1 -0
  165. package/lib/module/hooks/useOnramp.js +1 -1
  166. package/lib/module/hooks/useOnramp.js.map +1 -1
  167. package/lib/module/index.js +1 -1
  168. package/lib/module/index.js.map +1 -1
  169. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  170. package/lib/module/specs/NativeAddressSheet.js +1 -1
  171. package/lib/module/specs/NativeApplePayButton.js +1 -1
  172. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  173. package/lib/module/specs/NativeCardField.js +1 -1
  174. package/lib/module/specs/NativeCardField.js.map +1 -1
  175. package/lib/module/specs/NativeCardForm.js +1 -1
  176. package/lib/module/specs/NativeCardForm.js.map +1 -1
  177. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  178. package/lib/module/specs/NativeCurrencySelectorElement.js +2 -0
  179. package/lib/module/specs/NativeCurrencySelectorElement.js.map +1 -0
  180. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  181. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  182. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  183. package/lib/module/specs/NativeNavigationBar.js +1 -1
  184. package/lib/module/specs/NativePaymentMethodMessagingElement.js +1 -1
  185. package/lib/module/specs/NativePaymentMethodMessagingElement.js.map +1 -1
  186. package/lib/module/specs/NativeStripeContainer.js +1 -1
  187. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  188. package/lib/module/types/Checkout.js +2 -0
  189. package/lib/module/types/Checkout.js.map +1 -0
  190. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  191. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  192. package/lib/module/types/PaymentSheet.js.map +1 -1
  193. package/lib/typescript/src/components/CurrencySelectorElement.d.ts +62 -0
  194. package/lib/typescript/src/components/CurrencySelectorElement.d.ts.map +1 -0
  195. package/lib/typescript/src/components/PaymentMethodMessagingElement.d.ts +41 -0
  196. package/lib/typescript/src/components/PaymentMethodMessagingElement.d.ts.map +1 -0
  197. package/lib/typescript/src/events.d.ts +11 -0
  198. package/lib/typescript/src/events.d.ts.map +1 -1
  199. package/lib/typescript/src/functions.d.ts.map +1 -1
  200. package/lib/typescript/src/hooks/useCheckout.d.ts +21 -0
  201. package/lib/typescript/src/hooks/useCheckout.d.ts.map +1 -0
  202. package/lib/typescript/src/hooks/useOnramp.d.ts +1 -0
  203. package/lib/typescript/src/hooks/useOnramp.d.ts.map +1 -1
  204. package/lib/typescript/src/index.d.ts +3 -0
  205. package/lib/typescript/src/index.d.ts.map +1 -1
  206. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts +25 -0
  207. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts.map +1 -0
  208. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +5 -1
  209. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -1
  210. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts +1 -6
  211. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts.map +1 -1
  212. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +16 -1
  213. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  214. package/lib/typescript/src/types/Checkout.d.ts +336 -0
  215. package/lib/typescript/src/types/Checkout.d.ts.map +1 -0
  216. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +36 -1
  217. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  218. package/lib/typescript/src/types/PaymentMethod.d.ts +1 -5
  219. package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
  220. package/lib/typescript/src/types/PaymentSheet.d.ts +22 -6
  221. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  222. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts +16 -1
  223. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts.map +1 -1
  224. package/package.json +21 -7
  225. package/src/components/CurrencySelectorElement.tsx +95 -0
  226. package/src/components/PaymentMethodMessagingElement.tsx +109 -0
  227. package/src/events.ts +11 -0
  228. package/src/functions.ts +30 -1
  229. package/src/hooks/useCheckout.tsx +207 -0
  230. package/src/hooks/useOnramp.tsx +9 -3
  231. package/src/index.tsx +4 -0
  232. package/src/specs/NativeCurrencySelectorElement.ts +35 -0
  233. package/src/specs/NativeEmbeddedPaymentElement.ts +12 -2
  234. package/src/specs/NativePaymentMethodMessagingElement.ts +0 -7
  235. package/src/specs/NativeStripeSdkModule.ts +58 -1
  236. package/src/types/Checkout.ts +377 -0
  237. package/src/types/EmbeddedPaymentElement.tsx +117 -26
  238. package/src/types/PaymentMethod.ts +0 -6
  239. package/src/types/PaymentSheet.ts +29 -6
  240. package/src/types/components/PaymentMethodMessagingElementComponent.tsx +17 -1
  241. package/stripe-react-native.podspec +8 -8
  242. package/android/spotless.gradle +0 -19
@@ -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
  }
@@ -353,7 +354,6 @@ class PaymentLauncherManager(
353
354
  StripeIntent.NextActionType.AlipayRedirect,
354
355
  StripeIntent.NextActionType.BlikAuthorize,
355
356
  StripeIntent.NextActionType.WeChatPayRedirect,
356
- StripeIntent.NextActionType.UpiAwaitNotification,
357
357
  StripeIntent.NextActionType.CashAppRedirect,
358
358
  StripeIntent.NextActionType.SwishRedirect,
359
359
  StripeIntent.NextActionType.DisplayPromptPayDetails,
@@ -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,14 +77,13 @@ private fun parseFont(
77
77
  "family",
78
78
  context,
79
79
  )
80
- val scaleFactor = map.getDoubleOrNull("scale") ?: 1.0
81
- val textSize: Double = 16 * scaleFactor
80
+ val size = map.getDoubleOrNull("size") ?: DEFAULT_FONT_SIZE
82
81
 
83
82
  val font =
84
83
  PaymentMethodMessagingElement.Appearance
85
84
  .Font()
86
85
  .fontFamily(fontFamily)
87
- .fontSizeSp(textSize.toFloat())
86
+ .fontSizeSp(size.toFloat())
88
87
 
89
88
  return font
90
89
  }
@@ -137,7 +136,7 @@ private fun dynamicColorFromParams(
137
136
  @Throws(PaymentMethodMessagingElementAppearanceException::class)
138
137
  private fun colorFromHex(hexString: String?): Int? =
139
138
  hexString?.trim()?.replace("#", "")?.let {
140
- if (it.length == 6 || it.length == 8) {
139
+ if (it.length == HEX_COLOR_LENGTH_RGB || it.length == HEX_COLOR_LENGTH_ARGB) {
141
140
  "#$it".toColorInt()
142
141
  } else {
143
142
  throw PaymentMethodMessagingElementAppearanceException(
@@ -145,3 +144,7 @@ private fun colorFromHex(hexString: String?): Int? =
145
144
  )
146
145
  }
147
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"