@stripe/stripe-react-native 0.38.6 → 0.40.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 (41) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/android/.project +0 -11
  3. package/android/.settings/org.eclipse.buildship.core.prefs +3 -3
  4. package/android/gradle.properties +1 -1
  5. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +4 -0
  6. package/android/src/main/java/com/reactnativestripesdk/CardFieldViewManager.kt +5 -0
  7. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +43 -8
  8. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +0 -60
  9. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetFragment.kt +3 -3
  10. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerAdapter.kt +0 -2
  11. package/ios/CardFieldManager.m +1 -0
  12. package/ios/CardFieldView.swift +28 -39
  13. package/ios/CardFormManager.m +1 -0
  14. package/ios/StripeSdk+PaymentSheet.swift +17 -2
  15. package/ios/StripeSdk.swift +29 -66
  16. package/lib/commonjs/components/CardField.js +1 -1
  17. package/lib/commonjs/components/CardField.js.map +1 -1
  18. package/lib/commonjs/components/CustomerSheet.js +1 -1
  19. package/lib/commonjs/components/CustomerSheet.js.map +1 -1
  20. package/lib/commonjs/types/PaymentSheet.js +1 -1
  21. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  22. package/lib/commonjs/types/index.js +1 -1
  23. package/lib/commonjs/types/index.js.map +1 -1
  24. package/lib/module/components/CardField.js +1 -1
  25. package/lib/module/components/CardField.js.map +1 -1
  26. package/lib/module/components/CustomerSheet.js +1 -1
  27. package/lib/module/components/CustomerSheet.js.map +1 -1
  28. package/lib/module/types/PaymentSheet.js +1 -1
  29. package/lib/module/types/PaymentSheet.js.map +1 -1
  30. package/lib/module/types/index.js +1 -1
  31. package/lib/module/types/index.js.map +1 -1
  32. package/lib/typescript/src/components/CardField.d.ts +2 -0
  33. package/lib/typescript/src/components/CustomerSheet.d.ts +3 -3
  34. package/lib/typescript/src/types/PaymentSheet.d.ts +33 -3
  35. package/lib/typescript/src/types/index.d.ts +1 -0
  36. package/package.json +1 -1
  37. package/src/components/CardField.tsx +2 -0
  38. package/src/components/CustomerSheet.tsx +3 -3
  39. package/src/types/PaymentSheet.ts +40 -3
  40. package/src/types/index.ts +1 -0
  41. package/stripe-react-native.podspec +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.40.0 - 2024-11-19
6
+
7
+ **Breaking changes**
8
+
9
+ - Removed support for FPX payments via the bank picker UI. If you'd like to accept FPX payments, we recommend using [Mobile Payment Element](https://docs.stripe.com/payments/accept-a-payment?platform=react-native). Also see the [FPX Payment guide](https://docs.stripe.com/payments/fpx/accept-a-payment?web-or-mobile=mobile) for more info on how to integrate FPX specifically.
10
+
11
+ **Features**
12
+
13
+ - `CustomerSheet` is now generally available!
14
+ - If you were using `CustomerSheetBeta`, change that to `CustomerSheet`.
15
+ - If you were using `CustomerSheetBeta.CustomerSheet`, change that to `CustomerSheet.Component`
16
+ - Enabled vertical mode
17
+
18
+ ## 0.39.0 - 2024-10-15
19
+
20
+ **Features**
21
+
22
+ - Adds support for CustomerSession in private beta [1744](https://github.com/stripe/stripe-react-native/pull/1744)
23
+ - Added `onBehalfOf` prop to CardField
24
+
25
+ **Fixes**
26
+
27
+ * Updated `stripe-ios` to 23.30.\*
28
+ * Updated `stripe-android` to 20.52.\*
29
+
5
30
  ## 0.38.6 - 2024-09-04
6
31
 
7
32
  **Fixes**
package/android/.project CHANGED
@@ -14,15 +14,4 @@
14
14
  <natures>
15
15
  <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16
16
  </natures>
17
- <filteredResources>
18
- <filter>
19
- <id>1725490136547</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>
28
17
  </projectDescription>
@@ -1,11 +1,11 @@
1
- arguments=--init-script /var/folders/qg/5wmspvx516145k8z2q01c8_m0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/qg/5wmspvx516145k8z2q01c8_m0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
1
+ arguments=
2
2
  auto.sync=false
3
3
  build.scans.enabled=false
4
- connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(8.9))
4
+ connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0))
5
5
  connection.project.dir=
6
6
  eclipse.preferences.version=1
7
7
  gradle.user.home=
8
- java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
8
+ java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
9
9
  jvm.arguments=
10
10
  offline.mode=false
11
11
  override.workspace.settings=true
@@ -1,3 +1,3 @@
1
1
  StripeSdk_kotlinVersion=1.8.0
2
2
  # Keep StripeSdk_stripeVersion in sync with https://github.com/stripe/stripe-identity-react-native/blob/main/android/gradle.properties
3
- StripeSdk_stripeVersion=20.48.+
3
+ StripeSdk_stripeVersion=20.52.+
@@ -219,6 +219,10 @@ class CardFieldView(context: ThemedReactContext) : FrameLayout(context) {
219
219
  mCardWidget.setPreferredNetworks(mapToPreferredNetworks(preferredNetworks))
220
220
  }
221
221
 
222
+ fun setOnBehalfOf(onBehalfOf: String?) {
223
+ mCardWidget.onBehalfOf = onBehalfOf
224
+ }
225
+
222
226
  /**
223
227
  * We can reliable assume that setPostalCodeEnabled is called before
224
228
  * setCountryCode because of the order of the props in CardField.tsx
@@ -51,6 +51,11 @@ class CardFieldViewManager : SimpleViewManager<CardFieldView>() {
51
51
  view.setCountryCode(countryCode)
52
52
  }
53
53
 
54
+ @ReactProp(name = "onBehalfOf")
55
+ fun setOnBehalfOf(view: CardFieldView, onBehalfOf: String?) {
56
+ view.setOnBehalfOf(onBehalfOf)
57
+ }
58
+
54
59
  @ReactProp(name = "placeholders")
55
60
  fun setPlaceHolders(view: CardFieldView, placeholders: ReadableMap) {
56
61
  view.setPlaceHolders(placeholders)
@@ -55,6 +55,7 @@ class PaymentSheetFragment(
55
55
  }
56
56
  }
57
57
 
58
+ @OptIn(ExperimentalPaymentMethodLayoutApi::class)
58
59
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
59
60
  super.onViewCreated(view, savedInstanceState)
60
61
  val merchantDisplayName = arguments?.getString("merchantDisplayName").orEmpty()
@@ -63,8 +64,6 @@ class PaymentSheetFragment(
63
64
  return
64
65
  }
65
66
  val primaryButtonLabel = arguments?.getString("primaryButtonLabel")
66
- val customerId = arguments?.getString("customerId").orEmpty()
67
- val customerEphemeralKeySecret = arguments?.getString("customerEphemeralKeySecret").orEmpty()
68
67
  val googlePayConfig = buildGooglePayConfig(arguments?.getBundle("googlePay"))
69
68
  val allowsDelayedPaymentMethods = arguments?.getBoolean("allowsDelayedPaymentMethods")
70
69
  val billingDetailsBundle = arguments?.getBundle("defaultBillingDetails")
@@ -86,6 +85,13 @@ class PaymentSheetFragment(
86
85
  return
87
86
  }
88
87
 
88
+ val customerConfiguration = try {
89
+ buildCustomerConfiguration(arguments)
90
+ } catch (error: PaymentSheetException) {
91
+ initPromise.resolve(createError(ErrorType.Failed.toString(), error))
92
+ return
93
+ }
94
+
89
95
  val shippingDetails = arguments?.getBundle("defaultShippingDetails")?.let {
90
96
  AddressSheetView.buildAddressDetails(it)
91
97
  }
@@ -190,12 +196,7 @@ class PaymentSheetFragment(
190
196
  val configurationBuilder = PaymentSheet.Configuration.Builder(merchantDisplayName)
191
197
  .allowsDelayedPaymentMethods(allowsDelayedPaymentMethods ?: false)
192
198
  .defaultBillingDetails(defaultBillingDetails)
193
- .customer(
194
- if (customerId.isNotEmpty() && customerEphemeralKeySecret.isNotEmpty()) PaymentSheet.CustomerConfiguration(
195
- id = customerId,
196
- ephemeralKeySecret = customerEphemeralKeySecret
197
- ) else null
198
- )
199
+ .customer(customerConfiguration)
199
200
  .googlePay(googlePayConfig)
200
201
  .appearance(appearance)
201
202
  .shippingDetails(shippingDetails)
@@ -209,6 +210,10 @@ class PaymentSheetFragment(
209
210
  configurationBuilder.paymentMethodOrder(it)
210
211
  }
211
212
 
213
+ configurationBuilder.paymentMethodLayout(
214
+ mapToPaymentMethodLayout(arguments?.getString("paymentMethodLayout"))
215
+ )
216
+
212
217
  paymentSheetConfiguration = configurationBuilder.build()
213
218
 
214
219
  if (arguments?.getBoolean("customFlow") == true) {
@@ -428,6 +433,28 @@ class PaymentSheetFragment(
428
433
  )
429
434
  }
430
435
  }
436
+
437
+ @OptIn(ExperimentalCustomerSessionApi::class)
438
+ @Throws(PaymentSheetException::class)
439
+ private fun buildCustomerConfiguration(bundle: Bundle?): PaymentSheet.CustomerConfiguration? {
440
+ val customerId = bundle?.getString("customerId").orEmpty()
441
+ val customerEphemeralKeySecret = bundle?.getString("customerEphemeralKeySecret").orEmpty()
442
+ val customerSessionClientSecret = bundle?.getString("customerSessionClientSecret").orEmpty()
443
+ return if (customerSessionClientSecret.isNotEmpty() && customerEphemeralKeySecret.isNotEmpty()) {
444
+ throw PaymentSheetException("`customerEphemeralKeySecret` and `customerSessionClientSecret` cannot both be set")
445
+ } else if (customerId.isNotEmpty() && customerSessionClientSecret.isNotEmpty()) {
446
+ PaymentSheet.CustomerConfiguration.createWithCustomerSession(
447
+ id = customerId,
448
+ clientSecret = customerSessionClientSecret
449
+ )
450
+ }
451
+ else if (customerId.isNotEmpty() && customerEphemeralKeySecret.isNotEmpty()) {
452
+ PaymentSheet.CustomerConfiguration(
453
+ id = customerId,
454
+ ephemeralKeySecret = customerEphemeralKeySecret
455
+ )
456
+ } else null
457
+ }
431
458
  }
432
459
  }
433
460
 
@@ -468,6 +495,14 @@ fun mapToCollectionMode(str: String?): PaymentSheet.BillingDetailsCollectionConf
468
495
  }
469
496
  }
470
497
 
498
+ fun mapToPaymentMethodLayout(str: String?): PaymentSheet.PaymentMethodLayout {
499
+ return when (str) {
500
+ "Horizontal" -> PaymentSheet.PaymentMethodLayout.Horizontal
501
+ "Vertical" -> PaymentSheet.PaymentMethodLayout.Vertical
502
+ else -> PaymentSheet.PaymentMethodLayout.Automatic
503
+ }
504
+ }
505
+
471
506
  fun mapToAddressCollectionMode(str: String?): PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode {
472
507
  return when (str) {
473
508
  "automatic" -> PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Automatic
@@ -18,7 +18,6 @@ import com.stripe.android.googlepaylauncher.GooglePayLauncher
18
18
  import com.stripe.android.model.*
19
19
  import com.stripe.android.payments.bankaccount.CollectBankAccountConfiguration
20
20
  import com.stripe.android.paymentsheet.PaymentSheet
21
- import com.stripe.android.view.AddPaymentMethodActivityStarter
22
21
  import kotlinx.coroutines.CoroutineScope
23
22
  import kotlinx.coroutines.Dispatchers
24
23
  import kotlinx.coroutines.launch
@@ -77,14 +76,6 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
77
76
  }
78
77
  else -> {
79
78
  dispatchActivityResultsToFragments(requestCode, resultCode, data)
80
- try {
81
- val result = AddPaymentMethodActivityStarter.Result.fromIntent(data)
82
- if (data?.getParcelableExtra<Parcelable>("extra_activity_result") != null) {
83
- onFpxPaymentMethodResult(result)
84
- }
85
- } catch (e: java.lang.Exception) {
86
- Log.d("StripeReactNative", e.localizedMessage ?: e.toString())
87
- }
88
79
  }
89
80
  }
90
81
  }
@@ -219,48 +210,6 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
219
210
  paymentSheetFragment?.paymentSheetIntentCreationCallback?.complete(params)
220
211
  }
221
212
 
222
- private fun payWithFpx() {
223
- getCurrentActivityOrResolveWithError(confirmPromise)?.let {
224
- AddPaymentMethodActivityStarter(it)
225
- .startForResult(AddPaymentMethodActivityStarter.Args.Builder()
226
- .setPaymentMethodType(PaymentMethod.Type.Fpx)
227
- .build()
228
- )
229
- }
230
- }
231
-
232
- private fun onFpxPaymentMethodResult(result: AddPaymentMethodActivityStarter.Result) {
233
- when (result) {
234
- is AddPaymentMethodActivityStarter.Result.Success -> {
235
- if (confirmPaymentClientSecret != null && confirmPromise != null) {
236
- paymentLauncherFragment = PaymentLauncherFragment.forPayment(
237
- context = reactApplicationContext,
238
- stripe,
239
- publishableKey,
240
- stripeAccountId,
241
- confirmPromise!!,
242
- confirmPaymentClientSecret!!,
243
- ConfirmPaymentIntentParams.createWithPaymentMethodId(
244
- result.paymentMethod.id!!,
245
- confirmPaymentClientSecret!!
246
- )
247
- )
248
- } else {
249
- Log.e("StripeReactNative", "FPX payment failed. Promise and/or client secret is not set.")
250
- confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), "FPX payment failed. Client secret is not set."))
251
- }
252
- }
253
- is AddPaymentMethodActivityStarter.Result.Failure -> {
254
- confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), result.exception))
255
- }
256
- is AddPaymentMethodActivityStarter.Result.Canceled -> {
257
- confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), "The payment has been canceled"))
258
- }
259
- }
260
- this.confirmPaymentClientSecret = null
261
- this.confirmPromise = null
262
- }
263
-
264
213
  @ReactMethod
265
214
  fun createPaymentMethod(data: ReadableMap, options: ReadableMap, promise: Promise) {
266
215
  val paymentMethodType = getValOr(data, "paymentMethodType")?.let { mapToPaymentMethodType(it) } ?: run {
@@ -460,15 +409,6 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
460
409
  else
461
410
  null // Expect that payment method was attached on the server
462
411
 
463
- val testOfflineBank = getBooleanOrFalse(params, "testOfflineBank")
464
-
465
- if (paymentMethodType == PaymentMethod.Type.Fpx && !testOfflineBank) {
466
- confirmPaymentClientSecret = paymentIntentClientSecret
467
- confirmPromise = promise
468
- payWithFpx()
469
- return
470
- }
471
-
472
412
  // if (paymentMethodType == PaymentMethod.Type.WeChatPay) {
473
413
  // val appId = getValOr(params, "appId") ?: run {
474
414
  // promise.resolve(createError("Failed", "You must provide appId"))
@@ -20,7 +20,6 @@ import com.stripe.android.customersheet.CustomerAdapter
20
20
  import com.stripe.android.customersheet.CustomerEphemeralKey
21
21
  import com.stripe.android.customersheet.CustomerSheet
22
22
  import com.stripe.android.customersheet.CustomerSheetResult
23
- import com.stripe.android.customersheet.ExperimentalCustomerSheetApi
24
23
  import com.stripe.android.customersheet.PaymentOptionSelection
25
24
  import com.stripe.android.model.PaymentMethod
26
25
  import com.stripe.android.paymentsheet.*
@@ -29,7 +28,7 @@ import kotlinx.coroutines.Dispatchers
29
28
  import kotlinx.coroutines.launch
30
29
 
31
30
 
32
- @OptIn(ExperimentalCustomerSheetApi::class, ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class)
31
+ @OptIn(ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class)
33
32
  class CustomerSheetFragment : Fragment() {
34
33
  private var customerSheet: CustomerSheet? = null
35
34
  internal var customerAdapter: ReactNativeCustomerAdapter? = null
@@ -111,11 +110,12 @@ class CustomerSheetFragment : Fragment() {
111
110
 
112
111
  customerSheet = CustomerSheet.create(
113
112
  fragment = this,
114
- configuration = configuration.build(),
115
113
  customerAdapter = customerAdapter,
116
114
  callback = ::handleResult
117
115
  )
118
116
 
117
+ customerSheet?.configure(configuration.build())
118
+
119
119
  initPromise.resolve(WritableNativeMap())
120
120
  }
121
121
 
@@ -7,11 +7,9 @@ import com.facebook.react.bridge.ReadableMap
7
7
  import com.facebook.react.bridge.WritableMap
8
8
  import com.reactnativestripesdk.StripeSdkModule
9
9
  import com.stripe.android.customersheet.CustomerAdapter
10
- import com.stripe.android.customersheet.ExperimentalCustomerSheetApi
11
10
  import com.stripe.android.model.PaymentMethod
12
11
  import kotlinx.coroutines.CompletableDeferred
13
12
 
14
- @OptIn(ExperimentalCustomerSheetApi::class)
15
13
  class ReactNativeCustomerAdapter (
16
14
  private val context: ReactApplicationContext,
17
15
  private val adapter: CustomerAdapter,
@@ -12,6 +12,7 @@ RCT_EXPORT_VIEW_PROPERTY(placeholders, NSDictionary)
12
12
  RCT_EXPORT_VIEW_PROPERTY(autofocus, BOOL)
13
13
  RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL)
14
14
  RCT_EXPORT_VIEW_PROPERTY(dangerouslyGetFullCardDetails, BOOL)
15
+ RCT_EXPORT_VIEW_PROPERTY(onBehalfOf, NSString)
15
16
  RCT_EXPORT_VIEW_PROPERTY(preferredNetworks, NSArray)
16
17
  RCT_EXTERN_METHOD(focus:(nonnull NSNumber*) reactTag)
17
18
  RCT_EXTERN_METHOD(blur:(nonnull NSNumber*) reactTag)
@@ -6,9 +6,9 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
6
6
  @objc var onCardChange: RCTDirectEventBlock?
7
7
  @objc var onFocusChange: RCTDirectEventBlock?
8
8
  @objc var dangerouslyGetFullCardDetails: Bool = false
9
-
9
+
10
10
  private var cardField = STPPaymentCardTextField()
11
-
11
+
12
12
  public var cardParams: STPPaymentMethodParams? = nil
13
13
  public var cardPostalCode: String? = nil
14
14
 
@@ -17,19 +17,25 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
17
17
  cardField.isUserInteractionEnabled = !disabled
18
18
  }
19
19
  }
20
-
20
+
21
21
  @objc var postalCodeEnabled: Bool = true {
22
22
  didSet {
23
23
  cardField.postalCodeEntryEnabled = postalCodeEnabled
24
24
  }
25
25
  }
26
-
26
+
27
27
  @objc var countryCode: String? {
28
28
  didSet {
29
29
  cardField.countryCode = countryCode
30
30
  }
31
31
  }
32
-
32
+
33
+ @objc var onBehalfOf: String? {
34
+ didSet {
35
+ cardField.onBehalfOf = onBehalfOf
36
+ }
37
+ }
38
+
33
39
  @objc var preferredNetworks: Array<Int>? {
34
40
  didSet {
35
41
  if let preferredNetworks = preferredNetworks {
@@ -37,7 +43,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
37
43
  }
38
44
  }
39
45
  }
40
-
46
+
41
47
  @objc var placeholders: NSDictionary = NSDictionary() {
42
48
  didSet {
43
49
  if let numberPlaceholder = placeholders["number"] as? String {
@@ -56,7 +62,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
56
62
  }
57
63
  }
58
64
  }
59
-
65
+
60
66
  @objc var autofocus: Bool = false {
61
67
  didSet {
62
68
  if autofocus == true {
@@ -64,7 +70,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
64
70
  }
65
71
  }
66
72
  }
67
-
73
+
68
74
  @objc var cardStyle: NSDictionary = NSDictionary() {
69
75
  didSet {
70
76
  if let borderWidth = cardStyle["borderWidth"] as? Int {
@@ -91,7 +97,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
91
97
  cardField.textErrorColor = UIColor(hexString: textErrorColor)
92
98
  }
93
99
  let fontSize = cardStyle["fontSize"] as? Int ?? 14
94
-
100
+
95
101
  if let fontFamily = cardStyle["fontFamily"] as? String {
96
102
  cardField.font = UIFont(name: fontFamily, size: CGFloat(fontSize)) ?? UIFont.systemFont(ofSize: CGFloat(fontSize))
97
103
  } else {
@@ -104,46 +110,46 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
104
110
  }
105
111
  }
106
112
  }
107
-
113
+
108
114
  override init(frame: CGRect) {
109
115
  super.init(frame: frame)
110
116
  cardField.delegate = self
111
-
117
+
112
118
  self.addSubview(cardField)
113
119
  }
114
-
120
+
115
121
  func focus() {
116
122
  cardField.becomeFirstResponder()
117
123
  }
118
-
124
+
119
125
  func blur() {
120
126
  cardField.resignFirstResponder()
121
127
  }
122
-
128
+
123
129
  func clear() {
124
130
  cardField.clear()
125
131
  }
126
-
132
+
127
133
  func paymentCardTextFieldDidEndEditing(_ textField: STPPaymentCardTextField) {
128
134
  onFocusChange?(["focusedField": NSNull()])
129
135
  }
130
-
136
+
131
137
  func paymentCardTextFieldDidBeginEditingNumber(_ textField: STPPaymentCardTextField) {
132
138
  onFocusChange?(["focusedField": "CardNumber"])
133
139
  }
134
-
140
+
135
141
  func paymentCardTextFieldDidBeginEditingCVC(_ textField: STPPaymentCardTextField) {
136
142
  onFocusChange?(["focusedField": "Cvc"])
137
143
  }
138
-
144
+
139
145
  func paymentCardTextFieldDidBeginEditingExpiration(_ textField: STPPaymentCardTextField) {
140
146
  onFocusChange?(["focusedField": "ExpiryDate"])
141
147
  }
142
-
148
+
143
149
  func paymentCardTextFieldDidBeginEditingPostalCode(_ textField: STPPaymentCardTextField) {
144
150
  onFocusChange?(["focusedField": "PostalCode"])
145
151
  }
146
-
152
+
147
153
  func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
148
154
  if onCardChange != nil {
149
155
  let brand = STPCardValidator.brand(forNumber: textField.cardNumber ?? "")
@@ -180,29 +186,12 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate {
180
186
  self.cardPostalCode = nil
181
187
  }
182
188
  }
183
-
189
+
184
190
  override func layoutSubviews() {
185
191
  cardField.frame = self.bounds
186
192
  }
187
-
193
+
188
194
  required init?(coder: NSCoder) {
189
195
  fatalError("init(coder:) has not been implemented")
190
196
  }
191
-
192
- func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
193
- //
194
- }
195
-
196
- func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
197
- //
198
- }
199
-
200
- func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPPaymentStatusBlock) {
201
- //
202
- }
203
-
204
- func paymentContext(_ paymentContext: STPPaymentContext, didFinishWith status: STPPaymentStatus, error: Error?) {
205
- //
206
- }
207
-
208
197
  }
@@ -9,6 +9,7 @@ RCT_EXPORT_VIEW_PROPERTY(autofocus, BOOL)
9
9
  RCT_EXPORT_VIEW_PROPERTY(cardStyle, NSDictionary)
10
10
  RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL)
11
11
  RCT_EXPORT_VIEW_PROPERTY(preferredNetworks, NSArray)
12
+ RCT_EXPORT_VIEW_PROPERTY(onBehalfOf, NSString)
12
13
  RCT_EXTERN_METHOD(focus:(nonnull NSNumber*) reactTag)
13
14
  RCT_EXTERN_METHOD(blur:(nonnull NSNumber*) reactTag)
14
15
  @end
@@ -6,7 +6,7 @@
6
6
  //
7
7
 
8
8
  import Foundation
9
- @_spi(ExperimentalAllowsRemovalOfLastSavedPaymentMethodAPI) @_spi(STP) import StripePaymentSheet
9
+ @_spi(ExperimentalAllowsRemovalOfLastSavedPaymentMethodAPI) @_spi(CustomerSessionBetaAccess) @_spi(STP) import StripePaymentSheet
10
10
 
11
11
  extension StripeSdk {
12
12
  internal func buildPaymentSheetConfiguration(
@@ -91,11 +91,17 @@ extension StripeSdk {
91
91
  }
92
92
 
93
93
  if let customerId = params["customerId"] as? String {
94
- if let customerEphemeralKeySecret = params["customerEphemeralKeySecret"] as? String {
94
+ var customerEphemeralKeySecret = params["customerEphemeralKeySecret"] as? String
95
+ var customerClientSecret = params["customerSessionClientSecret"] as? String
96
+ if let customerEphemeralKeySecret, let customerClientSecret {
97
+ return(error: Errors.createError(ErrorType.Failed, "`customerEphemeralKeySecret` and `customerSessionClientSecret cannot both be set"), configuration: nil)
98
+ } else if let customerEphemeralKeySecret {
95
99
  if (!Errors.isEKClientSecretValid(clientSecret: customerEphemeralKeySecret)) {
96
100
  return(error: Errors.createError(ErrorType.Failed, "`customerEphemeralKeySecret` format does not match expected client secret formatting."), configuration: nil)
97
101
  }
98
102
  configuration.customer = .init(id: customerId, ephemeralKeySecret: customerEphemeralKeySecret)
103
+ } else if let customerClientSecret {
104
+ configuration.customer = .init(id: customerId, customerSessionClientSecret: customerClientSecret)
99
105
  }
100
106
  }
101
107
 
@@ -110,6 +116,15 @@ extension StripeSdk {
110
116
  if let paymentMethodOrder = params["paymentMethodOrder"] as? Array<String> {
111
117
  configuration.paymentMethodOrder = paymentMethodOrder
112
118
  }
119
+
120
+ switch params["paymentMethodLayout"] as? String? {
121
+ case "Horizontal":
122
+ configuration.paymentMethodLayout = .horizontal
123
+ case "Vertical":
124
+ configuration.paymentMethodLayout = .vertical
125
+ default:
126
+ configuration.paymentMethodLayout = .automatic
127
+ }
113
128
 
114
129
  return (nil, configuration)
115
130
  }