@stripe/stripe-react-native 0.57.3 → 0.59.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 (233) hide show
  1. package/android/build.gradle +2 -0
  2. package/android/gradle.properties +1 -1
  3. package/android/src/main/AndroidManifest.xml +27 -1
  4. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +0 -3
  5. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +7 -3
  6. package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
  7. package/android/src/main/java/com/reactnativestripesdk/NavigationBarView.kt +12 -1
  8. package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +26 -0
  9. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +147 -0
  10. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementView.kt +164 -0
  11. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +65 -0
  12. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +1 -1
  13. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +60 -31
  14. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +17 -5
  15. package/android/src/main/java/com/reactnativestripesdk/StripeConnectDeepLinkInterceptorActivity.kt +77 -0
  16. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +334 -24
  17. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
  18. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +3 -0
  19. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +8 -0
  20. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +0 -2
  21. package/android/src/main/res/xml/file_paths.xml +4 -0
  22. package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerDelegate.java +36 -0
  23. package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerInterface.java +18 -0
  24. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +20 -0
  25. package/android/src/test/java/com/reactnativestripesdk/PaymentElementConfigTest.kt +175 -1
  26. package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt +543 -0
  27. package/android/src/test/java/com/reactnativestripesdk/PaymentSheetManagerTest.kt +70 -0
  28. package/ios/ConnectAccountOnboarding/ConnectAccountOnboardingView.swift +13 -19
  29. package/ios/CustomerSheet/CustomerSheetUtils.swift +4 -0
  30. package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
  31. package/ios/OldArch/StripeSdkEventEmitterCompat.m +13 -1
  32. package/ios/PaymentMethodMessagingElementConfig.swift +116 -0
  33. package/ios/PaymentMethodMessagingElementHandler.m +9 -0
  34. package/ios/PaymentMethodMessagingElementView.swift +139 -0
  35. package/ios/StripeSdk.mm +40 -0
  36. package/ios/StripeSdkEmitter.swift +2 -0
  37. package/ios/StripeSdkImpl+CustomerSheet.swift +1 -0
  38. package/ios/StripeSdkImpl+Embedded.swift +8 -1
  39. package/ios/StripeSdkImpl+PaymentSheet.swift +44 -1
  40. package/ios/StripeSdkImpl.swift +158 -2
  41. package/jest/mock.js +26 -0
  42. package/jest/setup.js +30 -0
  43. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  44. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  45. package/lib/commonjs/components/AddressSheet.js +1 -1
  46. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  47. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  48. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  49. package/lib/commonjs/components/CardField.js +1 -1
  50. package/lib/commonjs/components/CardField.js.map +1 -1
  51. package/lib/commonjs/components/CardForm.js +1 -1
  52. package/lib/commonjs/components/CardForm.js.map +1 -1
  53. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  54. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  55. package/lib/commonjs/components/StripeContainer.js +1 -1
  56. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  57. package/lib/commonjs/connect/Components.js +1 -1
  58. package/lib/commonjs/connect/Components.js.map +1 -1
  59. package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
  60. package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
  61. package/lib/commonjs/connect/EmbeddedComponent.js +10 -5
  62. package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
  63. package/lib/commonjs/connect/ModalCloseButton.js +1 -1
  64. package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
  65. package/lib/commonjs/connect/NavigationBar.js +1 -1
  66. package/lib/commonjs/connect/NavigationBar.js.map +1 -1
  67. package/lib/commonjs/connect/analytics/AnalyticsClient.js +2 -0
  68. package/lib/commonjs/connect/analytics/AnalyticsClient.js.map +1 -0
  69. package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js +2 -0
  70. package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
  71. package/lib/commonjs/connect/analytics/events.js +2 -0
  72. package/lib/commonjs/connect/analytics/events.js.map +1 -0
  73. package/lib/commonjs/connect/testUtils.js +2 -0
  74. package/lib/commonjs/connect/testUtils.js.map +1 -0
  75. package/lib/commonjs/events.js.map +1 -1
  76. package/lib/commonjs/functions.js +1 -1
  77. package/lib/commonjs/functions.js.map +1 -1
  78. package/lib/commonjs/helpers.js +1 -1
  79. package/lib/commonjs/hooks/useStripe.js +1 -1
  80. package/lib/commonjs/hooks/useStripe.js.map +1 -1
  81. package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
  82. package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
  83. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  84. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
  85. package/lib/commonjs/specs/NativeCardField.js +1 -1
  86. package/lib/commonjs/specs/NativeCardField.js.map +1 -1
  87. package/lib/commonjs/specs/NativeCardForm.js +1 -1
  88. package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
  89. package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
  90. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
  91. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  92. package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
  93. package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
  94. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +2 -0
  95. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js.map +1 -0
  96. package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
  97. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  98. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  99. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  100. package/lib/commonjs/types/Errors.js +1 -1
  101. package/lib/commonjs/types/Errors.js.map +1 -1
  102. package/lib/commonjs/types/FinancialConnections.js.map +1 -1
  103. package/lib/commonjs/types/PaymentSheet.js +1 -1
  104. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  105. package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js +2 -0
  106. package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
  107. package/lib/commonjs/types/index.js.map +1 -1
  108. package/lib/module/components/AddToWalletButton.js +1 -1
  109. package/lib/module/components/AddToWalletButton.js.map +1 -1
  110. package/lib/module/components/AddressSheet.js +1 -1
  111. package/lib/module/components/AddressSheet.js.map +1 -1
  112. package/lib/module/components/AuBECSDebitForm.js +1 -1
  113. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  114. package/lib/module/components/CardField.js +1 -1
  115. package/lib/module/components/CardField.js.map +1 -1
  116. package/lib/module/components/CardForm.js +1 -1
  117. package/lib/module/components/CardForm.js.map +1 -1
  118. package/lib/module/components/PlatformPayButton.js +1 -1
  119. package/lib/module/components/PlatformPayButton.js.map +1 -1
  120. package/lib/module/components/StripeContainer.js +1 -1
  121. package/lib/module/components/StripeContainer.js.map +1 -1
  122. package/lib/module/connect/Components.js +1 -1
  123. package/lib/module/connect/Components.js.map +1 -1
  124. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  125. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  126. package/lib/module/connect/EmbeddedComponent.js +10 -5
  127. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  128. package/lib/module/connect/ModalCloseButton.js +1 -1
  129. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  130. package/lib/module/connect/NavigationBar.js +1 -1
  131. package/lib/module/connect/NavigationBar.js.map +1 -1
  132. package/lib/module/connect/analytics/AnalyticsClient.js +2 -0
  133. package/lib/module/connect/analytics/AnalyticsClient.js.map +1 -0
  134. package/lib/module/connect/analytics/ComponentAnalyticsClient.js +2 -0
  135. package/lib/module/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
  136. package/lib/module/connect/analytics/events.js +2 -0
  137. package/lib/module/connect/analytics/events.js.map +1 -0
  138. package/lib/module/connect/testUtils.js +2 -0
  139. package/lib/module/connect/testUtils.js.map +1 -0
  140. package/lib/module/events.js.map +1 -1
  141. package/lib/module/functions.js +1 -1
  142. package/lib/module/functions.js.map +1 -1
  143. package/lib/module/helpers.js +1 -1
  144. package/lib/module/hooks/useStripe.js +1 -1
  145. package/lib/module/hooks/useStripe.js.map +1 -1
  146. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  147. package/lib/module/specs/NativeAddressSheet.js +1 -1
  148. package/lib/module/specs/NativeApplePayButton.js +1 -1
  149. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  150. package/lib/module/specs/NativeCardField.js +1 -1
  151. package/lib/module/specs/NativeCardField.js.map +1 -1
  152. package/lib/module/specs/NativeCardForm.js +1 -1
  153. package/lib/module/specs/NativeCardForm.js.map +1 -1
  154. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  155. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  156. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  157. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  158. package/lib/module/specs/NativeNavigationBar.js +1 -1
  159. package/lib/module/specs/NativePaymentMethodMessagingElement.js +2 -0
  160. package/lib/module/specs/NativePaymentMethodMessagingElement.js.map +1 -0
  161. package/lib/module/specs/NativeStripeContainer.js +1 -1
  162. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  163. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  164. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  165. package/lib/module/types/Errors.js +1 -1
  166. package/lib/module/types/Errors.js.map +1 -1
  167. package/lib/module/types/FinancialConnections.js.map +1 -1
  168. package/lib/module/types/PaymentSheet.js +1 -1
  169. package/lib/module/types/PaymentSheet.js.map +1 -1
  170. package/lib/module/types/components/PaymentMethodMessagingElementComponent.js +2 -0
  171. package/lib/module/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
  172. package/lib/module/types/index.js.map +1 -1
  173. package/lib/typescript/src/connect/Components.d.ts +91 -0
  174. package/lib/typescript/src/connect/Components.d.ts.map +1 -1
  175. package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts +61 -0
  176. package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts.map +1 -1
  177. package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
  178. package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts +32 -0
  179. package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts.map +1 -0
  180. package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts +94 -0
  181. package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts.map +1 -0
  182. package/lib/typescript/src/connect/analytics/events.d.ts +215 -0
  183. package/lib/typescript/src/connect/analytics/events.d.ts.map +1 -0
  184. package/lib/typescript/src/connect/connectTypes.d.ts +5 -1
  185. package/lib/typescript/src/connect/connectTypes.d.ts.map +1 -1
  186. package/lib/typescript/src/connect/testUtils.d.ts +45 -0
  187. package/lib/typescript/src/connect/testUtils.d.ts.map +1 -0
  188. package/lib/typescript/src/events.d.ts +2 -0
  189. package/lib/typescript/src/events.d.ts.map +1 -1
  190. package/lib/typescript/src/functions.d.ts +13 -1
  191. package/lib/typescript/src/functions.d.ts.map +1 -1
  192. package/lib/typescript/src/hooks/useStripe.d.ts +2 -1
  193. package/lib/typescript/src/hooks/useStripe.d.ts.map +1 -1
  194. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts +16 -0
  195. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts.map +1 -0
  196. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +16 -1
  197. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  198. package/lib/typescript/src/types/CustomerSheet.d.ts +5 -0
  199. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  200. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +11 -1
  201. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  202. package/lib/typescript/src/types/Errors.d.ts +4 -0
  203. package/lib/typescript/src/types/Errors.d.ts.map +1 -1
  204. package/lib/typescript/src/types/FinancialConnections.d.ts +2 -0
  205. package/lib/typescript/src/types/FinancialConnections.d.ts.map +1 -1
  206. package/lib/typescript/src/types/PaymentSheet.d.ts +35 -0
  207. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  208. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts +69 -0
  209. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts.map +1 -0
  210. package/lib/typescript/src/types/index.d.ts +8 -1
  211. package/lib/typescript/src/types/index.d.ts.map +1 -1
  212. package/package.json +4 -1
  213. package/src/connect/Components.tsx +109 -11
  214. package/src/connect/ConnectComponentsProvider.tsx +69 -2
  215. package/src/connect/EmbeddedComponent.tsx +458 -23
  216. package/src/connect/analytics/AnalyticsClient.ts +75 -0
  217. package/src/connect/analytics/ComponentAnalyticsClient.ts +315 -0
  218. package/src/connect/analytics/events.ts +253 -0
  219. package/src/connect/connectTypes.ts +5 -1
  220. package/src/connect/testUtils.ts +37 -0
  221. package/src/events.ts +2 -0
  222. package/src/functions.ts +10 -0
  223. package/src/hooks/useStripe.tsx +8 -0
  224. package/src/specs/NativePaymentMethodMessagingElement.ts +25 -0
  225. package/src/specs/NativeStripeSdkModule.ts +21 -1
  226. package/src/types/CustomerSheet.ts +5 -0
  227. package/src/types/EmbeddedPaymentElement.tsx +11 -1
  228. package/src/types/Errors.ts +5 -0
  229. package/src/types/FinancialConnections.ts +2 -0
  230. package/src/types/PaymentSheet.ts +38 -1
  231. package/src/types/components/PaymentMethodMessagingElementComponent.tsx +74 -0
  232. package/src/types/index.ts +11 -0
  233. package/stripe-react-native.podspec +1 -1
@@ -39,14 +39,15 @@ 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.PaymentConfiguration
42
43
  import com.stripe.android.core.reactnative.ReactNativeSdkInternal
43
44
  import com.stripe.android.model.PaymentMethod
44
45
  import com.stripe.android.paymentelement.ConfirmCustomPaymentMethodCallback
45
46
  import com.stripe.android.paymentelement.CreateIntentWithConfirmationTokenCallback
46
47
  import com.stripe.android.paymentelement.CustomPaymentMethodResult
47
48
  import com.stripe.android.paymentelement.CustomPaymentMethodResultHandler
48
- import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
49
49
  import com.stripe.android.paymentelement.PaymentMethodOptionsSetupFutureUsagePreview
50
+ import com.stripe.android.paymentsheet.CardFundingFilteringPrivatePreview
50
51
  import com.stripe.android.paymentsheet.CreateIntentCallback
51
52
  import com.stripe.android.paymentsheet.CreateIntentResult
52
53
  import com.stripe.android.paymentsheet.PaymentOptionResultCallback
@@ -67,7 +68,7 @@ import kotlin.coroutines.resume
67
68
  @OptIn(
68
69
  ReactNativeSdkInternal::class,
69
70
  ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class,
70
- ExperimentalCustomPaymentMethodsApi::class,
71
+ CardFundingFilteringPrivatePreview::class,
71
72
  )
72
73
  class PaymentSheetManager(
73
74
  context: ReactApplicationContext,
@@ -88,7 +89,6 @@ class PaymentSheetManager(
88
89
  private var keepJsAwake: KeepJsAwakeTask? = null
89
90
 
90
91
  @SuppressLint("RestrictedApi")
91
- @OptIn(ExperimentalCustomPaymentMethodsApi::class)
92
92
  override fun onCreate() {
93
93
  val activity = getCurrentActivityOrResolveWithError(initPromise) ?: return
94
94
  val merchantDisplayName = arguments.getString("merchantDisplayName").orEmpty()
@@ -107,6 +107,8 @@ class PaymentSheetManager(
107
107
  val paymentMethodOrder = arguments.getStringList("paymentMethodOrder")
108
108
  val allowsRemovalOfLastSavedPaymentMethod =
109
109
  arguments.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
110
+ val opensCardScannerAutomatically =
111
+ arguments.getBooleanOr("opensCardScannerAutomatically", false)
110
112
  paymentIntentClientSecret = arguments.getString("paymentIntentClientSecret").orEmpty()
111
113
  setupIntentClientSecret = arguments.getString("setupIntentClientSecret").orEmpty()
112
114
  intentConfiguration =
@@ -284,8 +286,11 @@ class PaymentSheetManager(
284
286
  .preferredNetworks(
285
287
  mapToPreferredNetworks(arguments.getIntegerList("preferredNetworks")),
286
288
  ).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
289
+ .opensCardScannerAutomatically(opensCardScannerAutomatically)
287
290
  .cardBrandAcceptance(mapToCardBrandAcceptance(arguments))
288
- .customPaymentMethods(parseCustomPaymentMethods(arguments.getMap("customPaymentMethodConfiguration")))
291
+ .apply {
292
+ mapToAllowedCardFundingTypes(arguments)?.let { allowedCardFundingTypes(it) }
293
+ }.customPaymentMethods(parseCustomPaymentMethods(arguments.getMap("customPaymentMethodConfiguration")))
289
294
 
290
295
  primaryButtonLabel?.let { configurationBuilder.primaryButtonLabel(it) }
291
296
  paymentMethodOrder?.let { configurationBuilder.paymentMethodOrder(it) }
@@ -294,6 +299,14 @@ class PaymentSheetManager(
294
299
  mapToPaymentMethodLayout(arguments.getString("paymentMethodLayout")),
295
300
  )
296
301
 
302
+ val userKeyTermsDisplay =
303
+ computeTermsDisplayForUserKey(
304
+ PaymentConfiguration.getInstance(context).publishableKey,
305
+ )
306
+ if (userKeyTermsDisplay.isNotEmpty()) {
307
+ configurationBuilder.termsDisplay(userKeyTermsDisplay)
308
+ }
309
+
297
310
  paymentSheetConfiguration = configurationBuilder.build()
298
311
 
299
312
  if (arguments.getBooleanOr("customFlow", false)) {
@@ -429,32 +442,8 @@ class PaymentSheetManager(
429
442
 
430
443
  private fun configureFlowController() {
431
444
  val onFlowControllerConfigure =
432
- PaymentSheet.FlowController.ConfigCallback { _, _ ->
433
- flowController?.getPaymentOption()?.let { paymentOption ->
434
- // Launch async job to convert drawable, but resolve promise synchronously
435
- CoroutineScope(Dispatchers.Default).launch {
436
- val imageString =
437
- try {
438
- convertDrawableToBase64(paymentOption.icon())
439
- } catch (e: Exception) {
440
- val result =
441
- createError(
442
- PaymentSheetErrorType.Failed.toString(),
443
- "Failed to process payment option image: ${e.message}",
444
- )
445
- initPromise.resolve(result)
446
- return@launch
447
- }
448
-
449
- val option: WritableMap = Arguments.createMap()
450
- option.putString("label", paymentOption.label)
451
- option.putString("image", imageString)
452
- val result = createResult("paymentOption", option)
453
- initPromise.resolve(result)
454
- }
455
- } ?: run {
456
- initPromise.resolve(Arguments.createMap())
457
- }
445
+ PaymentSheet.FlowController.ConfigCallback { success, error ->
446
+ handleFlowControllerConfigured(success, error, initPromise, flowController)
458
447
  }
459
448
 
460
449
  if (!paymentIntentClientSecret.isNullOrEmpty()) {
@@ -498,7 +487,6 @@ class PaymentSheetManager(
498
487
  } ?: run { resolvePresentPromise(map) }
499
488
  }
500
489
 
501
- @OptIn(ExperimentalCustomPaymentMethodsApi::class)
502
490
  override fun onConfirmCustomPaymentMethod(
503
491
  customPaymentMethod: PaymentSheet.CustomPaymentMethod,
504
492
  billingDetails: PaymentMethod.BillingDetails,
@@ -717,3 +705,44 @@ internal fun mapToPaymentMethodOptions(options: ReadableMap?): PaymentSheet.Inte
717
705
  null
718
706
  }
719
707
  }
708
+
709
+ internal fun handleFlowControllerConfigured(
710
+ success: Boolean,
711
+ error: Throwable?,
712
+ promise: Promise,
713
+ flowController: PaymentSheet.FlowController?,
714
+ ) {
715
+ if (!success) {
716
+ promise.resolve(
717
+ createError(
718
+ PaymentSheetErrorType.Failed.toString(),
719
+ error?.message ?: "Failed to configure payment sheet",
720
+ ),
721
+ )
722
+ return
723
+ }
724
+ flowController?.getPaymentOption()?.let { paymentOption ->
725
+ CoroutineScope(Dispatchers.Default).launch {
726
+ val imageString =
727
+ try {
728
+ convertDrawableToBase64(paymentOption.icon())
729
+ } catch (e: Exception) {
730
+ val result =
731
+ createError(
732
+ PaymentSheetErrorType.Failed.toString(),
733
+ "Failed to process payment option image: ${e.message}",
734
+ )
735
+ promise.resolve(result)
736
+ return@launch
737
+ }
738
+
739
+ val option: WritableMap = Arguments.createMap()
740
+ option.putString("label", paymentOption.label)
741
+ option.putString("image", imageString)
742
+ val result = createResult("paymentOption", option)
743
+ promise.resolve(result)
744
+ }
745
+ } ?: run {
746
+ promise.resolve(Arguments.createMap())
747
+ }
748
+ }
@@ -69,6 +69,8 @@ abstract class StripeAbstractComposeView(
69
69
 
70
70
  private var innerComposeView: InnerComposeView? = null
71
71
  private var isLifecycleSetup = false
72
+ private var activityLifecycleOwner: LifecycleOwner? = null
73
+ private var activityLifecycleObserver: LifecycleEventObserver? = null
72
74
 
73
75
  // Create a lifecycle this is tied to the activity, but that we can manually
74
76
  // update to DESTROYED state when the view is dropped.
@@ -113,24 +115,34 @@ abstract class StripeAbstractComposeView(
113
115
  return
114
116
  }
115
117
 
116
- ((context as? ReactContext)?.currentActivity as? LifecycleOwner?)?.let {
118
+ ((context as? ReactContext)?.currentActivity as? LifecycleOwner?)?.let { owner ->
117
119
  isLifecycleSetup = true
120
+ activityLifecycleOwner = owner
118
121
 
119
122
  // Setup the lifecycle to match the activity.
120
- it.lifecycle.addObserver(
123
+ val observer =
121
124
  object : LifecycleEventObserver {
122
125
  override fun onStateChanged(
123
126
  source: LifecycleOwner,
124
127
  event: Lifecycle.Event,
125
128
  ) {
126
- lifecycleRegistry.handleLifecycleEvent(event)
129
+ if (lifecycleRegistry.currentState != Lifecycle.State.DESTROYED) {
130
+ lifecycleRegistry.handleLifecycleEvent(event)
131
+ }
127
132
  }
128
- },
129
- )
133
+ }
134
+ activityLifecycleObserver = observer
135
+ owner.lifecycle.addObserver(observer)
130
136
  }
131
137
  }
132
138
 
133
139
  fun handleOnDropViewInstance() {
140
+ activityLifecycleObserver?.let { observer ->
141
+ activityLifecycleOwner?.lifecycle?.removeObserver(observer)
142
+ }
143
+ activityLifecycleObserver = null
144
+ activityLifecycleOwner = null
145
+
134
146
  if (lifecycleRegistry.currentState.isAtLeast(Lifecycle.State.CREATED)) {
135
147
  lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
136
148
  }
@@ -0,0 +1,77 @@
1
+ package com.reactnativestripesdk
2
+
3
+ import android.app.Activity
4
+ import android.content.Intent
5
+ import android.os.Bundle
6
+ import android.util.Log
7
+
8
+ /**
9
+ * Transparent interceptor Activity that captures stripe-connect:// deep links
10
+ * before they reach React Native's Linking module.
11
+ *
12
+ * This prevents Expo Router from receiving the URL and dismissing the current screen.
13
+ * The URL is stored in StripeSdkModule's internal storage and retrieved via polling.
14
+ *
15
+ * HOW IT WORKS:
16
+ * 1. Android launches this Activity when a stripe-connect:// URL is opened
17
+ * 2. onCreate() extracts the URL and stores it via StripeSdkModule.storeStripeConnectDeepLink()
18
+ * 3. Launches an Intent to bring the main app to the foreground
19
+ * 4. The Activity immediately finishes without showing any UI
20
+ * 5. JavaScript polls for URLs via NativeStripeSdk.pollAndClearPendingStripeConnectUrls()
21
+ *
22
+ * MANIFEST CONFIGURATION:
23
+ * The AndroidManifest.xml declares this Activity with:
24
+ * - android:exported="true" - allows deep links from outside the app
25
+ * - android:launchMode="singleTask" - reuses existing instance if available
26
+ * - android:theme="@android:style/Theme.Translucent.NoTitleBar" - transparent UI
27
+ * - Intent filter for stripe-connect:// scheme
28
+ *
29
+ * USER IMPACT:
30
+ * - Zero configuration required by users
31
+ * - Works automatically for all package names
32
+ * - No MainActivity override needed
33
+ */
34
+ class StripeConnectDeepLinkInterceptorActivity : Activity() {
35
+ override fun onCreate(savedInstanceState: Bundle?) {
36
+ super.onCreate(savedInstanceState)
37
+
38
+ // Extract the deep link URL from the Intent
39
+ val url = intent?.data?.toString()
40
+
41
+ if (url != null && url.startsWith("stripe-connect://")) {
42
+ // Store in SDK's internal storage (thread-safe)
43
+ StripeSdkModule.storeStripeConnectDeepLink(url)
44
+ } else {
45
+ Log.w(TAG, "Unexpected URL scheme in StripeConnectDeepLinkInterceptor: $url")
46
+ }
47
+
48
+ // Bring the main app back to the foreground
49
+ // This is critical because when Custom Tabs opens a deep link,
50
+ // the interceptor Activity starts in a new task. When it finishes,
51
+ // Android doesn't automatically return to the main app - it just shows
52
+ // the Custom Tab again. We need to explicitly bring the app forward.
53
+ try {
54
+ val packageName = applicationContext.packageName
55
+ val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
56
+
57
+ if (launchIntent != null) {
58
+ // Flags to bring existing task to front without recreating activities
59
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
60
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
61
+ startActivity(launchIntent)
62
+ } else {
63
+ Log.w(TAG, "Could not get launch intent for package: $packageName")
64
+ }
65
+ } catch (e: Exception) {
66
+ Log.e(TAG, "Error bringing app to foreground", e)
67
+ }
68
+
69
+ // Immediately finish - don't show any UI
70
+ // This makes the Activity transparent to the user
71
+ finish()
72
+ }
73
+
74
+ companion object {
75
+ private const val TAG = "StripeConnectInterceptor"
76
+ }
77
+ }