@stripe/stripe-react-native 0.56.0 → 0.57.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 (84) hide show
  1. package/android/gradle.properties +1 -1
  2. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormView.kt +4 -3
  3. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +7 -6
  4. package/android/src/main/java/com/reactnativestripesdk/CardFormView.kt +11 -11
  5. package/android/src/main/java/com/reactnativestripesdk/{CollectBankAccountLauncherFragment.kt → CollectBankAccountLauncherManager.kt} +21 -44
  6. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +17 -24
  7. package/android/src/main/java/com/reactnativestripesdk/{FinancialConnectionsSheetFragment.kt → FinancialConnectionsSheetManager.kt} +30 -77
  8. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +107 -0
  9. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherManager.kt +37 -0
  10. package/android/src/main/java/com/reactnativestripesdk/{PaymentLauncherFragment.kt → PaymentLauncherManager.kt} +39 -77
  11. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +8 -20
  12. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +366 -483
  13. package/android/src/main/java/com/reactnativestripesdk/{PaymentSheetFragment.kt → PaymentSheetManager.kt} +79 -88
  14. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +176 -219
  15. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +78 -0
  16. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +48 -35
  17. package/android/src/main/java/com/reactnativestripesdk/customersheet/{CustomerSheetFragment.kt → CustomerSheetManager.kt} +70 -85
  18. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +0 -2
  19. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +47 -12
  20. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +87 -142
  21. package/android/src/main/java/com/reactnativestripesdk/utils/StripeUIManager.kt +62 -0
  22. package/ios/AddressSheet/AddressSheetView.swift +1 -1
  23. package/ios/FinancialConnections.swift +2 -2
  24. package/ios/Mappers.swift +2 -4
  25. package/ios/PaymentMethodFactory.swift +0 -17
  26. package/ios/PushProvisioning/AddToWalletButtonView.swift +1 -1
  27. package/ios/StripeSdkImpl+CustomerSheet.swift +1 -1
  28. package/ios/StripeSdkImpl+PaymentSheet.swift +15 -8
  29. package/ios/StripeSdkImpl.swift +6 -6
  30. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  31. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  32. package/lib/commonjs/components/AddressSheet.js +1 -1
  33. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  34. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  35. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  36. package/lib/commonjs/components/CardField.js +1 -1
  37. package/lib/commonjs/components/CardField.js.map +1 -1
  38. package/lib/commonjs/components/CardForm.js +1 -1
  39. package/lib/commonjs/components/CardForm.js.map +1 -1
  40. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  41. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  42. package/lib/commonjs/components/StripeContainer.js +1 -1
  43. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  44. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  45. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  46. package/lib/commonjs/types/PaymentIntent.js.map +1 -1
  47. package/lib/module/components/AddToWalletButton.js +1 -1
  48. package/lib/module/components/AddToWalletButton.js.map +1 -1
  49. package/lib/module/components/AddressSheet.js +1 -1
  50. package/lib/module/components/AddressSheet.js.map +1 -1
  51. package/lib/module/components/AuBECSDebitForm.js +1 -1
  52. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  53. package/lib/module/components/CardField.js +1 -1
  54. package/lib/module/components/CardField.js.map +1 -1
  55. package/lib/module/components/CardForm.js +1 -1
  56. package/lib/module/components/CardForm.js.map +1 -1
  57. package/lib/module/components/PlatformPayButton.js +1 -1
  58. package/lib/module/components/PlatformPayButton.js.map +1 -1
  59. package/lib/module/components/StripeContainer.js +1 -1
  60. package/lib/module/components/StripeContainer.js.map +1 -1
  61. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  62. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  63. package/lib/module/types/PaymentIntent.js.map +1 -1
  64. package/lib/typescript/src/types/PaymentIntent.d.ts +1 -9
  65. package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
  66. package/lib/typescript/src/types/PaymentMethod.d.ts +2 -8
  67. package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
  68. package/package.json +1 -1
  69. package/src/types/PaymentIntent.ts +0 -10
  70. package/src/types/PaymentMethod.ts +0 -9
  71. package/stripe-react-native.podspec +1 -1
  72. package/android/.idea/AndroidProjectSystem.xml +0 -6
  73. package/android/.idea/caches/deviceStreaming.xml +0 -703
  74. package/android/.idea/compiler.xml +0 -6
  75. package/android/.idea/gradle.xml +0 -18
  76. package/android/.idea/migrations.xml +0 -10
  77. package/android/.idea/misc.xml +0 -10
  78. package/android/.idea/runConfigurations.xml +0 -17
  79. package/android/.idea/vcs.xml +0 -6
  80. package/android/local.properties +0 -8
  81. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherFragment.kt +0 -146
  82. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +0 -68
  83. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherFragment.kt +0 -102
  84. package/android/src/main/java/com/reactnativestripesdk/utils/StripeFragment.kt +0 -52
@@ -0,0 +1,78 @@
1
+ package com.reactnativestripesdk.addresssheet
2
+
3
+ import android.annotation.SuppressLint
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.reactnativestripesdk.utils.ErrorType
7
+ import com.reactnativestripesdk.utils.StripeUIManager
8
+ import com.reactnativestripesdk.utils.createError
9
+ import com.stripe.android.core.reactnative.ReactNativeSdkInternal
10
+ import com.stripe.android.paymentsheet.PaymentSheet
11
+ import com.stripe.android.paymentsheet.addresselement.AddressDetails
12
+ import com.stripe.android.paymentsheet.addresselement.AddressLauncher
13
+ import com.stripe.android.paymentsheet.addresselement.AddressLauncherResult
14
+
15
+ @OptIn(ReactNativeSdkInternal::class)
16
+ class AddressLauncherManager(
17
+ context: ReactApplicationContext,
18
+ appearance: PaymentSheet.Appearance,
19
+ defaultAddress: AddressDetails?,
20
+ allowedCountries: Set<String>,
21
+ buttonTitle: String?,
22
+ title: String?,
23
+ googlePlacesApiKey: String?,
24
+ autocompleteCountries: Set<String>,
25
+ additionalFields: AddressLauncher.AdditionalFieldsConfiguration?,
26
+ private var callback: ((error: WritableMap?, address: AddressDetails?) -> Unit),
27
+ ) : StripeUIManager(context) {
28
+ companion object {
29
+ internal var publishableKey: String? = null
30
+ }
31
+
32
+ private lateinit var addressLauncher: AddressLauncher
33
+ private var configuration =
34
+ AddressLauncher.Configuration(
35
+ appearance = appearance,
36
+ address = defaultAddress,
37
+ allowedCountries = allowedCountries,
38
+ buttonTitle = buttonTitle,
39
+ additionalFields = additionalFields,
40
+ title = title,
41
+ googlePlacesApiKey = googlePlacesApiKey,
42
+ autocompleteCountries = autocompleteCountries,
43
+ )
44
+
45
+ override fun onPresent() {
46
+ val activity = getCurrentActivityOrResolveWithError(promise) ?: return
47
+ publishableKey?.let { publishableKey ->
48
+ @SuppressLint("RestrictedApi")
49
+ addressLauncher =
50
+ AddressLauncher(activity, signal, ::onAddressLauncherResult).also {
51
+ it.present(publishableKey = publishableKey, configuration = configuration)
52
+ }
53
+ }
54
+ ?: run {
55
+ callback.invoke(
56
+ createError(
57
+ ErrorType.Failed.toString(),
58
+ "No publishable key set. Stripe has not been initialized. Initialize Stripe in your app with the StripeProvider component or the initStripe method.",
59
+ ),
60
+ null,
61
+ )
62
+ }
63
+ }
64
+
65
+ private fun onAddressLauncherResult(result: AddressLauncherResult) {
66
+ when (result) {
67
+ is AddressLauncherResult.Canceled -> {
68
+ callback.invoke(
69
+ createError(ErrorType.Canceled.toString(), "The flow has been canceled."),
70
+ null,
71
+ )
72
+ }
73
+ is AddressLauncherResult.Succeeded -> {
74
+ callback.invoke(null, result.address)
75
+ }
76
+ }
77
+ }
78
+ }
@@ -1,7 +1,6 @@
1
1
  package com.reactnativestripesdk.addresssheet
2
2
 
3
3
  import android.annotation.SuppressLint
4
- import android.os.Bundle
5
4
  import android.util.Log
6
5
  import android.widget.FrameLayout
7
6
  import com.facebook.react.bridge.ReadableMap
@@ -13,7 +12,7 @@ import com.reactnativestripesdk.buildPaymentSheetAppearance
13
12
  import com.reactnativestripesdk.utils.ErrorType
14
13
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
15
14
  import com.reactnativestripesdk.utils.createError
16
- import com.reactnativestripesdk.utils.toBundleObject
15
+ import com.reactnativestripesdk.utils.getBooleanOr
17
16
  import com.stripe.android.paymentsheet.PaymentSheet
18
17
  import com.stripe.android.paymentsheet.addresselement.AddressDetails
19
18
  import com.stripe.android.paymentsheet.addresselement.AddressLauncher
@@ -31,6 +30,14 @@ class AddressSheetView(
31
30
  private var googlePlacesApiKey: String? = null
32
31
  private var autocompleteCountries: Set<String> = emptySet()
33
32
  private var additionalFields: AddressLauncher.AdditionalFieldsConfiguration? = null
33
+ private var addressSheetManager: AddressLauncherManager? = null
34
+
35
+ override fun onDetachedFromWindow() {
36
+ super.onDetachedFromWindow()
37
+
38
+ addressSheetManager?.destroy()
39
+ addressSheetManager = null
40
+ }
34
41
 
35
42
  private fun onSubmit(params: WritableMap) {
36
43
  UIManagerHelper.getEventDispatcherForReactTag(context, id)?.dispatchEvent(
@@ -59,29 +66,37 @@ class AddressSheetView(
59
66
  private fun launchAddressSheet() {
60
67
  val appearance =
61
68
  try {
62
- buildPaymentSheetAppearance(toBundleObject(appearanceParams), context)
69
+ buildPaymentSheetAppearance(appearanceParams, context)
63
70
  } catch (error: PaymentSheetAppearanceException) {
64
71
  onError(createError(ErrorType.Failed.toString(), error))
65
72
  return
66
73
  }
67
- AddressLauncherFragment().presentAddressSheet(
68
- context,
69
- appearance,
70
- defaultAddress,
71
- allowedCountries,
72
- buttonTitle,
73
- sheetTitle,
74
- googlePlacesApiKey,
75
- autocompleteCountries,
76
- additionalFields,
77
- ) { error, address ->
78
- if (address != null) {
79
- onSubmit(buildResult(address))
80
- } else {
81
- onError(error)
74
+ addressSheetManager?.destroy()
75
+ addressSheetManager =
76
+ AddressLauncherManager(
77
+ context.reactApplicationContext,
78
+ appearance,
79
+ defaultAddress,
80
+ allowedCountries,
81
+ buttonTitle,
82
+ sheetTitle,
83
+ googlePlacesApiKey,
84
+ autocompleteCountries,
85
+ additionalFields,
86
+ ) { error, address ->
87
+ addressSheetManager?.destroy()
88
+ addressSheetManager = null
89
+
90
+ if (address != null) {
91
+ onSubmit(buildResult(address))
92
+ } else {
93
+ onError(error)
94
+ }
95
+ isVisible = false
96
+ }.also {
97
+ it.create()
98
+ it.present()
82
99
  }
83
- isVisible = false
84
- }
85
100
  }
86
101
 
87
102
  fun setAppearance(appearanceParams: ReadableMap?) {
@@ -117,27 +132,25 @@ class AddressSheetView(
117
132
  }
118
133
 
119
134
  companion object {
120
- internal fun buildAddressDetails(bundle: Bundle): AddressDetails =
135
+ internal fun buildAddressDetails(map: ReadableMap): AddressDetails =
121
136
  AddressDetails(
122
- name = bundle.getString("name"),
123
- address = buildAddress(bundle.getBundle("address")),
124
- phoneNumber = bundle.getString("phone"),
125
- isCheckboxSelected = bundle.getBoolean("isCheckboxSelected"),
137
+ name = map.getString("name"),
138
+ address = buildAddress(map.getMap("address")),
139
+ phoneNumber = map.getString("phone"),
140
+ isCheckboxSelected = map.getBooleanOr("isCheckboxSelected", false),
126
141
  )
127
142
 
128
- internal fun buildAddressDetails(map: ReadableMap): AddressDetails = buildAddressDetails(toBundleObject(map))
129
-
130
- internal fun buildAddress(bundle: Bundle?): PaymentSheet.Address? {
131
- if (bundle == null) {
143
+ internal fun buildAddress(map: ReadableMap?): PaymentSheet.Address? {
144
+ if (map == null) {
132
145
  return null
133
146
  }
134
147
  return PaymentSheet.Address(
135
- city = bundle.getString("city"),
136
- country = bundle.getString("country"),
137
- line1 = bundle.getString("line1"),
138
- line2 = bundle.getString("line2"),
139
- state = bundle.getString("state"),
140
- postalCode = bundle.getString("postalCode"),
148
+ city = map.getString("city"),
149
+ country = map.getString("country"),
150
+ line1 = map.getString("line1"),
151
+ line2 = map.getString("line2"),
152
+ state = map.getString("state"),
153
+ postalCode = map.getString("postalCode"),
141
154
  )
142
155
  }
143
156
 
@@ -10,6 +10,7 @@ import android.util.Log
10
10
  import com.facebook.react.bridge.Arguments
11
11
  import com.facebook.react.bridge.Promise
12
12
  import com.facebook.react.bridge.ReactApplicationContext
13
+ import com.facebook.react.bridge.ReadableMap
13
14
  import com.facebook.react.bridge.WritableMap
14
15
  import com.facebook.react.bridge.WritableNativeMap
15
16
  import com.reactnativestripesdk.ReactNativeCustomerAdapter
@@ -17,6 +18,8 @@ import com.reactnativestripesdk.ReactNativeCustomerSessionProvider
17
18
  import com.reactnativestripesdk.buildPaymentSheetAppearance
18
19
  import com.reactnativestripesdk.getBase64FromBitmap
19
20
  import com.reactnativestripesdk.getBitmapFromDrawable
21
+ import com.reactnativestripesdk.getIntegerArrayList
22
+ import com.reactnativestripesdk.getStringArrayList
20
23
  import com.reactnativestripesdk.mapToAddressCollectionMode
21
24
  import com.reactnativestripesdk.mapToCardBrandAcceptance
22
25
  import com.reactnativestripesdk.mapToCollectionMode
@@ -24,65 +27,50 @@ import com.reactnativestripesdk.utils.CreateTokenErrorType
24
27
  import com.reactnativestripesdk.utils.ErrorType
25
28
  import com.reactnativestripesdk.utils.KeepJsAwakeTask
26
29
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
27
- import com.reactnativestripesdk.utils.StripeFragment
30
+ import com.reactnativestripesdk.utils.StripeUIManager
28
31
  import com.reactnativestripesdk.utils.createError
32
+ import com.reactnativestripesdk.utils.getBooleanOr
29
33
  import com.reactnativestripesdk.utils.mapFromPaymentMethod
30
34
  import com.reactnativestripesdk.utils.mapToPreferredNetworks
31
35
  import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
36
+ import com.stripe.android.core.reactnative.ReactNativeSdkInternal
32
37
  import com.stripe.android.customersheet.CustomerAdapter
33
38
  import com.stripe.android.customersheet.CustomerEphemeralKey
34
39
  import com.stripe.android.customersheet.CustomerSheet
35
40
  import com.stripe.android.customersheet.CustomerSheetResult
36
41
  import com.stripe.android.customersheet.PaymentOptionSelection
37
42
  import com.stripe.android.model.PaymentMethod
38
- import com.stripe.android.paymentsheet.ExperimentalCustomerSessionApi
39
43
  import com.stripe.android.paymentsheet.PaymentSheet
40
44
  import kotlinx.coroutines.CoroutineScope
41
45
  import kotlinx.coroutines.Dispatchers
42
46
  import kotlinx.coroutines.launch
43
47
 
44
- @OptIn(ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class, ExperimentalCustomerSessionApi::class)
45
- class CustomerSheetFragment : StripeFragment() {
48
+ @OptIn(ReactNativeSdkInternal::class, ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class)
49
+ class CustomerSheetManager(
50
+ context: ReactApplicationContext,
51
+ private var arguments: ReadableMap,
52
+ private var customerAdapterOverrides: ReadableMap,
53
+ private var initPromise: Promise,
54
+ ) : StripeUIManager(context) {
46
55
  private var customerSheet: CustomerSheet? = null
47
56
  internal var customerAdapter: ReactNativeCustomerAdapter? = null
48
57
  internal var customerSessionProvider: ReactNativeCustomerSessionProvider? = null
49
- internal var context: ReactApplicationContext? = null
50
- internal var initPromise: Promise? = null
51
58
  private var presentPromise: Promise? = null
52
59
  private var keepJsAwake: KeepJsAwakeTask? = null
53
60
 
54
- override fun prepare() {
55
- val context =
56
- context
57
- ?: run {
58
- Log.e(
59
- "StripeReactNative",
60
- "No context found during CustomerSheet.initialize. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
61
- )
62
- return
63
- }
64
- val initPromise =
65
- initPromise
66
- ?: run {
67
- Log.e(
68
- "StripeReactNative",
69
- "No promise found for CustomerSheet.initialize. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
70
- )
71
- return
72
- }
73
-
74
- val headerTextForSelectionScreen = arguments?.getString("headerTextForSelectionScreen")
75
- val merchantDisplayName = arguments?.getString("merchantDisplayName")
76
- val googlePayEnabled = arguments?.getBoolean("googlePayEnabled") ?: false
77
- val billingDetailsBundle = arguments?.getBundle("defaultBillingDetails")
78
- val billingConfigParams = arguments?.getBundle("billingDetailsCollectionConfiguration")
61
+ override fun onCreate() {
62
+ val headerTextForSelectionScreen = arguments.getString("headerTextForSelectionScreen")
63
+ val merchantDisplayName = arguments.getString("merchantDisplayName")
64
+ val googlePayEnabled = arguments.getBooleanOr("googlePayEnabled", false)
65
+ val billingDetailsMap = arguments.getMap("defaultBillingDetails")
66
+ val billingConfigParams = arguments.getMap("billingDetailsCollectionConfiguration")
79
67
  val allowsRemovalOfLastSavedPaymentMethod =
80
- arguments?.getBoolean("allowsRemovalOfLastSavedPaymentMethod", true) ?: true
81
- val paymentMethodOrder = arguments?.getStringArrayList("paymentMethodOrder")
68
+ arguments.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
69
+ val paymentMethodOrder = arguments.getStringArrayList("paymentMethodOrder")
82
70
 
83
71
  val appearance =
84
72
  try {
85
- buildPaymentSheetAppearance(arguments?.getBundle("appearance"), context)
73
+ buildPaymentSheetAppearance(arguments.getMap("appearance"), context)
86
74
  } catch (error: PaymentSheetAppearanceException) {
87
75
  initPromise.resolve(createError(ErrorType.Failed.toString(), error))
88
76
  return
@@ -95,13 +83,13 @@ class CustomerSheetFragment : StripeFragment() {
95
83
  .googlePayEnabled(googlePayEnabled)
96
84
  .headerTextForSelectionScreen(headerTextForSelectionScreen)
97
85
  .preferredNetworks(
98
- mapToPreferredNetworks(arguments?.getIntegerArrayList("preferredNetworks")),
86
+ mapToPreferredNetworks(arguments.getIntegerArrayList("preferredNetworks")),
99
87
  ).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
100
88
  .cardBrandAcceptance(mapToCardBrandAcceptance(arguments))
101
89
 
102
90
  paymentMethodOrder?.let { configuration.paymentMethodOrder(it) }
103
- billingDetailsBundle?.let {
104
- configuration.defaultBillingDetails(createDefaultBillingDetails(billingDetailsBundle))
91
+ billingDetailsMap?.let {
92
+ configuration.defaultBillingDetails(createDefaultBillingDetails(billingDetailsMap))
105
93
  }
106
94
  billingConfigParams?.let {
107
95
  configuration.billingDetailsCollectionConfiguration(
@@ -109,8 +97,10 @@ class CustomerSheetFragment : StripeFragment() {
109
97
  )
110
98
  }
111
99
 
112
- val customerEphemeralKeySecret = arguments?.getString("customerEphemeralKeySecret")
113
- val intentConfiguration = createIntentConfiguration(arguments?.getBundle("intentConfiguration"))
100
+ val activity = getCurrentActivityOrResolveWithError(initPromise) ?: return
101
+
102
+ val customerEphemeralKeySecret = arguments.getString("customerEphemeralKeySecret")
103
+ val intentConfiguration = createIntentConfiguration(arguments.getMap("intentConfiguration"))
114
104
  if (customerEphemeralKeySecret == null && intentConfiguration == null) {
115
105
  initPromise.resolve(
116
106
  createError(
@@ -128,32 +118,31 @@ class CustomerSheetFragment : StripeFragment() {
128
118
 
129
119
  customerSheet =
130
120
  CustomerSheet.create(
131
- fragment = this,
121
+ activity = activity,
132
122
  customerSessionProvider = customerSessionProvider,
133
123
  callback = ::handleResult,
134
124
  )
135
125
  } else if (intentConfiguration == null) {
136
- val customerId = arguments?.getString("customerId")
126
+ val customerId = arguments.getString("customerId")
137
127
  if (customerId == null) {
138
128
  initPromise.resolve(
139
129
  createError(ErrorType.Failed.toString(), "When using `customerEphemeralKeySecret` you must provide a value for `customerId`"),
140
130
  )
141
131
  return
142
132
  }
143
- val setupIntentClientSecret = arguments?.getString("setupIntentClientSecret")
144
- val customerAdapterOverrideParams = arguments?.getBundle("customerAdapter")
133
+ val setupIntentClientSecret = arguments.getString("setupIntentClientSecret")
145
134
  val customerAdapter =
146
135
  createCustomerAdapter(
147
136
  context,
148
- customerId!!,
137
+ customerId,
149
138
  customerEphemeralKeySecret,
150
139
  setupIntentClientSecret,
151
- customerAdapterOverrideParams,
140
+ customerAdapterOverrides,
152
141
  ).also { this.customerAdapter = it }
153
142
 
154
143
  customerSheet =
155
144
  CustomerSheet.create(
156
- fragment = this,
145
+ activity = activity,
157
146
  customerAdapter = customerAdapter,
158
147
  callback = ::handleResult,
159
148
  )
@@ -193,16 +182,15 @@ class CustomerSheetFragment : StripeFragment() {
193
182
  resolvePresentPromise(promiseResult)
194
183
  }
195
184
 
196
- fun present(
197
- timeout: Long?,
198
- promise: Promise,
199
- ) {
200
- keepJsAwake = context?.let { KeepJsAwakeTask(it).apply { start() } }
185
+ override fun onPresent() {
186
+ keepJsAwake = context.let { KeepJsAwakeTask(it).apply { start() } }
201
187
  presentPromise = promise
188
+ val timeout = timeout
202
189
  if (timeout != null) {
203
190
  presentWithTimeout(timeout)
191
+ } else {
192
+ customerSheet?.present() ?: run { resolvePresentPromise(createMissingInitError()) }
204
193
  }
205
- customerSheet?.present() ?: run { resolvePresentPromise(createMissingInitError()) }
206
194
  }
207
195
 
208
196
  private fun presentWithTimeout(timeout: Long) {
@@ -232,7 +220,7 @@ class CustomerSheetFragment : StripeFragment() {
232
220
 
233
221
  override fun onActivityDestroyed(activity: Activity) {
234
222
  activities = mutableListOf()
235
- context?.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
223
+ context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
236
224
  }
237
225
  }
238
226
 
@@ -248,7 +236,7 @@ class CustomerSheetFragment : StripeFragment() {
248
236
  )
249
237
 
250
238
  context
251
- ?.currentActivity
239
+ .currentActivity
252
240
  ?.application
253
241
  ?.registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
254
242
 
@@ -304,37 +292,35 @@ class CustomerSheetFragment : StripeFragment() {
304
292
  }
305
293
 
306
294
  companion object {
307
- internal const val TAG = "customer_sheet_launch_fragment"
308
-
309
295
  internal fun createMissingInitError(): WritableMap =
310
296
  createError(ErrorType.Failed.toString(), "No customer sheet has been initialized yet.")
311
297
 
312
- internal fun createDefaultBillingDetails(bundle: Bundle): PaymentSheet.BillingDetails {
313
- val addressBundle = bundle.getBundle("address")
298
+ internal fun createDefaultBillingDetails(map: ReadableMap): PaymentSheet.BillingDetails {
299
+ val addressMap = map.getMap("address")
314
300
  val address =
315
301
  PaymentSheet.Address(
316
- addressBundle?.getString("city"),
317
- addressBundle?.getString("country"),
318
- addressBundle?.getString("line1"),
319
- addressBundle?.getString("line2"),
320
- addressBundle?.getString("postalCode"),
321
- addressBundle?.getString("state"),
302
+ addressMap?.getString("city"),
303
+ addressMap?.getString("country"),
304
+ addressMap?.getString("line1"),
305
+ addressMap?.getString("line2"),
306
+ addressMap?.getString("postalCode"),
307
+ addressMap?.getString("state"),
322
308
  )
323
309
  return PaymentSheet.BillingDetails(
324
310
  address,
325
- bundle.getString("email"),
326
- bundle.getString("name"),
327
- bundle.getString("phone"),
311
+ map.getString("email"),
312
+ map.getString("name"),
313
+ map.getString("phone"),
328
314
  )
329
315
  }
330
316
 
331
- internal fun createBillingDetailsCollectionConfiguration(bundle: Bundle): PaymentSheet.BillingDetailsCollectionConfiguration =
317
+ internal fun createBillingDetailsCollectionConfiguration(map: ReadableMap): PaymentSheet.BillingDetailsCollectionConfiguration =
332
318
  PaymentSheet.BillingDetailsCollectionConfiguration(
333
- name = mapToCollectionMode(bundle.getString("name")),
334
- phone = mapToCollectionMode(bundle.getString("phone")),
335
- email = mapToCollectionMode(bundle.getString("email")),
336
- address = mapToAddressCollectionMode(bundle.getString("address")),
337
- attachDefaultsToPaymentMethod = bundle.getBoolean("attachDefaultsToPaymentMethod", false),
319
+ name = mapToCollectionMode(map.getString("name")),
320
+ phone = mapToCollectionMode(map.getString("phone")),
321
+ email = mapToCollectionMode(map.getString("email")),
322
+ address = mapToAddressCollectionMode(map.getString("address")),
323
+ attachDefaultsToPaymentMethod = map.getBooleanOr("attachDefaultsToPaymentMethod", false),
338
324
  )
339
325
 
340
326
  internal fun createCustomerAdapter(
@@ -342,7 +328,7 @@ class CustomerSheetFragment : StripeFragment() {
342
328
  customerId: String,
343
329
  customerEphemeralKeySecret: String,
344
330
  setupIntentClientSecret: String?,
345
- customerAdapterOverrideParams: Bundle?,
331
+ customerAdapterOverrideParams: ReadableMap?,
346
332
  ): ReactNativeCustomerAdapter {
347
333
  val ephemeralKeyProvider = {
348
334
  CustomerAdapter.Result.success(
@@ -375,18 +361,17 @@ class CustomerSheetFragment : StripeFragment() {
375
361
  context = context,
376
362
  adapter = customerAdapter,
377
363
  overridesFetchPaymentMethods =
378
- customerAdapterOverrideParams?.getBoolean("fetchPaymentMethods") ?: false,
364
+ customerAdapterOverrideParams.getBooleanOr("fetchPaymentMethods", false),
379
365
  overridesAttachPaymentMethod =
380
- customerAdapterOverrideParams?.getBoolean("attachPaymentMethod") ?: false,
366
+ customerAdapterOverrideParams.getBooleanOr("attachPaymentMethod", false),
381
367
  overridesDetachPaymentMethod =
382
- customerAdapterOverrideParams?.getBoolean("detachPaymentMethod") ?: false,
368
+ customerAdapterOverrideParams.getBooleanOr("detachPaymentMethod", false),
383
369
  overridesSetSelectedPaymentOption =
384
- customerAdapterOverrideParams?.getBoolean("setSelectedPaymentOption") ?: false,
370
+ customerAdapterOverrideParams.getBooleanOr("setSelectedPaymentOption", false),
385
371
  overridesFetchSelectedPaymentOption =
386
- customerAdapterOverrideParams?.getBoolean("fetchSelectedPaymentOption") ?: false,
372
+ customerAdapterOverrideParams.getBooleanOr("fetchSelectedPaymentOption", false),
387
373
  overridesSetupIntentClientSecretForCustomerAttach =
388
- customerAdapterOverrideParams?.getBoolean("setupIntentClientSecretForCustomerAttach")
389
- ?: false,
374
+ customerAdapterOverrideParams.getBooleanOr("setupIntentClientSecretForCustomerAttach", false),
390
375
  )
391
376
  }
392
377
 
@@ -414,15 +399,15 @@ class CustomerSheetFragment : StripeFragment() {
414
399
  return paymentOptionResult
415
400
  }
416
401
 
417
- internal fun createIntentConfiguration(intentConfigurationBundle: Bundle?): CustomerSheet.IntentConfiguration? =
402
+ internal fun createIntentConfiguration(intentConfigurationBundle: ReadableMap?): CustomerSheet.IntentConfiguration? =
418
403
  intentConfigurationBundle?.let { bundle ->
419
- val onBehalfOf = bundle?.getString("onBehalfOf")
404
+ val onBehalfOf = bundle.getString("onBehalfOf")
420
405
  CustomerSheet.IntentConfiguration
421
406
  .Builder()
422
- .paymentMethodTypes(bundle?.getStringArrayList("paymentMethodTypes") ?: emptyList())
407
+ .paymentMethodTypes(bundle.getStringArrayList("paymentMethodTypes") ?: emptyList())
423
408
  .apply {
424
409
  if (onBehalfOf != null) {
425
- this.onBehalfOf(onBehalfOf!!)
410
+ this.onBehalfOf(onBehalfOf)
426
411
  }
427
412
  }.build()
428
413
  }
@@ -2,10 +2,8 @@ package com.reactnativestripesdk
2
2
 
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.stripe.android.customersheet.CustomerSheet
5
- import com.stripe.android.paymentsheet.ExperimentalCustomerSessionApi
6
5
  import kotlinx.coroutines.CompletableDeferred
7
6
 
8
- @OptIn(ExperimentalCustomerSessionApi::class)
9
7
  class ReactNativeCustomerSessionProvider(
10
8
  val context: ReactApplicationContext,
11
9
  val intentConfiguration: CustomerSheet.IntentConfiguration,
@@ -3,10 +3,8 @@ package com.reactnativestripesdk.utils
3
3
  import android.content.Context
4
4
  import android.view.View
5
5
  import android.view.inputmethod.InputMethodManager
6
- import androidx.fragment.app.Fragment
7
- import androidx.fragment.app.FragmentActivity
8
6
  import com.facebook.react.bridge.Dynamic
9
- import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.ReadableArray
10
8
  import com.facebook.react.bridge.ReadableMap
11
9
  import com.facebook.react.bridge.ReadableType
12
10
 
@@ -26,17 +24,54 @@ fun View.hideSoftKeyboard() {
26
24
  }
27
25
  }
28
26
 
29
- fun Fragment.removeFragment(context: ReactApplicationContext) {
30
- (context.currentActivity as? FragmentActivity)?.supportFragmentManager?.let {
31
- if (it.findFragmentByTag(this.tag) != null) {
32
- it.beginTransaction().remove(this).commitAllowingStateLoss()
33
- }
27
+ fun ReadableMap?.getBooleanOr(
28
+ key: String,
29
+ default: Boolean,
30
+ ): Boolean = if (this?.hasKey(key) == true && this.getType(key) == ReadableType.Boolean) this.getBoolean(key) else default
31
+
32
+ fun ReadableMap?.getIntOrNull(key: String): Int? =
33
+ if (this?.hasKey(key) == true && this.getType(key) == ReadableType.Number) this.getInt(key) else null
34
+
35
+ fun ReadableMap?.getIntOr(
36
+ key: String,
37
+ default: Int,
38
+ ): Int = getIntOrNull(key) ?: default
39
+
40
+ fun ReadableMap?.getDoubleOrNull(key: String): Double? =
41
+ if (this?.hasKey(key) == true && this.getType(key) == ReadableType.Number) this.getDouble(key) else null
42
+
43
+ fun ReadableMap?.getDoubleOr(
44
+ key: String,
45
+ default: Double,
46
+ ): Double = getDoubleOrNull(key) ?: default
47
+
48
+ fun ReadableMap?.getFloatOrNull(key: String): Float? =
49
+ if (this?.hasKey(key) == true && this.getType(key) == ReadableType.Number) this.getDouble(key).toFloat() else null
50
+
51
+ fun ReadableMap?.getBooleanOrNull(key: String): Boolean? =
52
+ if (this?.hasKey(key) == true && this.getType(key) == ReadableType.Boolean) this.getBoolean(key) else null
53
+
54
+ fun ReadableMap?.getFloatOr(
55
+ key: String,
56
+ default: Float,
57
+ ): Float = getFloatOrNull(key) ?: default
58
+
59
+ fun ReadableMap.isEmpty() = !this.keySetIterator().hasNextKey()
60
+
61
+ fun ReadableMap.forEachKey(callback: (key: String) -> Unit) {
62
+ val iterator = this.keySetIterator()
63
+ while (iterator.hasNextKey()) {
64
+ val key = iterator.nextKey()
65
+ callback(key)
34
66
  }
35
67
  }
36
68
 
37
- fun ReadableMap.getBooleanOr(
38
- key: String,
39
- default: Boolean,
40
- ): Boolean = if (this.hasKey(key)) this.getBoolean(key) else default
69
+ fun ReadableArray.forEachMap(callback: (map: ReadableMap) -> Unit) {
70
+ for (i in 0 until this.size()) {
71
+ if (this.getType(i) == ReadableType.Map) {
72
+ this.getMap(i)?.let(callback)
73
+ }
74
+ }
75
+ }
41
76
 
42
77
  fun Dynamic.asMapOrNull(): ReadableMap? = if (this.type == ReadableType.Map) this.asMap() else null