@stripe/stripe-react-native 0.40.0 → 0.42.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 (54) hide show
  1. package/CHANGELOG.md +19 -2
  2. package/README.md +3 -0
  3. package/android/.project +11 -0
  4. package/android/.settings/org.eclipse.buildship.core.prefs +3 -3
  5. package/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt +21 -0
  6. package/android/src/main/java/com/reactnativestripesdk/FinancialConnectionsSheetFragment.kt +20 -0
  7. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +114 -35
  8. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +50 -0
  9. package/ios/FinancialConnections.swift +14 -2
  10. package/ios/Mappers.swift +23 -0
  11. package/ios/PaymentMethodFactory.swift +31 -29
  12. package/ios/StripeSdk.swift +50 -19
  13. package/lib/commonjs/NativeStripeSdk.js.map +1 -1
  14. package/lib/commonjs/functions.js +1 -1
  15. package/lib/commonjs/functions.js.map +1 -1
  16. package/lib/commonjs/hooks/useFinancialConnectionsSheet.js +1 -1
  17. package/lib/commonjs/hooks/useFinancialConnectionsSheet.js.map +1 -1
  18. package/lib/commonjs/hooks/useStripe.js +1 -1
  19. package/lib/commonjs/hooks/useStripe.js.map +1 -1
  20. package/lib/commonjs/types/FinancialConnections.js +1 -1
  21. package/lib/commonjs/types/FinancialConnections.js.map +1 -1
  22. package/lib/commonjs/types/PaymentIntent.js.map +1 -1
  23. package/lib/commonjs/types/PaymentMethod.js.map +1 -1
  24. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  25. package/lib/module/NativeStripeSdk.js.map +1 -1
  26. package/lib/module/functions.js +1 -1
  27. package/lib/module/functions.js.map +1 -1
  28. package/lib/module/hooks/useFinancialConnectionsSheet.js +1 -1
  29. package/lib/module/hooks/useFinancialConnectionsSheet.js.map +1 -1
  30. package/lib/module/hooks/useStripe.js +1 -1
  31. package/lib/module/hooks/useStripe.js.map +1 -1
  32. package/lib/module/types/FinancialConnections.js +1 -1
  33. package/lib/module/types/FinancialConnections.js.map +1 -1
  34. package/lib/module/types/PaymentIntent.js.map +1 -1
  35. package/lib/module/types/PaymentMethod.js.map +1 -1
  36. package/lib/module/types/PaymentSheet.js.map +1 -1
  37. package/lib/typescript/src/NativeStripeSdk.d.ts +1 -1
  38. package/lib/typescript/src/functions.d.ts +6 -2
  39. package/lib/typescript/src/hooks/useFinancialConnectionsSheet.d.ts +4 -2
  40. package/lib/typescript/src/hooks/useStripe.d.ts +2 -2
  41. package/lib/typescript/src/types/FinancialConnections.d.ts +64 -0
  42. package/lib/typescript/src/types/PaymentIntent.d.ts +26 -0
  43. package/lib/typescript/src/types/PaymentMethod.d.ts +7 -0
  44. package/lib/typescript/src/types/PaymentSheet.d.ts +1 -1
  45. package/package.json +2 -2
  46. package/src/NativeStripeSdk.tsx +1 -1
  47. package/src/functions.ts +57 -2
  48. package/src/hooks/useFinancialConnectionsSheet.tsx +12 -4
  49. package/src/hooks/useStripe.tsx +10 -4
  50. package/src/types/FinancialConnections.ts +69 -0
  51. package/src/types/PaymentIntent.ts +30 -1
  52. package/src/types/PaymentMethod.ts +8 -0
  53. package/src/types/PaymentSheet.ts +1 -1
  54. package/stripe-react-native.podspec +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.42.0 - 2025-02-25
6
+
7
+ **Features**
8
+
9
+ - Added ability to pass an `onEvent` listener to Financial Connections methods via a `params` argument. This includes the following methods, both when used directly or via `useStripe` or `useFinancialConnectionsSheet`:
10
+ - `collectBankAccountForPayment`
11
+ - `collectBankAccountForSetup`
12
+ - `collectBankAccountToken`
13
+ - `collectFinancialConnectionsAccounts`
14
+ - Added ability to pass `metadata` to `PaymentMethod.ConfirmParams` and `PaymentMethod.CreateParams`
15
+
16
+ ## 0.41.0 - 2024-12-19
17
+
18
+ **Fixes**
19
+
20
+ - Updated `stripe-ios` to 24.2.\*
21
+
5
22
  ## 0.40.0 - 2024-11-19
6
23
 
7
24
  **Breaking changes**
@@ -24,8 +41,8 @@
24
41
 
25
42
  **Fixes**
26
43
 
27
- * Updated `stripe-ios` to 23.30.\*
28
- * Updated `stripe-android` to 20.52.\*
44
+ - Updated `stripe-ios` to 23.30.\*
45
+ - Updated `stripe-android` to 20.52.\*
29
46
 
30
47
  ## 0.38.6 - 2024-09-04
31
48
 
package/README.md CHANGED
@@ -5,6 +5,9 @@
5
5
 
6
6
  The Stripe React Native SDK allows you to build delightful payment experiences in your native Android and iOS apps using React Native. We provide powerful and customizable UI screens and elements that can be used out-of-the-box to collect your users' payment details.
7
7
 
8
+ > [!WARNING]
9
+ > Until we support React Native's [New Architecture](https://reactnative.dev/blog/2024/10/23/the-new-architecture-is-here), if you are using React Native 0.76 or higher, we recommend [opting out](https://reactnative.dev/blog/2024/10/23/the-new-architecture-is-here#opt-out) of it.
10
+
8
11
  ## Getting started
9
12
 
10
13
  Get started with our [📚 integration guides](https://stripe.com/docs/payments/accept-a-payment?platform=react-native) and [example project](./CONTRIBUTING.md#running-the-example-app), or [📘 browse the SDK reference](https://stripe.dev/stripe-react-native).
package/android/.project CHANGED
@@ -14,4 +14,15 @@
14
14
  <natures>
15
15
  <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16
16
  </natures>
17
+ <filteredResources>
18
+ <filter>
19
+ <id>1740526494888</id>
20
+ <name></name>
21
+ <type>30</type>
22
+ <matcher>
23
+ <id>org.eclipse.core.resources.regexFilterMatcher</id>
24
+ <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
25
+ </matcher>
26
+ </filter>
27
+ </filteredResources>
17
28
  </projectDescription>
@@ -1,11 +1,11 @@
1
- arguments=
1
+ arguments=--init-script /var/folders/qg/5wmspvx516145k8z2q01c8_m0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/qg/5wmspvx516145k8z2q01c8_m0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
2
2
  auto.sync=false
3
3
  build.scans.enabled=false
4
- connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0))
4
+ connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(8.9))
5
5
  connection.project.dir=
6
6
  eclipse.preferences.version=1
7
7
  gradle.user.home=
8
- java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
8
+ java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
9
9
  jvm.arguments=
10
10
  offline.mode=false
11
11
  override.workspace.settings=true
@@ -7,6 +7,7 @@ import android.view.ViewGroup
7
7
  import android.widget.FrameLayout
8
8
  import androidx.appcompat.app.AppCompatActivity
9
9
  import androidx.fragment.app.Fragment
10
+ import com.facebook.react.bridge.Arguments
10
11
  import com.facebook.react.bridge.Promise
11
12
  import com.facebook.react.bridge.ReactApplicationContext
12
13
  import com.reactnativestripesdk.utils.*
@@ -14,6 +15,7 @@ import com.reactnativestripesdk.utils.createError
14
15
  import com.reactnativestripesdk.utils.createResult
15
16
  import com.reactnativestripesdk.utils.mapFromPaymentIntentResult
16
17
  import com.reactnativestripesdk.utils.mapFromSetupIntentResult
18
+ import com.stripe.android.financialconnections.FinancialConnections
17
19
  import com.stripe.android.model.PaymentIntent
18
20
  import com.stripe.android.model.SetupIntent
19
21
  import com.stripe.android.model.StripeIntent
@@ -32,6 +34,18 @@ class CollectBankAccountLauncherFragment(
32
34
  ) : Fragment() {
33
35
  private lateinit var collectBankAccountLauncher: CollectBankAccountLauncher
34
36
 
37
+ override fun onCreate(savedInstanceState: Bundle?) {
38
+ super.onCreate(savedInstanceState)
39
+
40
+ val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
41
+ if (stripeSdkModule != null && stripeSdkModule.eventListenerCount > 0) {
42
+ FinancialConnections.setEventListener { event ->
43
+ val params = mapFromFinancialConnectionsEvent(event)
44
+ stripeSdkModule.sendEvent(context, "onFinancialConnectionsEvent", params)
45
+ }
46
+ }
47
+ }
48
+
35
49
  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
36
50
  savedInstanceState: Bundle?): View {
37
51
  collectBankAccountLauncher = createBankAccountLauncher()
@@ -63,6 +77,13 @@ class CollectBankAccountLauncherFragment(
63
77
  }
64
78
  }
65
79
 
80
+ override fun onDestroy() {
81
+ super.onDestroy()
82
+
83
+ // Remove any event listener that might be set
84
+ FinancialConnections.clearEventListener()
85
+ }
86
+
66
87
  private fun createBankAccountLauncher(): CollectBankAccountLauncher {
67
88
  return CollectBankAccountLauncher.create(this) { result ->
68
89
  when (result) {
@@ -12,6 +12,7 @@ import com.reactnativestripesdk.utils.*
12
12
  import com.reactnativestripesdk.utils.createError
13
13
  import com.reactnativestripesdk.utils.createMissingActivityError
14
14
  import com.reactnativestripesdk.utils.mapFromToken
15
+ import com.stripe.android.financialconnections.FinancialConnections
15
16
  import com.stripe.android.financialconnections.FinancialConnectionsSheet
16
17
  import com.stripe.android.financialconnections.FinancialConnectionsSheetForTokenResult
17
18
  import com.stripe.android.financialconnections.FinancialConnectionsSheetResult
@@ -27,6 +28,18 @@ class FinancialConnectionsSheetFragment : Fragment() {
27
28
  private lateinit var configuration: FinancialConnectionsSheet.Configuration
28
29
  private lateinit var mode: Mode
29
30
 
31
+ override fun onCreate(savedInstanceState: Bundle?) {
32
+ super.onCreate(savedInstanceState)
33
+
34
+ val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
35
+ if (stripeSdkModule != null && stripeSdkModule.eventListenerCount > 0) {
36
+ FinancialConnections.setEventListener { event ->
37
+ val params = mapFromFinancialConnectionsEvent(event)
38
+ stripeSdkModule.sendEvent(context, "onFinancialConnectionsEvent", params)
39
+ }
40
+ }
41
+ }
42
+
30
43
  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
31
44
  savedInstanceState: Bundle?): View {
32
45
  return FrameLayout(requireActivity()).also {
@@ -55,6 +68,13 @@ class FinancialConnectionsSheetFragment : Fragment() {
55
68
  }
56
69
  }
57
70
 
71
+ override fun onDestroy() {
72
+ super.onDestroy()
73
+
74
+ // Remove any event listener that might be set
75
+ FinancialConnections.clearEventListener()
76
+ }
77
+
58
78
  private fun onFinancialConnectionsSheetForTokenResult(result: FinancialConnectionsSheetForTokenResult) {
59
79
  when(result) {
60
80
  is FinancialConnectionsSheetForTokenResult.Canceled -> {
@@ -3,6 +3,7 @@ package com.reactnativestripesdk
3
3
  import com.facebook.react.bridge.ReadableMap
4
4
  import com.reactnativestripesdk.utils.*
5
5
  import com.reactnativestripesdk.utils.mapToBillingDetails
6
+ import com.reactnativestripesdk.utils.mapToMetadata
6
7
  import com.reactnativestripesdk.utils.mapToUSBankAccountHolderType
7
8
  import com.reactnativestripesdk.utils.mapToUSBankAccountType
8
9
  import com.stripe.android.model.*
@@ -13,7 +14,12 @@ class PaymentMethodCreateParamsFactory(
13
14
  private val cardFieldView: CardFieldView?,
14
15
  private val cardFormView: CardFormView?,
15
16
  ) {
16
- private val billingDetailsParams = mapToBillingDetails(getMapOrNull(paymentMethodData, "billingDetails"), cardFieldView?.cardAddress ?: cardFormView?.cardAddress)
17
+ private val billingDetailsParams = mapToBillingDetails(
18
+ getMapOrNull(paymentMethodData, "billingDetails"),
19
+ cardFieldView?.cardAddress ?: cardFormView?.cardAddress
20
+ )
21
+ private val metadataParams: Map<String, String>? =
22
+ mapToMetadata(getMapOrNull(paymentMethodData, "metadata"))
17
23
 
18
24
  @Throws(PaymentMethodCreateParamsException::class)
19
25
  fun createPaymentMethodParams(paymentMethodType: PaymentMethod.Type): PaymentMethodCreateParams {
@@ -53,7 +59,11 @@ class PaymentMethodCreateParamsFactory(
53
59
  val bankName = getValOr(paymentMethodData, "bankName", null)
54
60
 
55
61
  val idealParams = PaymentMethodCreateParams.Ideal(bankName)
56
- return PaymentMethodCreateParams.create(ideal = idealParams, billingDetails = billingDetailsParams)
62
+ return PaymentMethodCreateParams.create(
63
+ ideal = idealParams,
64
+ billingDetails = billingDetailsParams,
65
+ metadata = metadataParams
66
+ )
57
67
  }
58
68
 
59
69
  @Throws(PaymentMethodCreateParamsException::class)
@@ -69,14 +79,18 @@ class PaymentMethodCreateParamsFactory(
69
79
 
70
80
  return PaymentMethodCreateParams.create(
71
81
  PaymentMethodCreateParams.Sofort(country = country),
72
- billingDetailsParams
82
+ billingDetailsParams,
83
+ metadata = metadataParams
73
84
  )
74
85
  }
75
86
 
76
87
  @Throws(PaymentMethodCreateParamsException::class)
77
88
  private fun createBancontactParams(): PaymentMethodCreateParams {
78
89
  billingDetailsParams?.let {
79
- return PaymentMethodCreateParams.createBancontact(it)
90
+ return PaymentMethodCreateParams.createBancontact(
91
+ billingDetails = it,
92
+ metadata = metadataParams
93
+ )
80
94
  }
81
95
 
82
96
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -91,7 +105,8 @@ class PaymentMethodCreateParamsFactory(
91
105
 
92
106
  return PaymentMethodCreateParams.create(
93
107
  sepaDebit = PaymentMethodCreateParams.SepaDebit(iban),
94
- billingDetails = it
108
+ billingDetails = it,
109
+ metadata = metadataParams
95
110
  )
96
111
  }
97
112
 
@@ -101,7 +116,10 @@ class PaymentMethodCreateParamsFactory(
101
116
  @Throws(PaymentMethodCreateParamsException::class)
102
117
  private fun createOXXOParams(): PaymentMethodCreateParams {
103
118
  billingDetailsParams?.let {
104
- return PaymentMethodCreateParams.createOxxo(it)
119
+ return PaymentMethodCreateParams.createOxxo(
120
+ billingDetails = it,
121
+ metadata = metadataParams
122
+ )
105
123
  }
106
124
 
107
125
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -110,7 +128,10 @@ class PaymentMethodCreateParamsFactory(
110
128
  @Throws(PaymentMethodCreateParamsException::class)
111
129
  private fun createGiropayParams(): PaymentMethodCreateParams {
112
130
  billingDetailsParams?.let {
113
- return PaymentMethodCreateParams.createGiropay(it)
131
+ return PaymentMethodCreateParams.createGiropay(
132
+ billingDetails = it,
133
+ metadata = metadataParams
134
+ )
114
135
  }
115
136
 
116
137
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -119,7 +140,10 @@ class PaymentMethodCreateParamsFactory(
119
140
  @Throws(PaymentMethodCreateParamsException::class)
120
141
  private fun createEPSParams(): PaymentMethodCreateParams {
121
142
  billingDetailsParams?.let {
122
- return PaymentMethodCreateParams.createEps(it)
143
+ return PaymentMethodCreateParams.createEps(
144
+ billingDetails = it,
145
+ metadata = metadataParams
146
+ )
123
147
  }
124
148
 
125
149
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -134,7 +158,10 @@ class PaymentMethodCreateParamsFactory(
134
158
  @Throws(PaymentMethodCreateParamsException::class)
135
159
  private fun createP24Params(): PaymentMethodCreateParams {
136
160
  billingDetailsParams?.let {
137
- return PaymentMethodCreateParams.createP24(it)
161
+ return PaymentMethodCreateParams.createP24(
162
+ billingDetails = it,
163
+ metadata = metadataParams
164
+ )
138
165
  }
139
166
 
140
167
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -144,14 +171,18 @@ class PaymentMethodCreateParamsFactory(
144
171
  private fun createFpxParams(): PaymentMethodCreateParams {
145
172
  val bank = getBooleanOrFalse(paymentMethodData, "testOfflineBank").let { "test_offline_bank" }
146
173
  return PaymentMethodCreateParams.create(
147
- PaymentMethodCreateParams.Fpx(bank)
174
+ PaymentMethodCreateParams.Fpx(bank),
175
+ metadata = metadataParams
148
176
  )
149
177
  }
150
178
 
151
179
  @Throws(PaymentMethodCreateParamsException::class)
152
180
  private fun createAfterpayClearpayParams(): PaymentMethodCreateParams {
153
181
  billingDetailsParams?.let {
154
- return PaymentMethodCreateParams.createAfterpayClearpay(it)
182
+ return PaymentMethodCreateParams.createAfterpayClearpay(
183
+ billingDetails = it,
184
+ metadata = metadataParams
185
+ )
155
186
  }
156
187
 
157
188
  throw PaymentMethodCreateParamsException("You must provide billing details")
@@ -178,7 +209,8 @@ class PaymentMethodCreateParamsFactory(
178
209
  bsbNumber = bsbNumber,
179
210
  accountNumber = accountNumber
180
211
  ),
181
- billingDetails = billingDetails
212
+ billingDetails = billingDetails,
213
+ metadata = metadataParams
182
214
  )
183
215
  }
184
216
 
@@ -191,35 +223,57 @@ class PaymentMethodCreateParamsFactory(
191
223
  throw PaymentMethodCreateParamsException("Klarna requires that you provide the following billing details: email, country")
192
224
  }
193
225
 
194
- return PaymentMethodCreateParams.createKlarna(billingDetailsParams)
226
+ return PaymentMethodCreateParams.createKlarna(
227
+ billingDetails = billingDetailsParams,
228
+ metadata = metadataParams
229
+ )
195
230
  }
196
231
 
197
232
  @Throws(PaymentMethodCreateParamsException::class)
198
233
  private fun createPayPalParams(): PaymentMethodCreateParams {
199
- return PaymentMethodCreateParams.createPayPal(null)
234
+ return PaymentMethodCreateParams.createPayPal(
235
+ metadata = metadataParams
236
+ )
200
237
  }
201
238
 
202
239
  @Throws(PaymentMethodCreateParamsException::class)
203
240
  private fun createAffirmParams(): PaymentMethodCreateParams {
204
- return PaymentMethodCreateParams.createAffirm(billingDetailsParams)
241
+ return PaymentMethodCreateParams.createAffirm(
242
+ billingDetails = billingDetailsParams,
243
+ metadata = metadataParams
244
+ )
205
245
  }
206
246
 
207
247
  @Throws(PaymentMethodCreateParamsException::class)
208
248
  private fun createCashAppParams(): PaymentMethodCreateParams {
209
- return PaymentMethodCreateParams.createCashAppPay(billingDetailsParams)
249
+ return PaymentMethodCreateParams.createCashAppPay(
250
+ billingDetails = billingDetailsParams,
251
+ metadata = metadataParams
252
+ )
210
253
  }
211
254
 
212
255
  @Throws(PaymentMethodCreateParamsException::class)
213
256
  private fun createRevolutPayParams(): PaymentMethodCreateParams {
214
- return PaymentMethodCreateParams.createRevolutPay(billingDetailsParams)
257
+ return PaymentMethodCreateParams.createRevolutPay(
258
+ billingDetails = billingDetailsParams,
259
+ metadata = metadataParams
260
+ )
215
261
  }
216
262
 
217
263
  @Throws(PaymentMethodCreateParamsException::class)
218
- fun createParams(clientSecret: String, paymentMethodType: PaymentMethod.Type?, isPaymentIntent: Boolean): ConfirmStripeIntentParams {
264
+ fun createParams(
265
+ clientSecret: String,
266
+ paymentMethodType: PaymentMethod.Type?,
267
+ isPaymentIntent: Boolean
268
+ ): ConfirmStripeIntentParams {
219
269
  try {
220
270
  return when (paymentMethodType) {
221
271
  PaymentMethod.Type.Card -> createCardStripeIntentParams(clientSecret, isPaymentIntent)
222
- PaymentMethod.Type.USBankAccount -> createUSBankAccountStripeIntentParams(clientSecret, isPaymentIntent)
272
+ PaymentMethod.Type.USBankAccount -> createUSBankAccountStripeIntentParams(
273
+ clientSecret,
274
+ isPaymentIntent
275
+ )
276
+
223
277
  PaymentMethod.Type.Affirm -> createAffirmStripeIntentParams(clientSecret, isPaymentIntent)
224
278
  PaymentMethod.Type.Ideal,
225
279
  PaymentMethod.Type.Alipay,
@@ -245,7 +299,12 @@ class PaymentMethodCreateParamsFactory(
245
299
  .createWithPaymentMethodCreateParams(
246
300
  paymentMethodCreateParams = params,
247
301
  clientSecret = clientSecret,
248
- setupFutureUsage = mapToPaymentIntentFutureUsage(getValOr(options, "setupFutureUsage")),
302
+ setupFutureUsage = mapToPaymentIntentFutureUsage(
303
+ getValOr(
304
+ options,
305
+ "setupFutureUsage"
306
+ )
307
+ ),
249
308
  mandateData = buildMandateDataParams()
250
309
  )
251
310
  } else {
@@ -256,6 +315,7 @@ class PaymentMethodCreateParamsFactory(
256
315
  )
257
316
  }
258
317
  }
318
+
259
319
  null -> ConfirmPaymentIntentParams.create(clientSecret)
260
320
  else -> {
261
321
  throw Exception("This paymentMethodType is not supported yet")
@@ -283,7 +343,10 @@ class PaymentMethodCreateParamsFactory(
283
343
  }
284
344
 
285
345
  @Throws(PaymentMethodCreateParamsException::class)
286
- private fun createCardStripeIntentParams(clientSecret: String, isPaymentIntent: Boolean): ConfirmStripeIntentParams {
346
+ private fun createCardStripeIntentParams(
347
+ clientSecret: String,
348
+ isPaymentIntent: Boolean
349
+ ): ConfirmStripeIntentParams {
287
350
  val paymentMethodId = getValOr(paymentMethodData, "paymentMethodId", null)
288
351
  val setupFutureUsage = mapToPaymentIntentFutureUsage(getValOr(options, "setupFutureUsage"))
289
352
 
@@ -298,11 +361,13 @@ class PaymentMethodCreateParamsFactory(
298
361
  paymentMethodId,
299
362
  paymentMethodOptions = paymentMethodOptionParams,
300
363
  clientSecret = clientSecret,
301
- setupFutureUsage = setupFutureUsage)
364
+ setupFutureUsage = setupFutureUsage
365
+ )
302
366
  else
303
367
  ConfirmSetupIntentParams.create(
304
368
  paymentMethodId,
305
- clientSecret)
369
+ clientSecret
370
+ )
306
371
  )
307
372
  } else {
308
373
  val paymentMethodCreateParams = createCardPaymentMethodParams()
@@ -312,7 +377,8 @@ class PaymentMethodCreateParamsFactory(
312
377
  .createWithPaymentMethodCreateParams(
313
378
  paymentMethodCreateParams,
314
379
  clientSecret,
315
- setupFutureUsage = setupFutureUsage)
380
+ setupFutureUsage = setupFutureUsage
381
+ )
316
382
  else
317
383
  ConfirmSetupIntentParams
318
384
  .create(paymentMethodCreateParams, clientSecret)
@@ -321,7 +387,10 @@ class PaymentMethodCreateParamsFactory(
321
387
  }
322
388
 
323
389
  @Throws(PaymentMethodCreateParamsException::class)
324
- private fun createUSBankAccountStripeIntentParams(clientSecret: String, isPaymentIntent: Boolean): ConfirmStripeIntentParams {
390
+ private fun createUSBankAccountStripeIntentParams(
391
+ clientSecret: String,
392
+ isPaymentIntent: Boolean
393
+ ): ConfirmStripeIntentParams {
325
394
  // If payment method data is supplied, assume they are passing in the bank details manually
326
395
  paymentMethodData?.let {
327
396
  if (billingDetailsParams?.name.isNullOrBlank()) {
@@ -344,7 +413,8 @@ class PaymentMethodCreateParamsFactory(
344
413
  return if (isPaymentIntent) {
345
414
  ConfirmPaymentIntentParams.create(
346
415
  clientSecret = clientSecret,
347
- paymentMethodType = PaymentMethod.Type.USBankAccount
416
+ paymentMethodType = PaymentMethod.Type.USBankAccount,
417
+
348
418
  )
349
419
  } else {
350
420
  ConfirmSetupIntentParams.create(
@@ -356,7 +426,10 @@ class PaymentMethodCreateParamsFactory(
356
426
  }
357
427
 
358
428
  @Throws(PaymentMethodCreateParamsException::class)
359
- private fun createAffirmStripeIntentParams(clientSecret: String, isPaymentIntent: Boolean): ConfirmStripeIntentParams {
429
+ private fun createAffirmStripeIntentParams(
430
+ clientSecret: String,
431
+ isPaymentIntent: Boolean
432
+ ): ConfirmStripeIntentParams {
360
433
  if (!isPaymentIntent) {
361
434
  throw PaymentMethodCreateParamsException("Affirm is not yet supported through SetupIntents.")
362
435
  }
@@ -368,7 +441,7 @@ class PaymentMethodCreateParamsFactory(
368
441
  paymentMethodCreateParams = params,
369
442
  clientSecret = clientSecret,
370
443
  setupFutureUsage = mapToPaymentIntentFutureUsage(getValOr(options, "setupFutureUsage")),
371
- mandateData = buildMandateDataParams()
444
+ mandateData = buildMandateDataParams(),
372
445
  )
373
446
  }
374
447
 
@@ -390,18 +463,22 @@ class PaymentMethodCreateParamsFactory(
390
463
  getValOr(
391
464
  params,
392
465
  "accountType",
393
- null)),
466
+ null
467
+ )
468
+ ),
394
469
  mapToUSBankAccountHolderType(
395
470
  getValOr(
396
471
  params,
397
472
  "accountHolderType",
398
- null))
473
+ null
474
+ )
475
+ )
399
476
  )
400
477
 
401
478
  return PaymentMethodCreateParams.Companion.create(
402
479
  usBankAccount,
403
480
  billingDetailsParams,
404
- null
481
+ metadataParams
405
482
  )
406
483
  }
407
484
 
@@ -409,10 +486,12 @@ class PaymentMethodCreateParamsFactory(
409
486
  getMapOrNull(paymentMethodData, "mandateData")?.let { mandateData ->
410
487
  getMapOrNull(mandateData, "customerAcceptance")?.let { customerAcceptance ->
411
488
  getMapOrNull(customerAcceptance, "online")?.let { onlineParams ->
412
- return MandateDataParams(MandateDataParams.Type.Online(
413
- ipAddress = getValOr(onlineParams, "ipAddress", "") ?: "",
414
- userAgent = getValOr(onlineParams, "userAgent", "") ?: "",
415
- ))
489
+ return MandateDataParams(
490
+ MandateDataParams.Type.Online(
491
+ ipAddress = getValOr(onlineParams, "ipAddress", "") ?: "",
492
+ userAgent = getValOr(onlineParams, "userAgent", "") ?: "",
493
+ )
494
+ )
416
495
  }
417
496
  }
418
497
  }
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
4
4
  import android.os.Bundle
5
5
  import android.util.Log
6
6
  import com.facebook.react.bridge.*
7
+ import com.stripe.android.financialconnections.analytics.FinancialConnectionsEvent
7
8
  import com.stripe.android.PaymentAuthConfig
8
9
  import com.stripe.android.model.*
9
10
  import com.stripe.android.model.StripeIntent.NextActionType
@@ -598,6 +599,10 @@ internal fun mapToBillingDetails(billingDetails: ReadableMap?, cardAddress: Addr
598
599
  return paymentMethodBillingDetailsBuilder.build()
599
600
  }
600
601
 
602
+ internal fun mapToMetadata(metadata: ReadableMap?): Map<String, String>? {
603
+ return metadata?.toHashMap()?.mapValues { it.value.toString() }
604
+ }
605
+
601
606
  internal fun mapToShippingDetails(shippingDetails: ReadableMap?): ConfirmPaymentIntentParams.Shipping? {
602
607
  if (shippingDetails == null) {
603
608
  return null
@@ -957,3 +962,48 @@ internal fun mapToPreferredNetworks(networksAsInts: ArrayList<Int>?): List<CardB
957
962
  intToCardBrand[it]
958
963
  }
959
964
  }
965
+
966
+ internal fun mapFromFinancialConnectionsEvent(event: FinancialConnectionsEvent): WritableMap {
967
+ return Arguments.createMap().apply {
968
+ putString("name", event.name.value)
969
+ putMap("metadata", event.metadata.toMap().toReadableMap())
970
+ }
971
+ }
972
+
973
+ private fun List<Any?>.toWritableArray(): WritableArray {
974
+ val writableArray = Arguments.createArray()
975
+
976
+ forEach { value ->
977
+ when (value) {
978
+ null -> writableArray.pushNull()
979
+ is Boolean -> writableArray.pushBoolean(value)
980
+ is Int -> writableArray.pushInt(value)
981
+ is Double -> writableArray.pushDouble(value)
982
+ is String -> writableArray.pushString(value)
983
+ is Map<*, *> -> writableArray.pushMap((value as Map<String, Any?>).toReadableMap())
984
+ is List<*> -> writableArray.pushArray((value as List<Any?>).toWritableArray())
985
+ else -> writableArray.pushString(value.toString())
986
+ }
987
+ }
988
+
989
+ return writableArray
990
+ }
991
+
992
+ private fun Map<String, Any?>.toReadableMap(): ReadableMap {
993
+ val writableMap = Arguments.createMap()
994
+
995
+ forEach { (key, value) ->
996
+ when (value) {
997
+ null -> writableMap.putNull(key)
998
+ is Boolean -> writableMap.putBoolean(key, value)
999
+ is Int -> writableMap.putInt(key, value)
1000
+ is Double -> writableMap.putDouble(key, value)
1001
+ is String -> writableMap.putString(key, value)
1002
+ is Map<*, *> -> writableMap.putMap(key, (value as Map<String, Any?>).toReadableMap())
1003
+ is List<*> -> writableMap.putArray(key, (value as List<Any?>).toWritableArray())
1004
+ else -> writableMap.putString(key, value.toString())
1005
+ }
1006
+ }
1007
+
1008
+ return writableMap
1009
+ }
@@ -14,10 +14,16 @@ class FinancialConnections {
14
14
  internal static func present(
15
15
  withClientSecret: String,
16
16
  returnURL: String? = nil,
17
+ onEvent: ((FinancialConnectionsEvent) -> Void)? = nil,
17
18
  resolve: @escaping RCTPromiseResolveBlock
18
19
  ) -> Void {
19
20
  DispatchQueue.main.async {
20
- FinancialConnectionsSheet(financialConnectionsSessionClientSecret: withClientSecret, returnURL: returnURL).present(
21
+ let financialConnectionsSheet = FinancialConnectionsSheet(
22
+ financialConnectionsSessionClientSecret: withClientSecret,
23
+ returnURL: returnURL
24
+ )
25
+ financialConnectionsSheet.onEvent = onEvent
26
+ financialConnectionsSheet.present(
21
27
  from: findViewControllerPresenter(from: UIApplication.shared.delegate?.window??.rootViewController ?? UIViewController()),
22
28
  completion: { result in
23
29
  switch result {
@@ -35,10 +41,16 @@ class FinancialConnections {
35
41
  internal static func presentForToken(
36
42
  withClientSecret: String,
37
43
  returnURL: String? = nil,
44
+ onEvent: ((FinancialConnectionsEvent) -> Void)? = nil,
38
45
  resolve: @escaping RCTPromiseResolveBlock
39
46
  ) -> Void {
40
47
  DispatchQueue.main.async {
41
- FinancialConnectionsSheet(financialConnectionsSessionClientSecret: withClientSecret, returnURL: returnURL).presentForToken(
48
+ let financialConnectionsSheet = FinancialConnectionsSheet(
49
+ financialConnectionsSessionClientSecret: withClientSecret,
50
+ returnURL: returnURL
51
+ )
52
+ financialConnectionsSheet.onEvent = onEvent
53
+ financialConnectionsSheet.presentForToken(
42
54
  from: findViewControllerPresenter(from: UIApplication.shared.delegate?.window??.rootViewController ?? UIViewController()),
43
55
  completion: { result in
44
56
  switch result {
package/ios/Mappers.swift CHANGED
@@ -1050,4 +1050,27 @@ class Mappers {
1050
1050
  return nil
1051
1051
  }
1052
1052
  }
1053
+
1054
+ class func financialConnectionsEventToMap(_ event: FinancialConnectionsEvent) -> [String: Any] {
1055
+ var metadata: [String: Any] = [:]
1056
+
1057
+ if let manualEntry = event.metadata.manualEntry {
1058
+ metadata["manualEntry"] = manualEntry
1059
+ }
1060
+
1061
+ if let institutionName = event.metadata.institutionName {
1062
+ metadata["institutionName"] = institutionName
1063
+ }
1064
+
1065
+ if let errorCode = event.metadata.errorCode {
1066
+ metadata["errorCode"] = errorCode.rawValue
1067
+ }
1068
+
1069
+ let mappedEvent: [String: Any] = [
1070
+ "name": event.name.rawValue,
1071
+ "metadata": metadata
1072
+ ]
1073
+
1074
+ return mappedEvent
1075
+ }
1053
1076
  }