@stripe/stripe-react-native 0.58.0 → 0.59.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 (222) hide show
  1. package/android/.idea/AndroidProjectSystem.xml +6 -0
  2. package/android/.idea/compiler.xml +6 -0
  3. package/android/.idea/gradle.xml +18 -0
  4. package/android/.idea/migrations.xml +10 -0
  5. package/android/.idea/misc.xml +10 -0
  6. package/android/.idea/runConfigurations.xml +17 -0
  7. package/android/.idea/vcs.xml +6 -0
  8. package/android/build.gradle +2 -0
  9. package/android/local.properties +8 -0
  10. package/android/src/main/AndroidManifest.xml +27 -1
  11. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +2 -0
  12. package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
  13. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +147 -0
  14. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementView.kt +164 -0
  15. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +65 -0
  16. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +1 -1
  17. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +46 -26
  18. package/android/src/main/java/com/reactnativestripesdk/StripeConnectDeepLinkInterceptorActivity.kt +77 -0
  19. package/android/src/main/java/com/reactnativestripesdk/StripeFileProvider.kt +17 -0
  20. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +325 -22
  21. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
  22. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +3 -0
  23. package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +8 -0
  24. package/android/src/main/res/xml/file_paths.xml +4 -0
  25. package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerDelegate.java +36 -0
  26. package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerInterface.java +18 -0
  27. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +20 -0
  28. package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt +543 -0
  29. package/android/src/test/java/com/reactnativestripesdk/PaymentSheetManagerTest.kt +70 -0
  30. package/ios/CustomerSheet/CustomerSheetUtils.swift +4 -0
  31. package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
  32. package/ios/OldArch/StripeSdkEventEmitterCompat.m +13 -1
  33. package/ios/PaymentMethodMessagingElementConfig.swift +116 -0
  34. package/ios/PaymentMethodMessagingElementHandler.m +9 -0
  35. package/ios/PaymentMethodMessagingElementView.swift +139 -0
  36. package/ios/StripeSdk.mm +40 -0
  37. package/ios/StripeSdkEmitter.swift +2 -0
  38. package/ios/StripeSdkImpl+CustomerSheet.swift +1 -0
  39. package/ios/StripeSdkImpl+Embedded.swift +4 -0
  40. package/ios/StripeSdkImpl+PaymentSheet.swift +4 -0
  41. package/ios/StripeSdkImpl.swift +132 -0
  42. package/jest/mock.js +20 -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 +5 -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/PaymentSheet.js.map +1 -1
  103. package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js +2 -0
  104. package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
  105. package/lib/commonjs/types/index.js.map +1 -1
  106. package/lib/module/components/AddToWalletButton.js +1 -1
  107. package/lib/module/components/AddToWalletButton.js.map +1 -1
  108. package/lib/module/components/AddressSheet.js +1 -1
  109. package/lib/module/components/AddressSheet.js.map +1 -1
  110. package/lib/module/components/AuBECSDebitForm.js +1 -1
  111. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  112. package/lib/module/components/CardField.js +1 -1
  113. package/lib/module/components/CardField.js.map +1 -1
  114. package/lib/module/components/CardForm.js +1 -1
  115. package/lib/module/components/CardForm.js.map +1 -1
  116. package/lib/module/components/PlatformPayButton.js +1 -1
  117. package/lib/module/components/PlatformPayButton.js.map +1 -1
  118. package/lib/module/components/StripeContainer.js +1 -1
  119. package/lib/module/components/StripeContainer.js.map +1 -1
  120. package/lib/module/connect/Components.js +1 -1
  121. package/lib/module/connect/Components.js.map +1 -1
  122. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  123. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  124. package/lib/module/connect/EmbeddedComponent.js +5 -5
  125. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  126. package/lib/module/connect/ModalCloseButton.js +1 -1
  127. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  128. package/lib/module/connect/NavigationBar.js +1 -1
  129. package/lib/module/connect/NavigationBar.js.map +1 -1
  130. package/lib/module/connect/analytics/AnalyticsClient.js +2 -0
  131. package/lib/module/connect/analytics/AnalyticsClient.js.map +1 -0
  132. package/lib/module/connect/analytics/ComponentAnalyticsClient.js +2 -0
  133. package/lib/module/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
  134. package/lib/module/connect/analytics/events.js +2 -0
  135. package/lib/module/connect/analytics/events.js.map +1 -0
  136. package/lib/module/connect/testUtils.js +2 -0
  137. package/lib/module/connect/testUtils.js.map +1 -0
  138. package/lib/module/events.js.map +1 -1
  139. package/lib/module/functions.js +1 -1
  140. package/lib/module/functions.js.map +1 -1
  141. package/lib/module/helpers.js +1 -1
  142. package/lib/module/hooks/useStripe.js +1 -1
  143. package/lib/module/hooks/useStripe.js.map +1 -1
  144. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  145. package/lib/module/specs/NativeAddressSheet.js +1 -1
  146. package/lib/module/specs/NativeApplePayButton.js +1 -1
  147. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  148. package/lib/module/specs/NativeCardField.js +1 -1
  149. package/lib/module/specs/NativeCardField.js.map +1 -1
  150. package/lib/module/specs/NativeCardForm.js +1 -1
  151. package/lib/module/specs/NativeCardForm.js.map +1 -1
  152. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  153. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  154. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  155. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  156. package/lib/module/specs/NativeNavigationBar.js +1 -1
  157. package/lib/module/specs/NativePaymentMethodMessagingElement.js +2 -0
  158. package/lib/module/specs/NativePaymentMethodMessagingElement.js.map +1 -0
  159. package/lib/module/specs/NativeStripeContainer.js +1 -1
  160. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  161. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  162. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  163. package/lib/module/types/Errors.js +1 -1
  164. package/lib/module/types/Errors.js.map +1 -1
  165. package/lib/module/types/PaymentSheet.js.map +1 -1
  166. package/lib/module/types/components/PaymentMethodMessagingElementComponent.js +2 -0
  167. package/lib/module/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
  168. package/lib/module/types/index.js.map +1 -1
  169. package/lib/typescript/src/connect/Components.d.ts +91 -0
  170. package/lib/typescript/src/connect/Components.d.ts.map +1 -1
  171. package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts +61 -0
  172. package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts.map +1 -1
  173. package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
  174. package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts +32 -0
  175. package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts.map +1 -0
  176. package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts +94 -0
  177. package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts.map +1 -0
  178. package/lib/typescript/src/connect/analytics/events.d.ts +215 -0
  179. package/lib/typescript/src/connect/analytics/events.d.ts.map +1 -0
  180. package/lib/typescript/src/connect/testUtils.d.ts +45 -0
  181. package/lib/typescript/src/connect/testUtils.d.ts.map +1 -0
  182. package/lib/typescript/src/events.d.ts +2 -0
  183. package/lib/typescript/src/events.d.ts.map +1 -1
  184. package/lib/typescript/src/functions.d.ts +13 -1
  185. package/lib/typescript/src/functions.d.ts.map +1 -1
  186. package/lib/typescript/src/hooks/useStripe.d.ts +2 -1
  187. package/lib/typescript/src/hooks/useStripe.d.ts.map +1 -1
  188. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts +16 -0
  189. package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts.map +1 -0
  190. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +16 -1
  191. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  192. package/lib/typescript/src/types/CustomerSheet.d.ts +5 -0
  193. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  194. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +5 -0
  195. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  196. package/lib/typescript/src/types/Errors.d.ts +4 -0
  197. package/lib/typescript/src/types/Errors.d.ts.map +1 -1
  198. package/lib/typescript/src/types/PaymentSheet.d.ts +5 -0
  199. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  200. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts +69 -0
  201. package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts.map +1 -0
  202. package/lib/typescript/src/types/index.d.ts +8 -1
  203. package/lib/typescript/src/types/index.d.ts.map +1 -1
  204. package/package.json +1 -1
  205. package/src/connect/Components.tsx +91 -0
  206. package/src/connect/ConnectComponentsProvider.tsx +69 -2
  207. package/src/connect/EmbeddedComponent.tsx +254 -30
  208. package/src/connect/analytics/AnalyticsClient.ts +75 -0
  209. package/src/connect/analytics/ComponentAnalyticsClient.ts +315 -0
  210. package/src/connect/analytics/events.ts +253 -0
  211. package/src/connect/testUtils.ts +37 -0
  212. package/src/events.ts +2 -0
  213. package/src/functions.ts +10 -0
  214. package/src/hooks/useStripe.tsx +8 -0
  215. package/src/specs/NativePaymentMethodMessagingElement.ts +25 -0
  216. package/src/specs/NativeStripeSdkModule.ts +21 -1
  217. package/src/types/CustomerSheet.ts +5 -0
  218. package/src/types/EmbeddedPaymentElement.tsx +5 -0
  219. package/src/types/Errors.ts +5 -0
  220. package/src/types/PaymentSheet.ts +6 -1
  221. package/src/types/components/PaymentMethodMessagingElementComponent.tsx +74 -0
  222. package/src/types/index.ts +11 -0
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AndroidProjectSystem">
4
+ <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="CompilerConfiguration">
4
+ <bytecodeTargetLevel target="1.6" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="GradleMigrationSettings" migrationVersion="1" />
4
+ <component name="GradleSettings">
5
+ <option name="linkedExternalProjectsSettings">
6
+ <GradleProjectSettings>
7
+ <option name="testRunner" value="CHOOSE_PER_TEST" />
8
+ <option name="externalProjectPath" value="$PROJECT_DIR$" />
9
+ <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
10
+ <option name="modules">
11
+ <set>
12
+ <option value="$PROJECT_DIR$" />
13
+ </set>
14
+ </option>
15
+ </GradleProjectSettings>
16
+ </option>
17
+ </component>
18
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectMigrations">
4
+ <option name="MigrateToGradleLocalJavaHome">
5
+ <set>
6
+ <option value="$PROJECT_DIR$" />
7
+ </set>
8
+ </option>
9
+ </component>
10
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ExternalStorageConfigurationManager" enabled="true" />
4
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
5
+ <output url="file://$PROJECT_DIR$/build/classes" />
6
+ </component>
7
+ <component name="ProjectType">
8
+ <option name="id" value="Android" />
9
+ </component>
10
+ </project>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="RunConfigurationProducerService">
4
+ <option name="ignoredProducers">
5
+ <set>
6
+ <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
7
+ <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
8
+ <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
9
+ <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
10
+ <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
11
+ <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
12
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
13
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
14
+ </set>
15
+ </option>
16
+ </component>
17
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
5
+ </component>
6
+ </project>
@@ -100,6 +100,7 @@ android {
100
100
  consumerProguardFiles "proguard-rules.txt"
101
101
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
102
102
  buildConfigField "boolean", "IS_ONRAMP_INCLUDED", isOnrampIncluded().toString()
103
+ buildConfigField "String", "STRIPE_ANDROID_SDK_VERSION", "\"${getExtOrDefault("stripeVersion")}\""
103
104
 
104
105
  ndk {
105
106
  abiFilters(*reactNativeArchitectures())
@@ -162,6 +163,7 @@ dependencies {
162
163
  implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
163
164
  implementation("com.stripe:stripe-android:$stripeVersion")
164
165
  implementation("com.stripe:financial-connections:$stripeVersion")
166
+ implementation("com.stripe:payment-method-messaging:$stripeVersion")
165
167
 
166
168
  if (isOnrampIncluded()) {
167
169
  implementation("com.stripe:crypto-onramp:$stripeVersion")
@@ -0,0 +1,8 @@
1
+ ## This file must *NOT* be checked into Version Control Systems,
2
+ # as it contains information specific to your local configuration.
3
+ #
4
+ # Location of the SDK. This is only used by Gradle.
5
+ # For customization when using a Version Control System, please read the
6
+ # header note.
7
+ #Fri Aug 30 15:10:34 EDT 2024
8
+ sdk.dir=/Users/samer/Library/Android/sdk
@@ -2,12 +2,38 @@
2
2
  package="com.reactnativestripesdk">
3
3
 
4
4
  <application>
5
- <activity
5
+ <activity
6
6
  android:name=".CustomPaymentMethodActivity"
7
7
  android:theme="@style/Theme.StripeReactNative.Transparent"
8
8
  android:exported="false"
9
9
  android:launchMode="singleTop"
10
10
  android:excludeFromRecents="true"
11
11
  android:noHistory="true" />
12
+
13
+ <!-- Interceptor for stripe-connect:// deep links -->
14
+ <activity
15
+ android:name=".StripeConnectDeepLinkInterceptorActivity"
16
+ android:theme="@android:style/Theme.Translucent.NoTitleBar"
17
+ android:exported="true"
18
+ android:launchMode="singleTask"
19
+ android:excludeFromRecents="true"
20
+ android:noHistory="true">
21
+ <intent-filter>
22
+ <action android:name="android.intent.action.VIEW"/>
23
+ <category android:name="android.intent.category.DEFAULT"/>
24
+ <category android:name="android.intent.category.BROWSABLE"/>
25
+ <data android:scheme="stripe-connect"/>
26
+ </intent-filter>
27
+ </activity>
28
+
29
+ <provider
30
+ android:name="com.reactnativestripesdk.StripeFileProvider"
31
+ android:authorities="${applicationId}.fileprovider"
32
+ android:exported="false"
33
+ android:grantUriPermissions="true">
34
+ <meta-data
35
+ android:name="android.support.FILE_PROVIDER_PATHS"
36
+ android:resource="@xml/file_paths" />
37
+ </provider>
12
38
  </application>
13
39
  </manifest>
@@ -132,6 +132,7 @@ class EmbeddedPaymentElementViewManager :
132
132
  map.getMap("billingDetailsCollectionConfiguration"),
133
133
  )
134
134
  val allowsRemovalOfLastSavedPaymentMethod = map.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
135
+ val opensCardScannerAutomatically = map.getBooleanOr("opensCardScannerAutomatically", false)
135
136
  val primaryButtonLabel = map.getString("primaryButtonLabel")
136
137
  val paymentMethodOrder = map.getStringList("paymentMethodOrder")
137
138
 
@@ -156,6 +157,7 @@ class EmbeddedPaymentElementViewManager :
156
157
  ?.let { ArrayList(it) },
157
158
  ),
158
159
  ).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
160
+ .opensCardScannerAutomatically(opensCardScannerAutomatically)
159
161
  .cardBrandAcceptance(mapToCardBrandAcceptance(map))
160
162
  .apply {
161
163
  mapToAllowedCardFundingTypes(map)?.let { allowedCardFundingTypes(it) }
@@ -91,4 +91,12 @@ class EventEmitterCompat(
91
91
  fun emitOnCustomPaymentMethodConfirmHandlerCallback(value: ReadableMap?) {
92
92
  invoke("onCustomPaymentMethodConfirmHandlerCallback", value)
93
93
  }
94
+
95
+ fun emitPaymentMethodMessagingElementDidUpdateHeight(value: ReadableMap?) {
96
+ invoke("paymentMethodMessagingElementDidUpdateHeight", value)
97
+ }
98
+
99
+ fun emitPaymentMethodMessagingElementConfigureResult(value: ReadableMap?) {
100
+ invoke("paymentMethodMessagingElementConfigureResult", value)
101
+ }
94
102
  }
@@ -0,0 +1,147 @@
1
+ @file:OptIn(PaymentMethodMessagingElementPreview::class)
2
+
3
+ package com.reactnativestripesdk
4
+
5
+ import android.content.Context
6
+ import androidx.core.graphics.toColorInt
7
+ import com.facebook.react.bridge.ReadableMap
8
+ import com.facebook.react.bridge.ReadableType
9
+ import com.reactnativestripesdk.utils.PaymentMethodMessagingElementAppearanceException
10
+ import com.reactnativestripesdk.utils.PaymentMethodMessagingElementConfigurationException
11
+ import com.reactnativestripesdk.utils.getDoubleOrNull
12
+ import com.reactnativestripesdk.utils.getStringList
13
+ import com.stripe.android.model.PaymentMethod
14
+ import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElement
15
+ import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElementPreview
16
+
17
+ @Throws(PaymentMethodMessagingElementConfigurationException::class)
18
+ fun parseElementConfiguration(map: ReadableMap): PaymentMethodMessagingElement.Configuration {
19
+ val amount =
20
+ map.getDoubleOrNull("amount")?.toLong()
21
+ ?: throw PaymentMethodMessagingElementConfigurationException("`amount` is required")
22
+ val currency =
23
+ map.getString("currency")
24
+ ?: throw PaymentMethodMessagingElementConfigurationException("`currency` is required")
25
+
26
+ val locale = map.getString("locale")
27
+ val countryCode = map.getString("country")
28
+ val stringPaymentMethodTypes = map.getStringList("paymentMethodTypes")
29
+ val paymentMethodTypes =
30
+ stringPaymentMethodTypes?.mapNotNull {
31
+ PaymentMethod.Type.fromCode(it)
32
+ }
33
+
34
+ val config = PaymentMethodMessagingElement.Configuration()
35
+ config.amount(amount)
36
+ config.currency(currency)
37
+ locale?.let { config.locale(it) }
38
+ countryCode?.let { config.countryCode(it) }
39
+ paymentMethodTypes?.let { config.paymentMethodTypes(it) }
40
+
41
+ return config
42
+ }
43
+
44
+ fun parseAppearance(
45
+ map: ReadableMap,
46
+ context: Context,
47
+ ): PaymentMethodMessagingElement.Appearance {
48
+ val font =
49
+ map.getMap("font")?.let {
50
+ parseFont(
51
+ it,
52
+ context,
53
+ )
54
+ }
55
+
56
+ val theme = getTheme(map)
57
+ val textColor = dynamicColorFromParams(map, "textColor", theme)
58
+ val linkTextColor = dynamicColorFromParams(map, "linkTextColor", theme)
59
+ val appearance = PaymentMethodMessagingElement.Appearance()
60
+ appearance.theme(theme)
61
+ font?.let { appearance.font(font) }
62
+ val colors = PaymentMethodMessagingElement.Appearance.Colors()
63
+ textColor?.let { colors.textColor(it) }
64
+ linkTextColor?.let { colors.infoIconColor(linkTextColor) }
65
+ appearance.colors(colors)
66
+
67
+ return appearance
68
+ }
69
+
70
+ private fun parseFont(
71
+ map: ReadableMap,
72
+ context: Context,
73
+ ): PaymentMethodMessagingElement.Appearance.Font {
74
+ val fontFamily =
75
+ getFontResId(
76
+ map,
77
+ "family",
78
+ context,
79
+ )
80
+ val scaleFactor = map.getDoubleOrNull("scale") ?: 1.0
81
+ val textSize: Double = 16 * scaleFactor
82
+
83
+ val font =
84
+ PaymentMethodMessagingElement.Appearance
85
+ .Font()
86
+ .fontFamily(fontFamily)
87
+ .fontSizeSp(textSize.toFloat())
88
+
89
+ return font
90
+ }
91
+
92
+ private fun getTheme(map: ReadableMap): PaymentMethodMessagingElement.Appearance.Theme {
93
+ val style = map.getString("style")
94
+ return when (style) {
95
+ "dark" -> PaymentMethodMessagingElement.Appearance.Theme.DARK
96
+ "flat" -> PaymentMethodMessagingElement.Appearance.Theme.FLAT
97
+ else -> PaymentMethodMessagingElement.Appearance.Theme.LIGHT
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Parses a ThemedColor from [params] at [key]. Supports both:
103
+ * - Single hex string: "#RRGGBB"
104
+ * - Light/dark object: { "light": "#RRGGBB", "dark": "#RRGGBB" }
105
+ * For light/dark objects, chooses the appropriate color based on current UI mode.
106
+ * Returns null if no color is provided.
107
+ */
108
+ private fun dynamicColorFromParams(
109
+ params: ReadableMap?,
110
+ key: String,
111
+ theme: PaymentMethodMessagingElement.Appearance.Theme,
112
+ ): Int? {
113
+ if (params == null) {
114
+ return null
115
+ }
116
+
117
+ // First check if it's a nested map { "light": "#RRGGBB", "dark": "#RRGGBB" }
118
+ if (params.hasKey(key) && params.getType(key) == ReadableType.Map) {
119
+ val colorMap = params.getMap(key)
120
+ val isDark = theme == PaymentMethodMessagingElement.Appearance.Theme.DARK
121
+
122
+ // Pick the hex for current mode, or null
123
+ val hex =
124
+ if (isDark) {
125
+ colorMap?.getString("dark")
126
+ } else {
127
+ colorMap?.getString("light")
128
+ }
129
+
130
+ return colorFromHex(hex)
131
+ }
132
+
133
+ // Check if it's a single color string
134
+ return colorFromHex(params.getString(key))
135
+ }
136
+
137
+ @Throws(PaymentMethodMessagingElementAppearanceException::class)
138
+ private fun colorFromHex(hexString: String?): Int? =
139
+ hexString?.trim()?.replace("#", "")?.let {
140
+ if (it.length == 6 || it.length == 8) {
141
+ "#$it".toColorInt()
142
+ } else {
143
+ throw PaymentMethodMessagingElementAppearanceException(
144
+ "Failed to set appearance. Expected hex string of length 6 or 8, but received: $it",
145
+ )
146
+ }
147
+ }
@@ -0,0 +1,164 @@
1
+ package com.reactnativestripesdk
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.app.Application
5
+ import android.content.Context
6
+ import androidx.compose.foundation.layout.Box
7
+ import androidx.compose.runtime.Composable
8
+ import androidx.compose.runtime.LaunchedEffect
9
+ import androidx.compose.runtime.getValue
10
+ import androidx.compose.runtime.mutableStateOf
11
+ import androidx.compose.runtime.remember
12
+ import androidx.compose.runtime.setValue
13
+ import androidx.compose.ui.Modifier
14
+ import androidx.compose.ui.layout.layout
15
+ import androidx.compose.ui.layout.onSizeChanged
16
+ import androidx.compose.ui.platform.LocalDensity
17
+ import androidx.compose.ui.unit.IntOffset
18
+ import androidx.compose.ui.unit.dp
19
+ import com.facebook.react.bridge.Arguments
20
+ import com.facebook.react.uimanager.ThemedReactContext
21
+ import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElement
22
+ import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElementPreview
23
+ import kotlinx.coroutines.channels.Channel
24
+ import kotlinx.coroutines.flow.consumeAsFlow
25
+
26
+ @OptIn(PaymentMethodMessagingElementPreview::class)
27
+ class PaymentMethodMessagingElementView(
28
+ context: Context,
29
+ ) : StripeAbstractComposeView(context) {
30
+ private sealed interface Event {
31
+ data class Configure(
32
+ val configuration: PaymentMethodMessagingElement.Configuration,
33
+ ) : Event
34
+
35
+ data class Appearance(
36
+ val appearance: PaymentMethodMessagingElement.Appearance,
37
+ ) : Event
38
+ }
39
+
40
+ var latestElementConfig: PaymentMethodMessagingElement.Configuration? = null
41
+
42
+ private val reactContext get() = context as ThemedReactContext
43
+ private val events = Channel<Event>(Channel.UNLIMITED)
44
+
45
+ @SuppressLint("RestrictedApi")
46
+ @Composable
47
+ override fun Content() {
48
+ val messagingElement =
49
+ remember {
50
+ PaymentMethodMessagingElement.create(context.applicationContext as Application)
51
+ }
52
+ var appearance by remember { mutableStateOf(PaymentMethodMessagingElement.Appearance()) }
53
+
54
+ // collect events: configure, appearance
55
+ LaunchedEffect(Unit) {
56
+ events.consumeAsFlow().collect { ev ->
57
+ when (ev) {
58
+ is Event.Configure -> {
59
+ val loadingPayload = Arguments.createMap()
60
+ loadingPayload.putString("status", "loading")
61
+ requireStripeSdkModule().eventEmitter.emitPaymentMethodMessagingElementConfigureResult(loadingPayload)
62
+ val result =
63
+ messagingElement.configure(
64
+ configuration = ev.configuration,
65
+ )
66
+
67
+ val payload = Arguments.createMap()
68
+ when (result) {
69
+ is PaymentMethodMessagingElement.ConfigureResult.Succeeded -> {
70
+ payload.putString("status", "loaded")
71
+ }
72
+ is PaymentMethodMessagingElement.ConfigureResult.NoContent -> {
73
+ payload.putString("status", "no_content")
74
+ reportHeightChange(0f)
75
+ }
76
+ is PaymentMethodMessagingElement.ConfigureResult.Failed -> {
77
+ // send the error back to JS
78
+ val err = result.error
79
+ val msg = err.localizedMessage ?: err.toString()
80
+ // build a RN map
81
+ payload.putString("status", "failed")
82
+ payload.putString("message", msg)
83
+ reportHeightChange(0f)
84
+ }
85
+ }
86
+ requireStripeSdkModule().eventEmitter.emitPaymentMethodMessagingElementConfigureResult(payload)
87
+ }
88
+ is Event.Appearance -> {
89
+ appearance = ev.appearance
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ Box {
96
+ MeasureMessagingElement(
97
+ reportHeightChange = { h -> reportHeightChange(h) },
98
+ ) {
99
+ messagingElement.Content(appearance)
100
+ }
101
+ }
102
+ }
103
+
104
+ @Composable
105
+ private fun MeasureMessagingElement(
106
+ reportHeightChange: (Float) -> Unit,
107
+ content: @Composable () -> Unit,
108
+ ) {
109
+ val density = LocalDensity.current
110
+ var heightDp by remember { mutableStateOf(1.dp) } // non-zero sentinel
111
+
112
+ Box(
113
+ Modifier
114
+ // Post-layout: convert px -> dp, update RN & our dp state
115
+ .onSizeChanged { size ->
116
+ val h = with(density) { size.height.toDp() }
117
+ if (h != heightDp) {
118
+ heightDp = h
119
+ reportHeightChange(h.value) // send dp as Float to RN
120
+ }
121
+ }
122
+ // Custom measure path: force child to its min intrinsic height (in *px*)
123
+ .layout { measurable, constraints ->
124
+ val widthPx = constraints.maxWidth
125
+ val minHpx = measurable.minIntrinsicHeight(widthPx).coerceAtLeast(1)
126
+
127
+ // Measure the child with a tight height equal to min intrinsic
128
+ val placeable =
129
+ measurable.measure(
130
+ constraints.copy(
131
+ minHeight = minHpx,
132
+ maxHeight = minHpx,
133
+ ),
134
+ )
135
+
136
+ // Our own size: use the child’s measured size
137
+ layout(constraints.maxWidth, placeable.height) {
138
+ placeable.placeRelative(IntOffset.Zero)
139
+ }
140
+ },
141
+ ) {
142
+ content()
143
+ }
144
+ }
145
+
146
+ private fun reportHeightChange(height: Float) {
147
+ val params =
148
+ Arguments.createMap().apply {
149
+ putDouble("height", height.toDouble())
150
+ }
151
+ requireStripeSdkModule().eventEmitter.emitPaymentMethodMessagingElementDidUpdateHeight(params)
152
+ }
153
+
154
+ // APIs
155
+ fun configure(config: PaymentMethodMessagingElement.Configuration) {
156
+ events.trySend(Event.Configure(config))
157
+ }
158
+
159
+ fun appearance(appearance: PaymentMethodMessagingElement.Appearance) {
160
+ events.trySend(Event.Appearance(appearance))
161
+ }
162
+
163
+ private fun requireStripeSdkModule() = requireNotNull(reactContext.getNativeModule(StripeSdkModule::class.java))
164
+ }
@@ -0,0 +1,65 @@
1
+ package com.reactnativestripesdk
2
+
3
+ import com.facebook.react.bridge.Dynamic
4
+ import com.facebook.react.module.annotations.ReactModule
5
+ import com.facebook.react.uimanager.ThemedReactContext
6
+ import com.facebook.react.uimanager.ViewGroupManager
7
+ import com.facebook.react.uimanager.annotations.ReactProp
8
+ import com.facebook.react.viewmanagers.PaymentMethodMessagingElementViewManagerDelegate
9
+ import com.facebook.react.viewmanagers.PaymentMethodMessagingElementViewManagerInterface
10
+ import com.reactnativestripesdk.utils.asMapOrNull
11
+ import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElementPreview
12
+
13
+ @OptIn(PaymentMethodMessagingElementPreview::class)
14
+ @ReactModule(name = PaymentMethodMessagingElementViewManager.NAME)
15
+ class PaymentMethodMessagingElementViewManager :
16
+ ViewGroupManager<PaymentMethodMessagingElementView>(),
17
+ PaymentMethodMessagingElementViewManagerInterface<PaymentMethodMessagingElementView> {
18
+ companion object {
19
+ const val NAME = "PaymentMethodMessagingElementView"
20
+ }
21
+
22
+ private val delegate = PaymentMethodMessagingElementViewManagerDelegate(this)
23
+
24
+ override fun getName() = NAME
25
+
26
+ override fun getDelegate() = delegate
27
+
28
+ override fun createViewInstance(ctx: ThemedReactContext): PaymentMethodMessagingElementView = PaymentMethodMessagingElementView(ctx)
29
+
30
+ override fun onDropViewInstance(view: PaymentMethodMessagingElementView) {
31
+ super.onDropViewInstance(view)
32
+
33
+ view.handleOnDropViewInstance()
34
+ }
35
+
36
+ override fun needsCustomLayoutForChildren(): Boolean = true
37
+
38
+ @ReactProp(name = "appearance")
39
+ override fun setAppearance(
40
+ view: PaymentMethodMessagingElementView?,
41
+ value: Dynamic?,
42
+ ) {
43
+ val readableMap = value?.asMapOrNull() ?: return
44
+ view?.let {
45
+ val appearance = parseAppearance(readableMap, view.context)
46
+ view.appearance(appearance)
47
+ }
48
+ }
49
+
50
+ @ReactProp(name = "configuration")
51
+ override fun setConfiguration(
52
+ view: PaymentMethodMessagingElementView,
53
+ cfg: Dynamic,
54
+ ) {
55
+ val readableMap = cfg.asMapOrNull() ?: return
56
+
57
+ val elementConfig = parseElementConfiguration(readableMap)
58
+ view.latestElementConfig = elementConfig
59
+ view.configure(elementConfig)
60
+ view.post {
61
+ view.requestLayout()
62
+ view.invalidate()
63
+ }
64
+ }
65
+ }
@@ -537,7 +537,7 @@ private fun dynamicColorFromParams(
537
537
  }
538
538
 
539
539
  @Throws(PaymentSheetAppearanceException::class)
540
- private fun getFontResId(
540
+ internal fun getFontResId(
541
541
  map: ReadableMap?,
542
542
  key: String,
543
543
  context: Context,
@@ -106,6 +106,8 @@ class PaymentSheetManager(
106
106
  val paymentMethodOrder = arguments.getStringList("paymentMethodOrder")
107
107
  val allowsRemovalOfLastSavedPaymentMethod =
108
108
  arguments.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
109
+ val opensCardScannerAutomatically =
110
+ arguments.getBooleanOr("opensCardScannerAutomatically", false)
109
111
  paymentIntentClientSecret = arguments.getString("paymentIntentClientSecret").orEmpty()
110
112
  setupIntentClientSecret = arguments.getString("setupIntentClientSecret").orEmpty()
111
113
  intentConfiguration =
@@ -283,6 +285,7 @@ class PaymentSheetManager(
283
285
  .preferredNetworks(
284
286
  mapToPreferredNetworks(arguments.getIntegerList("preferredNetworks")),
285
287
  ).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
288
+ .opensCardScannerAutomatically(opensCardScannerAutomatically)
286
289
  .cardBrandAcceptance(mapToCardBrandAcceptance(arguments))
287
290
  .apply {
288
291
  mapToAllowedCardFundingTypes(arguments)?.let { allowedCardFundingTypes(it) }
@@ -430,32 +433,8 @@ class PaymentSheetManager(
430
433
 
431
434
  private fun configureFlowController() {
432
435
  val onFlowControllerConfigure =
433
- PaymentSheet.FlowController.ConfigCallback { _, _ ->
434
- flowController?.getPaymentOption()?.let { paymentOption ->
435
- // Launch async job to convert drawable, but resolve promise synchronously
436
- CoroutineScope(Dispatchers.Default).launch {
437
- val imageString =
438
- try {
439
- convertDrawableToBase64(paymentOption.icon())
440
- } catch (e: Exception) {
441
- val result =
442
- createError(
443
- PaymentSheetErrorType.Failed.toString(),
444
- "Failed to process payment option image: ${e.message}",
445
- )
446
- initPromise.resolve(result)
447
- return@launch
448
- }
449
-
450
- val option: WritableMap = Arguments.createMap()
451
- option.putString("label", paymentOption.label)
452
- option.putString("image", imageString)
453
- val result = createResult("paymentOption", option)
454
- initPromise.resolve(result)
455
- }
456
- } ?: run {
457
- initPromise.resolve(Arguments.createMap())
458
- }
436
+ PaymentSheet.FlowController.ConfigCallback { success, error ->
437
+ handleFlowControllerConfigured(success, error, initPromise, flowController)
459
438
  }
460
439
 
461
440
  if (!paymentIntentClientSecret.isNullOrEmpty()) {
@@ -717,3 +696,44 @@ internal fun mapToPaymentMethodOptions(options: ReadableMap?): PaymentSheet.Inte
717
696
  null
718
697
  }
719
698
  }
699
+
700
+ internal fun handleFlowControllerConfigured(
701
+ success: Boolean,
702
+ error: Throwable?,
703
+ promise: Promise,
704
+ flowController: PaymentSheet.FlowController?,
705
+ ) {
706
+ if (!success) {
707
+ promise.resolve(
708
+ createError(
709
+ PaymentSheetErrorType.Failed.toString(),
710
+ error?.message ?: "Failed to configure payment sheet",
711
+ ),
712
+ )
713
+ return
714
+ }
715
+ flowController?.getPaymentOption()?.let { paymentOption ->
716
+ CoroutineScope(Dispatchers.Default).launch {
717
+ val imageString =
718
+ try {
719
+ convertDrawableToBase64(paymentOption.icon())
720
+ } catch (e: Exception) {
721
+ val result =
722
+ createError(
723
+ PaymentSheetErrorType.Failed.toString(),
724
+ "Failed to process payment option image: ${e.message}",
725
+ )
726
+ promise.resolve(result)
727
+ return@launch
728
+ }
729
+
730
+ val option: WritableMap = Arguments.createMap()
731
+ option.putString("label", paymentOption.label)
732
+ option.putString("image", imageString)
733
+ val result = createResult("paymentOption", option)
734
+ promise.resolve(result)
735
+ }
736
+ } ?: run {
737
+ promise.resolve(Arguments.createMap())
738
+ }
739
+ }