@stripe/stripe-react-native 0.55.0 → 0.56.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 (135) hide show
  1. package/android/.idea/AndroidProjectSystem.xml +6 -0
  2. package/android/.idea/caches/deviceStreaming.xml +703 -0
  3. package/android/.idea/compiler.xml +6 -0
  4. package/android/.idea/gradle.xml +18 -0
  5. package/android/.idea/migrations.xml +10 -0
  6. package/android/.idea/misc.xml +10 -0
  7. package/android/.idea/runConfigurations.xml +17 -0
  8. package/android/.idea/vcs.xml +6 -0
  9. package/android/gradle.properties +1 -1
  10. package/android/local.properties +8 -0
  11. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +120 -57
  12. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +5 -0
  13. package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +12 -0
  14. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +1 -0
  15. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +54 -8
  16. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +3 -2
  17. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +64 -0
  18. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetFragment.kt +72 -34
  19. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +37 -0
  20. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +84 -1
  21. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +12 -0
  22. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +4 -0
  23. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +12 -64
  24. package/ios/ApplePayButtonManager.m +1 -1
  25. package/ios/ApplePayButtonView.swift +2 -2
  26. package/ios/Mappers.swift +111 -18
  27. package/ios/NewArch/ApplePayButtonComponentView.mm +1 -1
  28. package/ios/OldArch/StripeSdkEventEmitterCompat.h +3 -0
  29. package/ios/OldArch/StripeSdkEventEmitterCompat.m +18 -0
  30. package/ios/StripeSdk.mm +21 -0
  31. package/ios/StripeSdkEmitter.swift +3 -0
  32. package/ios/StripeSdkImpl+CustomerSheet.swift +70 -19
  33. package/ios/StripeSdkImpl+Embedded.swift +26 -4
  34. package/ios/StripeSdkImpl+PaymentSheet.swift +46 -15
  35. package/ios/StripeSdkImpl.swift +21 -2
  36. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  37. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  38. package/lib/commonjs/components/AddressSheet.js +1 -1
  39. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  40. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  41. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  42. package/lib/commonjs/components/CardField.js +1 -1
  43. package/lib/commonjs/components/CardField.js.map +1 -1
  44. package/lib/commonjs/components/CardForm.js +1 -1
  45. package/lib/commonjs/components/CardForm.js.map +1 -1
  46. package/lib/commonjs/components/CustomerSheet.js +1 -1
  47. package/lib/commonjs/components/CustomerSheet.js.map +1 -1
  48. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  49. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  50. package/lib/commonjs/components/StripeContainer.js +1 -1
  51. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  52. package/lib/commonjs/events.js.map +1 -1
  53. package/lib/commonjs/functions.js +1 -1
  54. package/lib/commonjs/functions.js.map +1 -1
  55. package/lib/commonjs/index.js +1 -1
  56. package/lib/commonjs/index.js.map +1 -1
  57. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  58. package/lib/commonjs/specs/NativeApplePayButton.js.map +1 -1
  59. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  60. package/lib/commonjs/types/ConfirmationToken.js +2 -0
  61. package/lib/commonjs/types/ConfirmationToken.js.map +1 -0
  62. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  63. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  64. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  65. package/lib/commonjs/types/index.js +1 -1
  66. package/lib/commonjs/types/index.js.map +1 -1
  67. package/lib/module/components/AddToWalletButton.js +1 -1
  68. package/lib/module/components/AddToWalletButton.js.map +1 -1
  69. package/lib/module/components/AddressSheet.js +1 -1
  70. package/lib/module/components/AddressSheet.js.map +1 -1
  71. package/lib/module/components/AuBECSDebitForm.js +1 -1
  72. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  73. package/lib/module/components/CardField.js +1 -1
  74. package/lib/module/components/CardField.js.map +1 -1
  75. package/lib/module/components/CardForm.js +1 -1
  76. package/lib/module/components/CardForm.js.map +1 -1
  77. package/lib/module/components/CustomerSheet.js +1 -1
  78. package/lib/module/components/CustomerSheet.js.map +1 -1
  79. package/lib/module/components/PlatformPayButton.js +1 -1
  80. package/lib/module/components/PlatformPayButton.js.map +1 -1
  81. package/lib/module/components/StripeContainer.js +1 -1
  82. package/lib/module/components/StripeContainer.js.map +1 -1
  83. package/lib/module/events.js.map +1 -1
  84. package/lib/module/functions.js +1 -1
  85. package/lib/module/functions.js.map +1 -1
  86. package/lib/module/index.js +1 -1
  87. package/lib/module/index.js.map +1 -1
  88. package/lib/module/specs/NativeApplePayButton.js +1 -1
  89. package/lib/module/specs/NativeApplePayButton.js.map +1 -1
  90. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  91. package/lib/module/types/ConfirmationToken.js +2 -0
  92. package/lib/module/types/ConfirmationToken.js.map +1 -0
  93. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  94. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  95. package/lib/module/types/PaymentSheet.js.map +1 -1
  96. package/lib/module/types/index.js +1 -1
  97. package/lib/module/types/index.js.map +1 -1
  98. package/lib/typescript/src/components/CustomerSheet.d.ts +1 -1
  99. package/lib/typescript/src/components/CustomerSheet.d.ts.map +1 -1
  100. package/lib/typescript/src/events.d.ts +6 -0
  101. package/lib/typescript/src/events.d.ts.map +1 -1
  102. package/lib/typescript/src/functions.d.ts.map +1 -1
  103. package/lib/typescript/src/index.d.ts +1 -0
  104. package/lib/typescript/src/index.d.ts.map +1 -1
  105. package/lib/typescript/src/specs/NativeApplePayButton.d.ts +1 -1
  106. package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -1
  107. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +4 -1
  108. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  109. package/lib/typescript/src/types/ConfirmationToken.d.ts +56 -0
  110. package/lib/typescript/src/types/ConfirmationToken.d.ts.map +1 -0
  111. package/lib/typescript/src/types/CustomerSheet.d.ts +70 -12
  112. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  113. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +2 -4
  114. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  115. package/lib/typescript/src/types/PaymentSheet.d.ts +26 -4
  116. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  117. package/lib/typescript/src/types/index.d.ts +2 -1
  118. package/lib/typescript/src/types/index.d.ts.map +1 -1
  119. package/package.json +1 -1
  120. package/src/components/CustomerSheet.tsx +65 -9
  121. package/src/components/PlatformPayButton.tsx +1 -1
  122. package/src/events.ts +6 -0
  123. package/src/functions.ts +16 -0
  124. package/src/index.tsx +1 -0
  125. package/src/specs/NativeApplePayButton.ts +1 -1
  126. package/src/specs/NativeStripeSdkModule.ts +10 -0
  127. package/src/types/ConfirmationToken.ts +73 -0
  128. package/src/types/CustomerSheet.ts +80 -12
  129. package/src/types/EmbeddedPaymentElement.tsx +23 -4
  130. package/src/types/PaymentSheet.ts +31 -12
  131. package/src/types/index.ts +2 -0
  132. package/stripe-react-native.podspec +1 -1
  133. package/ios/StripeSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  134. package/ios/StripeSdk.xcodeproj/project.xcworkspace/xcuserdata/wooj.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  135. package/ios/StripeSdk.xcodeproj/xcuserdata/wooj.xcuserdatad/xcschemes/xcschememanagement.plist +0 -19
@@ -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>
@@ -3,4 +3,4 @@ StripeSdk_compileSdkVersion=30
3
3
  StripeSdk_targetSdkVersion=28
4
4
  StripeSdk_minSdkVersion=21
5
5
  # Keep StripeSdk_stripeVersion in sync with https://github.com/stripe/stripe-identity-react-native/blob/main/android/gradle.properties
6
- StripeSdk_stripeVersion=21.26.+
6
+ StripeSdk_stripeVersion=21.29.+
@@ -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
@@ -1,5 +1,6 @@
1
1
  package com.reactnativestripesdk
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.content.Context
4
5
  import android.content.Intent
5
6
  import android.util.Log
@@ -23,6 +24,7 @@ import com.facebook.react.bridge.Arguments
23
24
  import com.facebook.react.uimanager.ThemedReactContext
24
25
  import com.reactnativestripesdk.toWritableMap
25
26
  import com.reactnativestripesdk.utils.KeepJsAwakeTask
27
+ import com.reactnativestripesdk.utils.mapFromConfirmationToken
26
28
  import com.reactnativestripesdk.utils.mapFromCustomPaymentMethod
27
29
  import com.reactnativestripesdk.utils.mapFromPaymentMethod
28
30
  import com.stripe.android.model.PaymentMethod
@@ -63,10 +65,16 @@ class EmbeddedPaymentElementView(
63
65
  var latestElementConfig: EmbeddedPaymentElement.Configuration? = null
64
66
 
65
67
  val rowSelectionBehaviorType = mutableStateOf<RowSelectionBehaviorType?>(null)
68
+ val useConfirmationTokenCallback = mutableStateOf(false)
66
69
 
67
70
  private val reactContext get() = context as ThemedReactContext
68
71
  private val events = Channel<Event>(Channel.UNLIMITED)
69
72
 
73
+ fun setUseConfirmationTokenCallback(value: Boolean) {
74
+ useConfirmationTokenCallback.value = value
75
+ }
76
+
77
+ @SuppressLint("RestrictedApi")
70
78
  @OptIn(ExperimentalCustomPaymentMethodsApi::class)
71
79
  @Composable
72
80
  override fun Content() {
@@ -153,73 +161,128 @@ class EmbeddedPaymentElementView(
153
161
  }
154
162
  }
155
163
 
156
- val builder =
157
- remember(type) {
158
- EmbeddedPaymentElement
159
- .Builder(
160
- createIntentCallback = { paymentMethod, shouldSavePaymentMethod ->
161
- val stripeSdkModule =
162
- try {
163
- requireStripeSdkModule()
164
- } catch (ex: IllegalArgumentException) {
165
- return@Builder CreateIntentResult.Failure(
166
- cause =
167
- Exception(
168
- "Tried to call confirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
169
- ),
170
- displayMessage = "An unexpected error occurred",
171
- )
164
+ val useConfirmationToken by remember { useConfirmationTokenCallback }
165
+
166
+ val resultCallback =
167
+ remember {
168
+ { result: EmbeddedPaymentElement.Result ->
169
+ val map =
170
+ Arguments.createMap().apply {
171
+ when (result) {
172
+ is EmbeddedPaymentElement.Result.Completed -> {
173
+ putString("status", "completed")
172
174
  }
173
175
 
174
- // Make sure that JS is active since the activity will be paused when stripe ui is presented.
175
- val keepJsAwakeTask =
176
- KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
176
+ is EmbeddedPaymentElement.Result.Canceled -> {
177
+ putString("status", "canceled")
178
+ }
177
179
 
178
- val params =
179
- Arguments.createMap().apply {
180
- putMap("paymentMethod", mapFromPaymentMethod(paymentMethod))
181
- putBoolean("shouldSavePaymentMethod", shouldSavePaymentMethod)
180
+ is EmbeddedPaymentElement.Result.Failed -> {
181
+ putString("status", "failed")
182
+ putString("error", result.error.message ?: "Unknown error")
182
183
  }
184
+ }
185
+ }
186
+ requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
187
+ }
188
+ }
183
189
 
184
- stripeSdkModule.eventEmitter.emitOnConfirmHandlerCallback(params)
190
+ val builder =
191
+ remember(type, useConfirmationToken) {
192
+ if (useConfirmationToken) {
193
+ EmbeddedPaymentElement
194
+ .Builder(
195
+ createIntentCallback = { confirmationToken ->
196
+ val stripeSdkModule =
197
+ try {
198
+ requireStripeSdkModule()
199
+ } catch (ex: IllegalArgumentException) {
200
+ return@Builder CreateIntentResult.Failure(
201
+ cause =
202
+ Exception(
203
+ "Tried to call confirmationTokenConfirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
204
+ ),
205
+ displayMessage = "An unexpected error occurred",
206
+ )
207
+ }
185
208
 
186
- val resultFromJavascript = stripeSdkModule.embeddedIntentCreationCallback.await()
187
- // reset the completable
188
- stripeSdkModule.embeddedIntentCreationCallback = CompletableDeferred()
209
+ // Make sure that JS is active since the activity will be paused when stripe ui is presented.
210
+ val keepJsAwakeTask =
211
+ KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
189
212
 
190
- keepJsAwakeTask.stop()
213
+ val params =
214
+ Arguments.createMap().apply {
215
+ putMap("confirmationToken", mapFromConfirmationToken(confirmationToken))
216
+ }
191
217
 
192
- resultFromJavascript.getString("clientSecret")?.let {
193
- CreateIntentResult.Success(clientSecret = it)
194
- } ?: run {
195
- val errorMap = resultFromJavascript.getMap("error")
196
- CreateIntentResult.Failure(
197
- cause = Exception(errorMap?.getString("message")),
198
- displayMessage = errorMap?.getString("localizedMessage"),
199
- )
200
- }
201
- },
202
- resultCallback = { result ->
203
- val map =
204
- Arguments.createMap().apply {
205
- when (result) {
206
- is EmbeddedPaymentElement.Result.Completed -> {
207
- putString("status", "completed")
208
- }
209
-
210
- is EmbeddedPaymentElement.Result.Canceled -> {
211
- putString("status", "canceled")
212
- }
213
-
214
- is EmbeddedPaymentElement.Result.Failed -> {
215
- putString("status", "failed")
216
- putString("error", result.error.message ?: "Unknown error")
217
- }
218
+ stripeSdkModule.eventEmitter.emitOnConfirmationTokenHandlerCallback(params)
219
+
220
+ val resultFromJavascript = stripeSdkModule.embeddedConfirmationTokenCreationCallback.await()
221
+ // reset the completable
222
+ stripeSdkModule.embeddedConfirmationTokenCreationCallback = CompletableDeferred()
223
+
224
+ keepJsAwakeTask.stop()
225
+
226
+ resultFromJavascript.getString("clientSecret")?.let {
227
+ CreateIntentResult.Success(clientSecret = it)
228
+ } ?: run {
229
+ val errorMap = resultFromJavascript.getMap("error")
230
+ CreateIntentResult.Failure(
231
+ cause = Exception(errorMap?.getString("message")),
232
+ displayMessage = errorMap?.getString("localizedMessage"),
233
+ )
234
+ }
235
+ },
236
+ resultCallback = resultCallback,
237
+ )
238
+ } else {
239
+ EmbeddedPaymentElement
240
+ .Builder(
241
+ createIntentCallback = { paymentMethod, shouldSavePaymentMethod ->
242
+ val stripeSdkModule =
243
+ try {
244
+ requireStripeSdkModule()
245
+ } catch (ex: IllegalArgumentException) {
246
+ return@Builder CreateIntentResult.Failure(
247
+ cause =
248
+ Exception(
249
+ "Tried to call confirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
250
+ ),
251
+ displayMessage = "An unexpected error occurred",
252
+ )
218
253
  }
254
+
255
+ // Make sure that JS is active since the activity will be paused when stripe ui is presented.
256
+ val keepJsAwakeTask =
257
+ KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
258
+
259
+ val params =
260
+ Arguments.createMap().apply {
261
+ putMap("paymentMethod", mapFromPaymentMethod(paymentMethod))
262
+ putBoolean("shouldSavePaymentMethod", shouldSavePaymentMethod)
263
+ }
264
+
265
+ stripeSdkModule.eventEmitter.emitOnConfirmHandlerCallback(params)
266
+
267
+ val resultFromJavascript = stripeSdkModule.embeddedIntentCreationCallback.await()
268
+ // reset the completable
269
+ stripeSdkModule.embeddedIntentCreationCallback = CompletableDeferred()
270
+
271
+ keepJsAwakeTask.stop()
272
+
273
+ resultFromJavascript.getString("clientSecret")?.let {
274
+ CreateIntentResult.Success(clientSecret = it)
275
+ } ?: run {
276
+ val errorMap = resultFromJavascript.getMap("error")
277
+ CreateIntentResult.Failure(
278
+ cause = Exception(errorMap?.getString("message")),
279
+ displayMessage = errorMap?.getString("localizedMessage"),
280
+ )
219
281
  }
220
- requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
221
- },
222
- ).confirmCustomPaymentMethodCallback(confirmCustomPaymentMethodCallback)
282
+ },
283
+ resultCallback = resultCallback,
284
+ )
285
+ }.confirmCustomPaymentMethodCallback(confirmCustomPaymentMethodCallback)
223
286
  .rowSelectionBehavior(
224
287
  if (type == RowSelectionBehaviorType.Default) {
225
288
  EmbeddedPaymentElement.RowSelectionBehavior.default()
@@ -80,6 +80,11 @@ class EmbeddedPaymentElementViewManager :
80
80
  ) {
81
81
  val readableMap = cfg.asMap()
82
82
  if (readableMap == null) return
83
+
84
+ // Detect which callback type to use based on the presence of the confirmation token handler
85
+ val useConfirmationTokenCallback = readableMap.hasKey("confirmationTokenConfirmHandler")
86
+ view.setUseConfirmationTokenCallback(useConfirmationTokenCallback)
87
+
83
88
  val intentConfig = parseIntentConfiguration(readableMap)
84
89
  view.latestIntentConfig = intentConfig
85
90
  view.latestElementConfig?.let { elemCfg ->
@@ -24,6 +24,10 @@ class EventEmitterCompat(
24
24
  invoke("onConfirmHandlerCallback", value)
25
25
  }
26
26
 
27
+ fun emitOnConfirmationTokenHandlerCallback(value: ReadableMap?) {
28
+ invoke("onConfirmationTokenHandlerCallback", value)
29
+ }
30
+
27
31
  fun emitOnFinancialConnectionsEvent(value: ReadableMap?) {
28
32
  invoke("onFinancialConnectionsEvent", value)
29
33
  }
@@ -56,6 +60,14 @@ class EventEmitterCompat(
56
60
  invoke("onCustomerAdapterSetupIntentClientSecretForCustomerAttachCallback")
57
61
  }
58
62
 
63
+ fun emitOnCustomerSessionProviderSetupIntentClientSecret() {
64
+ invoke("onCustomerSessionProviderSetupIntentClientSecret")
65
+ }
66
+
67
+ fun emitOnCustomerSessionProviderCustomerSessionClientSecret() {
68
+ invoke("onCustomerSessionProviderCustomerSessionClientSecret")
69
+ }
70
+
59
71
  fun emitEmbeddedPaymentElementDidUpdateHeight(value: ReadableMap?) {
60
72
  invoke("embeddedPaymentElementDidUpdateHeight", value)
61
73
  }
@@ -384,6 +384,7 @@ class PaymentLauncherFragment : StripeFragment() {
384
384
  StripeIntent.NextActionType.VerifyWithMicrodeposits,
385
385
  StripeIntent.NextActionType.DisplayMultibancoDetails,
386
386
  StripeIntent.NextActionType.DisplayPayNowDetails,
387
+ StripeIntent.NextActionType.DisplayPromptPayDetails,
387
388
  -> true
388
389
  StripeIntent.NextActionType.RedirectToUrl,
389
390
  StripeIntent.NextActionType.UseStripeSdk,
@@ -1,5 +1,6 @@
1
1
  package com.reactnativestripesdk
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.app.Activity
4
5
  import android.app.Application
5
6
  import android.content.Context
@@ -30,6 +31,7 @@ import com.reactnativestripesdk.utils.PaymentSheetException
30
31
  import com.reactnativestripesdk.utils.StripeFragment
31
32
  import com.reactnativestripesdk.utils.createError
32
33
  import com.reactnativestripesdk.utils.createResult
34
+ import com.reactnativestripesdk.utils.mapFromConfirmationToken
33
35
  import com.reactnativestripesdk.utils.mapFromCustomPaymentMethod
34
36
  import com.reactnativestripesdk.utils.mapFromPaymentMethod
35
37
  import com.reactnativestripesdk.utils.mapToPreferredNetworks
@@ -38,6 +40,7 @@ import com.reactnativestripesdk.utils.removeFragment
38
40
  import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
39
41
  import com.stripe.android.model.PaymentMethod
40
42
  import com.stripe.android.paymentelement.ConfirmCustomPaymentMethodCallback
43
+ import com.stripe.android.paymentelement.CreateIntentWithConfirmationTokenCallback
41
44
  import com.stripe.android.paymentelement.CustomPaymentMethodResult
42
45
  import com.stripe.android.paymentelement.CustomPaymentMethodResultHandler
43
46
  import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
@@ -73,8 +76,10 @@ class PaymentSheetFragment :
73
76
  private var presentPromise: Promise? = null
74
77
  private var paymentSheetTimedOut = false
75
78
  internal var paymentSheetIntentCreationCallback = CompletableDeferred<ReadableMap>()
79
+ internal var paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
76
80
  private var keepJsAwake: KeepJsAwakeTask? = null
77
81
 
82
+ @SuppressLint("RestrictedApi")
78
83
  @OptIn(ExperimentalCustomPaymentMethodsApi::class)
79
84
  override fun prepare() {
80
85
  val merchantDisplayName = arguments?.getString("merchantDisplayName").orEmpty()
@@ -102,6 +107,10 @@ class PaymentSheetFragment :
102
107
  initPromise.resolve(createError(ErrorType.Failed.toString(), error))
103
108
  return
104
109
  }
110
+
111
+ // Determine which callback type to use based on what's provided
112
+ val intentConfigBundle = arguments?.getBundle("intentConfiguration")
113
+ val useConfirmationTokenCallback = intentConfigBundle?.containsKey("confirmationTokenConfirmHandler") == true
105
114
  val appearance =
106
115
  try {
107
116
  buildPaymentSheetAppearance(arguments?.getBundle("appearance"), context)
@@ -212,6 +221,32 @@ class PaymentSheetFragment :
212
221
  }
213
222
  }
214
223
 
224
+ val createConfirmationTokenCallback =
225
+ CreateIntentWithConfirmationTokenCallback { confirmationToken ->
226
+ val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
227
+ val params =
228
+ Arguments.createMap().apply {
229
+ putMap("confirmationToken", mapFromConfirmationToken(confirmationToken))
230
+ }
231
+
232
+ stripeSdkModule?.eventEmitter?.emitOnConfirmationTokenHandlerCallback(params)
233
+
234
+ val resultFromJavascript = paymentSheetConfirmationTokenCreationCallback.await()
235
+ // reset the completable
236
+ paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
237
+
238
+ return@CreateIntentWithConfirmationTokenCallback resultFromJavascript.getString("clientSecret")?.let {
239
+ CreateIntentResult.Success(clientSecret = it)
240
+ }
241
+ ?: run {
242
+ val errorMap = resultFromJavascript.getMap("error")
243
+ CreateIntentResult.Failure(
244
+ cause = Exception(errorMap?.getString("message")),
245
+ displayMessage = errorMap?.getString("localizedMessage"),
246
+ )
247
+ }
248
+ }
249
+
215
250
  val billingDetailsConfig =
216
251
  PaymentSheet.BillingDetailsCollectionConfiguration(
217
252
  name = mapToCollectionMode(billingConfigParams?.getString("name")),
@@ -271,11 +306,18 @@ class PaymentSheetFragment :
271
306
  if (arguments?.getBoolean("customFlow") == true) {
272
307
  flowController =
273
308
  if (intentConfiguration != null) {
274
- PaymentSheet.FlowController
275
- .Builder(
276
- resultCallback = paymentResultCallback,
277
- paymentOptionResultCallback = paymentOptionCallback,
278
- ).createIntentCallback(createIntentCallback)
309
+ val builder =
310
+ PaymentSheet.FlowController
311
+ .Builder(
312
+ resultCallback = paymentResultCallback,
313
+ paymentOptionResultCallback = paymentOptionCallback,
314
+ )
315
+ if (useConfirmationTokenCallback) {
316
+ builder.createIntentCallback(createConfirmationTokenCallback)
317
+ } else {
318
+ builder.createIntentCallback(createIntentCallback)
319
+ }
320
+ builder
279
321
  .confirmCustomPaymentMethodCallback(this)
280
322
  .build(this)
281
323
  } else {
@@ -290,9 +332,13 @@ class PaymentSheetFragment :
290
332
  } else {
291
333
  paymentSheet =
292
334
  if (intentConfiguration != null) {
293
- PaymentSheet
294
- .Builder(paymentResultCallback)
295
- .createIntentCallback(createIntentCallback)
335
+ val builder = PaymentSheet.Builder(paymentResultCallback)
336
+ if (useConfirmationTokenCallback) {
337
+ builder.createIntentCallback(createConfirmationTokenCallback)
338
+ } else {
339
+ builder.createIntentCallback(createIntentCallback)
340
+ }
341
+ builder
296
342
  .confirmCustomPaymentMethodCallback(this)
297
343
  .build(this)
298
344
  } else {
@@ -107,7 +107,8 @@ abstract class StripeAbstractComposeView(
107
107
  }
108
108
 
109
109
  fun handleOnDropViewInstance() {
110
- // Update the lifecycle state to DESTROYED to cause the composition to be destroyed.
111
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
110
+ if (lifecycleRegistry.currentState.isAtLeast(Lifecycle.State.CREATED)) {
111
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
112
+ }
112
113
  }
113
114
  }
@@ -55,6 +55,7 @@ import com.stripe.android.PaymentConfiguration
55
55
  import com.stripe.android.Stripe
56
56
  import com.stripe.android.core.ApiVersion
57
57
  import com.stripe.android.core.AppInfo
58
+ import com.stripe.android.customersheet.CustomerSheet
58
59
  import com.stripe.android.googlepaylauncher.GooglePayLauncher
59
60
  import com.stripe.android.model.BankAccountTokenParams
60
61
  import com.stripe.android.model.CardParams
@@ -65,6 +66,7 @@ import com.stripe.android.model.PaymentMethod
65
66
  import com.stripe.android.model.SetupIntent
66
67
  import com.stripe.android.model.Token
67
68
  import com.stripe.android.payments.bankaccount.CollectBankAccountConfiguration
69
+ import com.stripe.android.paymentsheet.ExperimentalCustomerSessionApi
68
70
  import com.stripe.android.paymentsheet.PaymentSheet
69
71
  import kotlinx.coroutines.CompletableDeferred
70
72
  import kotlinx.coroutines.CoroutineScope
@@ -94,7 +96,9 @@ class StripeSdkModule(
94
96
  private var customerSheetFragment: CustomerSheetFragment? = null
95
97
 
96
98
  internal var embeddedIntentCreationCallback = CompletableDeferred<ReadableMap>()
99
+ internal var embeddedConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
97
100
  internal var customPaymentMethodResultCallback = CompletableDeferred<ReadableMap>()
101
+ internal var paymentSheetConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
98
102
 
99
103
  internal var composeCompatView: StripeAbstractComposeView.CompatView? = null
100
104
 
@@ -323,6 +327,22 @@ class StripeSdkModule(
323
327
  promise?.resolve(null)
324
328
  }
325
329
 
330
+ @ReactMethod
331
+ override fun confirmationTokenCreationCallback(
332
+ params: ReadableMap,
333
+ promise: Promise,
334
+ ) {
335
+ embeddedConfirmationTokenCreationCallback.complete(params)
336
+ paymentSheetConfirmationTokenCreationCallback.complete(params)
337
+
338
+ if (paymentSheetFragment == null) {
339
+ promise.resolve(PaymentSheetFragment.createMissingInitError())
340
+ return
341
+ }
342
+
343
+ paymentSheetFragment?.paymentSheetConfirmationTokenCreationCallback?.complete(params)
344
+ }
345
+
326
346
  @ReactMethod
327
347
  override fun createPaymentMethod(
328
348
  data: ReadableMap,
@@ -1267,6 +1287,50 @@ class StripeSdkModule(
1267
1287
  }
1268
1288
  }
1269
1289
 
1290
+ @OptIn(ExperimentalCustomerSessionApi::class)
1291
+ @ReactMethod
1292
+ override fun clientSecretProviderSetupIntentClientSecretCallback(
1293
+ setupIntentClientSecret: String,
1294
+ promise: Promise,
1295
+ ) {
1296
+ customerSheetFragment?.let {
1297
+ it.customerSessionProvider?.provideSetupIntentClientSecretCallback?.complete(setupIntentClientSecret)
1298
+ } ?: run {
1299
+ promise.resolve(CustomerSheetFragment.createMissingInitError())
1300
+ return
1301
+ }
1302
+ }
1303
+
1304
+ @OptIn(ExperimentalCustomerSessionApi::class)
1305
+ @ReactMethod
1306
+ override fun clientSecretProviderCustomerSessionClientSecretCallback(
1307
+ customerSessionClientSecretJson: ReadableMap,
1308
+ promise: Promise,
1309
+ ) {
1310
+ val clientSecret = customerSessionClientSecretJson.getString("clientSecret")
1311
+ val customerId = customerSessionClientSecretJson.getString("customerId")
1312
+
1313
+ if (clientSecret.isNullOrEmpty() || customerId.isNullOrEmpty()) {
1314
+ Log.e(
1315
+ "StripeReactNative",
1316
+ "Invalid CustomerSessionClientSecret format",
1317
+ )
1318
+ return
1319
+ }
1320
+
1321
+ customerSheetFragment?.let {
1322
+ it.customerSessionProvider?.providesCustomerSessionClientSecretCallback?.complete(
1323
+ CustomerSheet.CustomerSessionClientSecret.create(
1324
+ customerId = customerId!!,
1325
+ clientSecret = clientSecret!!,
1326
+ ),
1327
+ )
1328
+ } ?: run {
1329
+ promise.resolve(CustomerSheetFragment.createMissingInitError())
1330
+ return
1331
+ }
1332
+ }
1333
+
1270
1334
  @ReactMethod
1271
1335
  override fun createEmbeddedPaymentElement(
1272
1336
  intentConfig: ReadableMap,