@stripe/stripe-react-native 0.65.0 → 0.66.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 (239) hide show
  1. package/README.md +2 -2
  2. package/android/detekt/detekt-baseline.xml +1 -76
  3. package/android/gradle.properties +4 -4
  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 +56 -58
  7. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementEvent.kt +26 -0
  8. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementView.kt +139 -0
  9. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +59 -0
  10. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +105 -49
  11. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +72 -12
  12. package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +4 -0
  13. package/android/src/main/java/com/reactnativestripesdk/FinancialConnectionsSheetManager.kt +8 -4
  14. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonManager.kt +2 -1
  15. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonView.kt +26 -11
  16. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +2 -1
  17. package/android/src/main/java/com/reactnativestripesdk/NavigationBarView.kt +14 -5
  18. package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +6 -2
  19. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherManager.kt +2 -1
  20. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +2 -1
  21. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +6 -2
  22. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +2 -1
  23. package/android/src/main/java/com/reactnativestripesdk/PaymentOptionDisplayDataMapper.kt +8 -4
  24. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +9 -3
  25. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +118 -48
  26. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +1 -0
  27. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +281 -46
  28. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +2 -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 +8 -18
  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 +127 -0
  37. package/android/src/main/java/com/reactnativestripesdk/utils/DefaultActivityLifecycleCallbacks.kt +41 -0
  38. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +4 -2
  39. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +5 -1
  40. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +29 -13
  41. package/android/src/main/java/com/reactnativestripesdk/utils/PostalCodeUtilities.kt +2 -1
  42. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +6 -0
  43. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +2 -0
  44. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerDelegate.java +35 -0
  45. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerInterface.java +18 -0
  46. package/android/src/oldarch/java/com/reactnativestripesdk/NativeOnrampSdkModuleSpec.java +17 -3
  47. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +13 -1
  48. package/android/src/onramp/java/com/reactnativestripesdk/OnrampMappers.kt +116 -0
  49. package/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +109 -1
  50. package/android/src/test/java/com/reactnativestripesdk/DrawableLoadingTest.kt +6 -2
  51. package/android/src/test/java/com/reactnativestripesdk/mappers/MappersTest.kt +60 -0
  52. package/android/src/test/java/com/reactnativestripesdk/mappers/OnrampMappersTest.kt +145 -0
  53. package/android/src/test/java/com/reactnativestripesdk/mappers/PaymentOptionDisplayDataMapperTest.kt +9 -4
  54. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutMappersTest.kt +98 -0
  55. package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutTestFixtures.java +57 -0
  56. package/ios/ConnectAccountOnboarding/ConnectAccountOnboardingViewController.swift +6 -8
  57. package/ios/CurrencySelectorElementManager.m +16 -0
  58. package/ios/CurrencySelectorElementView.swift +159 -0
  59. package/ios/EmbeddedPaymentElementView.swift +1 -1
  60. package/ios/Mappers+Checkout.swift +337 -0
  61. package/ios/Mappers.swift +90 -2
  62. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +16 -2
  63. package/ios/NewArch/StripeCurrencySelectorElementComponentView.h +10 -0
  64. package/ios/NewArch/StripeCurrencySelectorElementComponentView.mm +89 -0
  65. package/ios/OldArch/StripeSdkEventEmitterCompat.h +1 -0
  66. package/ios/OldArch/StripeSdkEventEmitterCompat.m +6 -0
  67. package/ios/PaymentOptionDisplayData+ReactNative.swift +1 -1
  68. package/ios/PaymentSheetAppearance.swift +1 -1
  69. package/ios/StripeOnrampSdk.mm +19 -0
  70. package/ios/StripeSdk.mm +136 -0
  71. package/ios/StripeSdkEmitter.swift +1 -0
  72. package/ios/StripeSdkImpl+Checkout.swift +360 -0
  73. package/ios/StripeSdkImpl+CustomerSheet.swift +1 -1
  74. package/ios/StripeSdkImpl+Embedded.swift +108 -27
  75. package/ios/StripeSdkImpl+PaymentSheet.swift +18 -2
  76. package/ios/StripeSdkImpl.swift +89 -7
  77. package/jest/mock.js +13 -1
  78. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  79. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  80. package/lib/commonjs/components/AddressSheet.js +1 -1
  81. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  82. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  83. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  84. package/lib/commonjs/components/CardField.js +1 -1
  85. package/lib/commonjs/components/CardField.js.map +1 -1
  86. package/lib/commonjs/components/CardForm.js +1 -1
  87. package/lib/commonjs/components/CardForm.js.map +1 -1
  88. package/lib/commonjs/components/CurrencySelectorElement.js +2 -0
  89. package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -0
  90. package/lib/commonjs/components/PaymentMethodMessagingElement.js +1 -1
  91. package/lib/commonjs/components/PaymentMethodMessagingElement.js.map +1 -1
  92. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  93. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  94. package/lib/commonjs/components/StripeContainer.js +1 -1
  95. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  96. package/lib/commonjs/connect/Components.js +1 -1
  97. package/lib/commonjs/connect/Components.js.map +1 -1
  98. package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
  99. package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
  100. package/lib/commonjs/connect/EmbeddedComponent.js +1 -1
  101. package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
  102. package/lib/commonjs/connect/ModalCloseButton.js +1 -1
  103. package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
  104. package/lib/commonjs/connect/NavigationBar.js +1 -1
  105. package/lib/commonjs/connect/NavigationBar.js.map +1 -1
  106. package/lib/commonjs/events.js.map +1 -1
  107. package/lib/commonjs/functions.js +1 -1
  108. package/lib/commonjs/functions.js.map +1 -1
  109. package/lib/commonjs/helpers.js +1 -1
  110. package/lib/commonjs/hooks/useCheckout.js +1 -1
  111. package/lib/commonjs/hooks/useCheckout.js.map +1 -1
  112. package/lib/commonjs/hooks/useOnramp.js +1 -1
  113. package/lib/commonjs/hooks/useOnramp.js.map +1 -1
  114. package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
  115. package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
  116. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  117. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
  118. package/lib/commonjs/specs/NativeCardField.js +1 -1
  119. package/lib/commonjs/specs/NativeCardField.js.map +1 -1
  120. package/lib/commonjs/specs/NativeCardForm.js +1 -1
  121. package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
  122. package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
  123. package/lib/commonjs/specs/NativeCurrencySelectorElement.js +2 -0
  124. package/lib/commonjs/specs/NativeCurrencySelectorElement.js.map +1 -0
  125. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
  126. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  127. package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
  128. package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
  129. package/lib/commonjs/specs/NativeOnrampSdkModule.js.map +1 -1
  130. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +1 -1
  131. package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
  132. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  133. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  134. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  135. package/lib/module/components/AddToWalletButton.js +1 -1
  136. package/lib/module/components/AddToWalletButton.js.map +1 -1
  137. package/lib/module/components/AddressSheet.js +1 -1
  138. package/lib/module/components/AddressSheet.js.map +1 -1
  139. package/lib/module/components/AuBECSDebitForm.js +1 -1
  140. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  141. package/lib/module/components/CardField.js +1 -1
  142. package/lib/module/components/CardField.js.map +1 -1
  143. package/lib/module/components/CardForm.js +1 -1
  144. package/lib/module/components/CardForm.js.map +1 -1
  145. package/lib/module/components/CurrencySelectorElement.js +2 -0
  146. package/lib/module/components/CurrencySelectorElement.js.map +1 -0
  147. package/lib/module/components/PaymentMethodMessagingElement.js +1 -1
  148. package/lib/module/components/PaymentMethodMessagingElement.js.map +1 -1
  149. package/lib/module/components/PlatformPayButton.js +1 -1
  150. package/lib/module/components/PlatformPayButton.js.map +1 -1
  151. package/lib/module/components/StripeContainer.js +1 -1
  152. package/lib/module/components/StripeContainer.js.map +1 -1
  153. package/lib/module/connect/Components.js +1 -1
  154. package/lib/module/connect/Components.js.map +1 -1
  155. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  156. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  157. package/lib/module/connect/EmbeddedComponent.js +1 -1
  158. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  159. package/lib/module/connect/ModalCloseButton.js +1 -1
  160. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  161. package/lib/module/connect/NavigationBar.js +1 -1
  162. package/lib/module/connect/NavigationBar.js.map +1 -1
  163. package/lib/module/events.js.map +1 -1
  164. package/lib/module/functions.js +1 -1
  165. package/lib/module/functions.js.map +1 -1
  166. package/lib/module/helpers.js +1 -1
  167. package/lib/module/hooks/useCheckout.js +1 -1
  168. package/lib/module/hooks/useCheckout.js.map +1 -1
  169. package/lib/module/hooks/useOnramp.js +1 -1
  170. package/lib/module/hooks/useOnramp.js.map +1 -1
  171. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  172. package/lib/module/specs/NativeAddressSheet.js +1 -1
  173. package/lib/module/specs/NativeApplePayButton.js +1 -1
  174. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  175. package/lib/module/specs/NativeCardField.js +1 -1
  176. package/lib/module/specs/NativeCardField.js.map +1 -1
  177. package/lib/module/specs/NativeCardForm.js +1 -1
  178. package/lib/module/specs/NativeCardForm.js.map +1 -1
  179. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  180. package/lib/module/specs/NativeCurrencySelectorElement.js +2 -0
  181. package/lib/module/specs/NativeCurrencySelectorElement.js.map +1 -0
  182. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  183. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  184. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  185. package/lib/module/specs/NativeNavigationBar.js +1 -1
  186. package/lib/module/specs/NativeOnrampSdkModule.js.map +1 -1
  187. package/lib/module/specs/NativePaymentMethodMessagingElement.js +1 -1
  188. package/lib/module/specs/NativeStripeContainer.js +1 -1
  189. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  190. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  191. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  192. package/lib/typescript/src/components/CurrencySelectorElement.d.ts +62 -0
  193. package/lib/typescript/src/components/CurrencySelectorElement.d.ts.map +1 -0
  194. package/lib/typescript/src/components/PaymentMethodMessagingElement.d.ts +1 -1
  195. package/lib/typescript/src/components/PaymentMethodMessagingElement.d.ts.map +1 -1
  196. package/lib/typescript/src/events.d.ts +11 -0
  197. package/lib/typescript/src/events.d.ts.map +1 -1
  198. package/lib/typescript/src/functions.d.ts.map +1 -1
  199. package/lib/typescript/src/hooks/useCheckout.d.ts.map +1 -1
  200. package/lib/typescript/src/hooks/useOnramp.d.ts +22 -0
  201. package/lib/typescript/src/hooks/useOnramp.d.ts.map +1 -1
  202. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts +25 -0
  203. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts.map +1 -0
  204. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +5 -1
  205. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -1
  206. package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts +3 -0
  207. package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts.map +1 -1
  208. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +5 -2
  209. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  210. package/lib/typescript/src/types/Checkout.d.ts +268 -86
  211. package/lib/typescript/src/types/Checkout.d.ts.map +1 -1
  212. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +36 -1
  213. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  214. package/lib/typescript/src/types/Onramp.d.ts +94 -0
  215. package/lib/typescript/src/types/Onramp.d.ts.map +1 -1
  216. package/package.json +16 -4
  217. package/src/components/CurrencySelectorElement.tsx +95 -0
  218. package/src/components/PaymentMethodMessagingElement.tsx +54 -52
  219. package/src/events.ts +11 -0
  220. package/src/functions.ts +30 -1
  221. package/src/hooks/useCheckout.tsx +129 -74
  222. package/src/hooks/useOnramp.tsx +44 -0
  223. package/src/specs/NativeCurrencySelectorElement.ts +35 -0
  224. package/src/specs/NativeEmbeddedPaymentElement.ts +12 -2
  225. package/src/specs/NativeOnrampSdkModule.ts +5 -0
  226. package/src/specs/NativeStripeSdkModule.ts +16 -2
  227. package/src/types/Checkout.ts +291 -86
  228. package/src/types/EmbeddedPaymentElement.tsx +117 -26
  229. package/src/types/Onramp.ts +109 -0
  230. package/stripe-react-native.podspec +1 -1
  231. package/android/.idea/AndroidProjectSystem.xml +0 -6
  232. package/android/.idea/caches/deviceStreaming.xml +0 -835
  233. package/android/.idea/compiler.xml +0 -6
  234. package/android/.idea/gradle.xml +0 -17
  235. package/android/.idea/migrations.xml +0 -10
  236. package/android/.idea/misc.xml +0 -10
  237. package/android/.idea/runConfigurations.xml +0 -17
  238. package/android/.idea/vcs.xml +0 -6
  239. package/android/local.properties +0 -8
@@ -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"
@@ -2,7 +2,6 @@ package com.reactnativestripesdk
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.app.Activity
5
- import android.app.Application
6
5
  import android.content.Intent
7
6
  import android.graphics.Bitmap
8
7
  import android.graphics.Canvas
@@ -21,6 +20,7 @@ import com.facebook.react.bridge.ReactApplicationContext
21
20
  import com.facebook.react.bridge.ReadableMap
22
21
  import com.facebook.react.bridge.WritableMap
23
22
  import com.reactnativestripesdk.addresssheet.AddressSheetView
23
+ import com.reactnativestripesdk.utils.DefaultActivityLifecycleCallbacks
24
24
  import com.reactnativestripesdk.utils.ErrorType
25
25
  import com.reactnativestripesdk.utils.KeepJsAwakeTask
26
26
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
@@ -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
@@ -61,18 +63,19 @@ import kotlinx.coroutines.launch
61
63
  import kotlinx.coroutines.suspendCancellableCoroutine
62
64
  import kotlinx.coroutines.withTimeoutOrNull
63
65
  import java.io.ByteArrayOutputStream
64
- import kotlin.Exception
65
66
  import kotlin.coroutines.resume
66
67
 
67
68
  @OptIn(
68
69
  ReactNativeSdkInternal::class,
69
70
  ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class,
70
71
  CardFundingFilteringPrivatePreview::class,
72
+ CheckoutSessionPreview::class,
71
73
  )
72
74
  class PaymentSheetManager(
73
75
  context: ReactApplicationContext,
74
76
  private val arguments: ReadableMap,
75
77
  private val initPromise: Promise,
78
+ private val checkoutInstances: Map<String, Checkout>,
76
79
  ) : StripeUIManager(context),
77
80
  ConfirmCustomPaymentMethodCallback {
78
81
  private var paymentSheet: PaymentSheet? = null
@@ -80,6 +83,7 @@ class PaymentSheetManager(
80
83
  private var paymentIntentClientSecret: String? = null
81
84
  private var setupIntentClientSecret: String? = null
82
85
  private var intentConfiguration: PaymentSheet.IntentConfiguration? = null
86
+ private var checkoutSessionKey: String? = null
83
87
  private lateinit var paymentSheetConfiguration: PaymentSheet.Configuration
84
88
  private var confirmPromise: Promise? = null
85
89
  private var paymentSheetTimedOut = false
@@ -97,6 +101,7 @@ class PaymentSheetManager(
97
101
  super.onDestroy()
98
102
  flowController = null
99
103
  paymentSheet = null
104
+ checkoutSessionKey = null
100
105
  }
101
106
 
102
107
  fun configure(
@@ -110,6 +115,10 @@ class PaymentSheetManager(
110
115
  )
111
116
  return
112
117
  }
118
+ if (!resolveCheckoutSessionOrReturn(args, promise)) {
119
+ return
120
+ }
121
+
113
122
  val primaryButtonLabel = args.getString("primaryButtonLabel")
114
123
  val googlePayConfig = buildGooglePayConfig(args.getMap("googlePay"))
115
124
  val linkConfig = buildLinkConfig(args.getMap("link"))
@@ -121,31 +130,23 @@ class PaymentSheetManager(
121
130
  args.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
122
131
  val opensCardScannerAutomatically =
123
132
  args.getBooleanOr("opensCardScannerAutomatically", false)
133
+
124
134
  paymentIntentClientSecret = args.getString("paymentIntentClientSecret").orEmpty()
125
135
  setupIntentClientSecret = args.getString("setupIntentClientSecret").orEmpty()
126
136
  intentConfiguration =
127
- try {
137
+ resolvePaymentSheetValue(promise) {
128
138
  buildIntentConfiguration(args.getMap("intentConfiguration"))
129
- } catch (error: PaymentSheetException) {
130
- promise.resolve(createError(ErrorType.Failed.toString(), error))
131
- return
132
- }
139
+ }.getOrElse { return }
133
140
 
134
141
  val appearance =
135
- try {
142
+ resolveAppearanceValue(promise) {
136
143
  buildPaymentSheetAppearance(args.getMap("appearance"), context)
137
- } catch (error: PaymentSheetAppearanceException) {
138
- promise.resolve(createError(ErrorType.Failed.toString(), error))
139
- return
140
- }
144
+ }.getOrElse { return }
141
145
 
142
146
  val customerConfiguration =
143
- try {
147
+ resolvePaymentSheetValue(promise) {
144
148
  buildCustomerConfiguration(args)
145
- } catch (error: PaymentSheetException) {
146
- promise.resolve(createError(ErrorType.Failed.toString(), error))
147
- return
148
- }
149
+ }.getOrElse { return }
149
150
 
150
151
  val shippingDetails =
151
152
  args.getMap("defaultShippingDetails")?.let {
@@ -185,19 +186,64 @@ class PaymentSheetManager(
185
186
  mapToTermsDisplay(args)?.let { configurationBuilder.termsDisplay(it) }
186
187
 
187
188
  paymentSheetConfiguration = configurationBuilder.build()
189
+ configureMode(args, promise)
190
+ }
191
+
192
+ private fun resolveCheckoutSessionOrReturn(
193
+ args: ReadableMap,
194
+ promise: Promise,
195
+ ): Boolean {
196
+ checkoutSessionKey = args.getMap("checkout")?.getString("sessionKey")
197
+ val checkoutSessionKey = checkoutSessionKey ?: return true
198
+ checkoutInstances[checkoutSessionKey] ?: run {
199
+ promise.resolve(
200
+ createError(ErrorType.Failed.toString(), "Checkout session not found."),
201
+ )
202
+ return false
203
+ }
204
+ return true
205
+ }
206
+
207
+ private inline fun <T> resolvePaymentSheetValue(
208
+ promise: Promise,
209
+ builder: () -> T,
210
+ ): Result<T> =
211
+ try {
212
+ Result.success(builder())
213
+ } catch (error: PaymentSheetException) {
214
+ promise.resolve(createError(ErrorType.Failed.toString(), error))
215
+ Result.failure(error)
216
+ }
217
+
218
+ private inline fun <T> resolveAppearanceValue(
219
+ promise: Promise,
220
+ builder: () -> T,
221
+ ): Result<T> =
222
+ try {
223
+ Result.success(builder())
224
+ } catch (error: PaymentSheetAppearanceException) {
225
+ promise.resolve(createError(ErrorType.Failed.toString(), error))
226
+ Result.failure(error)
227
+ }
228
+
229
+ private fun configureMode(
230
+ args: ReadableMap,
231
+ promise: Promise,
232
+ ) {
188
233
  if (args.getBooleanOr("customFlow", false)) {
189
234
  lastConfigureWasCustomFlow = true
190
235
  if (flowController == null) {
191
236
  initFlowController(args, promise)
192
237
  }
193
238
  configureFlowController(promise)
194
- } else {
195
- lastConfigureWasCustomFlow = false
196
- if (paymentSheet == null) {
197
- initPaymentSheet(args, promise)
198
- }
199
- promise.resolve(Arguments.createMap())
239
+ return
240
+ }
241
+
242
+ lastConfigureWasCustomFlow = false
243
+ if (paymentSheet == null) {
244
+ initPaymentSheet(args, promise)
200
245
  }
246
+ promise.resolve(Arguments.createMap())
201
247
  }
202
248
 
203
249
  private fun initPaymentSheet(
@@ -391,7 +437,10 @@ class PaymentSheetManager(
391
437
  override fun onPresent() {
392
438
  keepJsAwake = KeepJsAwakeTask(context).apply { start() }
393
439
  if (lastConfigureWasCustomFlow == false) {
394
- if (!paymentIntentClientSecret.isNullOrEmpty()) {
440
+ val checkout = getCheckoutInstanceOrResolveError(promise)
441
+ if (checkout != null) {
442
+ paymentSheet?.presentWithCheckout(checkout, paymentSheetConfiguration)
443
+ } else if (!paymentIntentClientSecret.isNullOrEmpty()) {
395
444
  paymentSheet?.presentWithPaymentIntent(
396
445
  paymentIntentClientSecret!!,
397
446
  paymentSheetConfiguration,
@@ -418,31 +467,25 @@ class PaymentSheetManager(
418
467
  var paymentSheetActivity: Activity? = null
419
468
 
420
469
  val activityLifecycleCallbacks =
421
- object : Application.ActivityLifecycleCallbacks {
470
+ object : DefaultActivityLifecycleCallbacks() {
422
471
  override fun onActivityCreated(
423
472
  activity: Activity,
424
473
  savedInstanceState: Bundle?,
425
474
  ) {
426
- paymentSheetActivity = activity
427
- }
428
-
429
- override fun onActivityStarted(activity: Activity) {}
430
-
431
- override fun onActivityResumed(activity: Activity) {}
432
-
433
- override fun onActivityPaused(activity: Activity) {}
434
-
435
- override fun onActivityStopped(activity: Activity) {}
436
-
437
- override fun onActivitySaveInstanceState(
438
- activity: Activity,
439
- outState: Bundle,
440
- ) {
475
+ if (activity.javaClass.name == PAYMENT_SHEET_ACTIVITY ||
476
+ activity.javaClass.name == PAYMENT_OPTIONS_ACTIVITY
477
+ ) {
478
+ paymentSheetActivity = activity
479
+ }
441
480
  }
442
481
 
443
482
  override fun onActivityDestroyed(activity: Activity) {
444
- paymentSheetActivity = null
445
- context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
483
+ if (activity.javaClass.name == PAYMENT_SHEET_ACTIVITY ||
484
+ activity.javaClass.name == PAYMENT_OPTIONS_ACTIVITY
485
+ ) {
486
+ paymentSheetActivity = null
487
+ context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
488
+ }
446
489
  }
447
490
  }
448
491
 
@@ -475,7 +518,14 @@ class PaymentSheetManager(
475
518
  handleFlowControllerConfigured(success, error, promise, flowController)
476
519
  }
477
520
 
478
- if (!paymentIntentClientSecret.isNullOrEmpty()) {
521
+ val checkout = getCheckoutInstanceOrResolveError(promise)
522
+ if (checkout != null) {
523
+ flowController?.configureWithCheckout(
524
+ checkout = checkout,
525
+ configuration = paymentSheetConfiguration,
526
+ callback = onFlowControllerConfigure,
527
+ )
528
+ } else if (!paymentIntentClientSecret.isNullOrEmpty()) {
479
529
  flowController?.configureWithPaymentIntent(
480
530
  paymentIntentClientSecret = paymentIntentClientSecret!!,
481
531
  configuration = paymentSheetConfiguration,
@@ -504,6 +554,14 @@ class PaymentSheetManager(
504
554
  }
505
555
  }
506
556
 
557
+ private fun getCheckoutInstanceOrResolveError(promise: Promise?): Checkout? {
558
+ val checkoutSessionKey = checkoutSessionKey ?: return null
559
+ return checkoutInstances[checkoutSessionKey] ?: run {
560
+ promise?.resolve(createError(ErrorType.Failed.toString(), "Checkout session not found."))
561
+ null
562
+ }
563
+ }
564
+
507
565
  private fun resolvePresentPromise(value: Any?) {
508
566
  keepJsAwake?.stop()
509
567
  promise?.resolve(value)
@@ -550,7 +608,7 @@ class PaymentSheetManager(
550
608
  CoroutineScope(Dispatchers.Main).launch {
551
609
  try {
552
610
  // Give the CustomPaymentMethodActivity a moment to fully initialize
553
- delay(100)
611
+ delay(CUSTOM_PAYMENT_METHOD_INIT_DELAY_MS)
554
612
 
555
613
  // Emit event so JS can show the Alert and eventually respond via `customPaymentMethodResultCallback`.
556
614
  stripeSdkModule.eventEmitter.emitOnCustomPaymentMethodConfirmHandlerCallback(
@@ -596,6 +654,8 @@ class PaymentSheetManager(
596
654
  PaymentSheetErrorType.Failed.toString(),
597
655
  "No payment sheet has been initialized yet. You must call `initPaymentSheet` before `presentPaymentSheet`.",
598
656
  )
657
+
658
+ private const val CUSTOM_PAYMENT_METHOD_INIT_DELAY_MS = 100L
599
659
  }
600
660
  }
601
661
 
@@ -627,12 +687,16 @@ suspend fun waitForDrawableToLoad(
627
687
  who: Drawable,
628
688
  what: Runnable,
629
689
  `when`: Long,
630
- ) {}
690
+ ) {
691
+ // NO-OP
692
+ }
631
693
 
632
694
  override fun unscheduleDrawable(
633
695
  who: Drawable,
634
696
  what: Runnable,
635
- ) {}
697
+ ) {
698
+ // NO-OP
699
+ }
636
700
  }
637
701
 
638
702
  drawable.callback = callback
@@ -687,7 +751,7 @@ fun getBase64FromBitmap(bitmap: Bitmap?): String? {
687
751
  return null
688
752
  }
689
753
  val stream = ByteArrayOutputStream()
690
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
754
+ bitmap.compress(Bitmap.CompressFormat.PNG, BITMAP_COMPRESS_QUALITY, stream)
691
755
  val imageBytes: ByteArray = stream.toByteArray()
692
756
  return Base64.encodeToString(imageBytes, Base64.DEFAULT)
693
757
  }
@@ -716,7 +780,9 @@ internal fun mapToCaptureMethod(type: String?): PaymentSheet.IntentConfiguration
716
780
  }
717
781
 
718
782
  @OptIn(PaymentMethodOptionsSetupFutureUsagePreview::class)
719
- internal fun mapToPaymentMethodOptions(options: ReadableMap?): PaymentSheet.IntentConfiguration.Mode.Payment.PaymentMethodOptions? {
783
+ internal fun mapToPaymentMethodOptions(
784
+ options: ReadableMap?
785
+ ): PaymentSheet.IntentConfiguration.Mode.Payment.PaymentMethodOptions? {
720
786
  val sfuMap = options?.getMap("setupFutureUsageValues")
721
787
  val paymentMethodToSfuMap = mutableMapOf<PaymentMethod.Type, PaymentSheet.IntentConfiguration.SetupFutureUse>()
722
788
  sfuMap?.forEachKey { code ->
@@ -775,3 +841,7 @@ internal fun handleFlowControllerConfigured(
775
841
  promise.resolve(Arguments.createMap())
776
842
  }
777
843
  }
844
+
845
+ private const val BITMAP_COMPRESS_QUALITY = 100
846
+ private const val PAYMENT_SHEET_ACTIVITY = "com.stripe.android.paymentsheet.PaymentSheetActivity"
847
+ private const val PAYMENT_OPTIONS_ACTIVITY = "com.stripe.android.paymentsheet.PaymentOptionsActivity"
@@ -64,6 +64,7 @@ abstract class StripeAbstractComposeView(
64
64
 
65
65
  @Composable
66
66
  override fun Content() {
67
+ // NO-OP
67
68
  }
68
69
  }
69
70