@stripe/stripe-react-native 0.55.1 → 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 (126) 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/EventEmitterCompat.kt +8 -0
  8. package/android/src/main/java/com/reactnativestripesdk/{FinancialConnectionsSheetFragment.kt → FinancialConnectionsSheetManager.kt} +30 -77
  9. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +107 -0
  10. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherManager.kt +37 -0
  11. package/android/src/main/java/com/reactnativestripesdk/{PaymentLauncherFragment.kt → PaymentLauncherManager.kt} +39 -77
  12. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +8 -20
  13. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +366 -483
  14. package/android/src/main/java/com/reactnativestripesdk/{PaymentSheetFragment.kt → PaymentSheetManager.kt} +79 -88
  15. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +3 -2
  16. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +213 -210
  17. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +78 -0
  18. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +48 -35
  19. package/android/src/main/java/com/reactnativestripesdk/customersheet/{CustomerSheetFragment.kt → CustomerSheetManager.kt} +127 -104
  20. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +35 -0
  21. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +47 -12
  22. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +87 -142
  23. package/android/src/main/java/com/reactnativestripesdk/utils/StripeUIManager.kt +62 -0
  24. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +12 -0
  25. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +4 -0
  26. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -64
  27. package/ios/AddressSheet/AddressSheetView.swift +1 -1
  28. package/ios/ApplePayButtonManager.m +1 -1
  29. package/ios/ApplePayButtonView.swift +2 -2
  30. package/ios/FinancialConnections.swift +2 -2
  31. package/ios/Mappers.swift +2 -4
  32. package/ios/NewArch/ApplePayButtonComponentView.mm +1 -1
  33. package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
  34. package/ios/OldArch/StripeSdkEventEmitterCompat.m +12 -0
  35. package/ios/PaymentMethodFactory.swift +0 -17
  36. package/ios/PushProvisioning/AddToWalletButtonView.swift +1 -1
  37. package/ios/StripeSdk.mm +14 -0
  38. package/ios/StripeSdkEmitter.swift +2 -0
  39. package/ios/StripeSdkImpl+CustomerSheet.swift +71 -20
  40. package/ios/StripeSdkImpl+PaymentSheet.swift +29 -13
  41. package/ios/StripeSdkImpl.swift +9 -7
  42. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  43. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  44. package/lib/commonjs/components/AddressSheet.js +1 -1
  45. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  46. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  47. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  48. package/lib/commonjs/components/CardField.js +1 -1
  49. package/lib/commonjs/components/CardField.js.map +1 -1
  50. package/lib/commonjs/components/CardForm.js +1 -1
  51. package/lib/commonjs/components/CardForm.js.map +1 -1
  52. package/lib/commonjs/components/CustomerSheet.js +1 -1
  53. package/lib/commonjs/components/CustomerSheet.js.map +1 -1
  54. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  55. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  56. package/lib/commonjs/components/StripeContainer.js +1 -1
  57. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  58. package/lib/commonjs/events.js.map +1 -1
  59. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  60. package/lib/commonjs/specs/NativeApplePayButton.js.map +1 -1
  61. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  62. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  63. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  64. package/lib/commonjs/types/PaymentIntent.js.map +1 -1
  65. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  66. package/lib/module/components/AddToWalletButton.js +1 -1
  67. package/lib/module/components/AddToWalletButton.js.map +1 -1
  68. package/lib/module/components/AddressSheet.js +1 -1
  69. package/lib/module/components/AddressSheet.js.map +1 -1
  70. package/lib/module/components/AuBECSDebitForm.js +1 -1
  71. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  72. package/lib/module/components/CardField.js +1 -1
  73. package/lib/module/components/CardField.js.map +1 -1
  74. package/lib/module/components/CardForm.js +1 -1
  75. package/lib/module/components/CardForm.js.map +1 -1
  76. package/lib/module/components/CustomerSheet.js +1 -1
  77. package/lib/module/components/CustomerSheet.js.map +1 -1
  78. package/lib/module/components/PlatformPayButton.js +1 -1
  79. package/lib/module/components/PlatformPayButton.js.map +1 -1
  80. package/lib/module/components/StripeContainer.js +1 -1
  81. package/lib/module/components/StripeContainer.js.map +1 -1
  82. package/lib/module/events.js.map +1 -1
  83. package/lib/module/specs/NativeApplePayButton.js +1 -1
  84. package/lib/module/specs/NativeApplePayButton.js.map +1 -1
  85. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  86. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  87. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  88. package/lib/module/types/PaymentIntent.js.map +1 -1
  89. package/lib/module/types/PaymentSheet.js.map +1 -1
  90. package/lib/typescript/src/components/CustomerSheet.d.ts +1 -1
  91. package/lib/typescript/src/components/CustomerSheet.d.ts.map +1 -1
  92. package/lib/typescript/src/events.d.ts +2 -0
  93. package/lib/typescript/src/events.d.ts.map +1 -1
  94. package/lib/typescript/src/specs/NativeApplePayButton.d.ts +1 -1
  95. package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -1
  96. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +3 -1
  97. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  98. package/lib/typescript/src/types/ConfirmationToken.d.ts +0 -3
  99. package/lib/typescript/src/types/ConfirmationToken.d.ts.map +1 -1
  100. package/lib/typescript/src/types/CustomerSheet.d.ts +70 -12
  101. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  102. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +2 -4
  103. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  104. package/lib/typescript/src/types/PaymentIntent.d.ts +1 -9
  105. package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
  106. package/lib/typescript/src/types/PaymentMethod.d.ts +2 -8
  107. package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
  108. package/lib/typescript/src/types/PaymentSheet.d.ts +1 -6
  109. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  110. package/package.json +1 -1
  111. package/src/components/CustomerSheet.tsx +65 -9
  112. package/src/components/PlatformPayButton.tsx +1 -1
  113. package/src/events.ts +2 -0
  114. package/src/specs/NativeApplePayButton.ts +1 -1
  115. package/src/specs/NativeStripeSdkModule.ts +7 -0
  116. package/src/types/ConfirmationToken.ts +0 -3
  117. package/src/types/CustomerSheet.ts +80 -12
  118. package/src/types/EmbeddedPaymentElement.tsx +2 -4
  119. package/src/types/PaymentIntent.ts +0 -10
  120. package/src/types/PaymentMethod.ts +0 -9
  121. package/src/types/PaymentSheet.ts +1 -6
  122. package/stripe-react-native.podspec +1 -1
  123. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherFragment.kt +0 -146
  124. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +0 -68
  125. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherFragment.kt +0 -102
  126. package/android/src/main/java/com/reactnativestripesdk/utils/StripeFragment.kt +0 -52
@@ -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.29.0
6
+ StripeSdk_stripeVersion=22.1.+
@@ -10,6 +10,7 @@ import com.facebook.react.uimanager.UIManagerHelper
10
10
  import com.google.android.material.shape.CornerFamily
11
11
  import com.google.android.material.shape.MaterialShapeDrawable
12
12
  import com.google.android.material.shape.ShapeAppearanceModel
13
+ import com.reactnativestripesdk.utils.getIntOr
13
14
  import com.reactnativestripesdk.utils.getIntOrNull
14
15
  import com.reactnativestripesdk.utils.getValOr
15
16
  import com.stripe.android.databinding.StripeBecsDebitWidgetBinding
@@ -41,11 +42,11 @@ class AuBECSDebitFormView(
41
42
  val textColor = getValOr(value, "textColor", null)
42
43
  val textErrorColor = getValOr(value, "textErrorColor", null)
43
44
  val placeholderColor = getValOr(value, "placeholderColor", null)
44
- val fontSize = getIntOrNull(value, "fontSize")
45
- val borderWidth = getIntOrNull(value, "borderWidth")
45
+ val fontSize = value.getIntOrNull("fontSize")
46
+ val borderWidth = value.getIntOrNull("borderWidth")
46
47
  val backgroundColor = getValOr(value, "backgroundColor", null)
47
48
  val borderColor = getValOr(value, "borderColor", null)
48
- val borderRadius = getIntOrNull(value, "borderRadius") ?: 0
49
+ val borderRadius = value.getIntOr("borderRadius", 0)
49
50
 
50
51
  textColor?.let {
51
52
  (binding.accountNumberEditText as StripeEditText).setTextColor(Color.parseColor(it))
@@ -19,6 +19,7 @@ import com.google.android.material.shape.CornerFamily
19
19
  import com.google.android.material.shape.MaterialShapeDrawable
20
20
  import com.google.android.material.shape.ShapeAppearanceModel
21
21
  import com.reactnativestripesdk.utils.PostalCodeUtilities
22
+ import com.reactnativestripesdk.utils.getIntOr
22
23
  import com.reactnativestripesdk.utils.getIntOrNull
23
24
  import com.reactnativestripesdk.utils.getValOr
24
25
  import com.reactnativestripesdk.utils.hideSoftKeyboard
@@ -103,12 +104,12 @@ class CardFieldView(
103
104
  }
104
105
 
105
106
  fun setCardStyle(value: ReadableMap?) {
106
- val borderWidth = getIntOrNull(value, "borderWidth")
107
+ val borderWidth = value.getIntOrNull("borderWidth")
107
108
  val backgroundColor = getValOr(value, "backgroundColor", null)
108
109
  val borderColor = getValOr(value, "borderColor", null)
109
- val borderRadius = getIntOrNull(value, "borderRadius") ?: 0
110
+ val borderRadius = value.getIntOr("borderRadius", 0)
110
111
  val textColor = getValOr(value, "textColor", null)
111
- val fontSize = getIntOrNull(value, "fontSize")
112
+ val fontSize = value.getIntOrNull("fontSize")
112
113
  val fontFamily = getValOr(value, "fontFamily")
113
114
  val placeholderColor = getValOr(value, "placeholderColor", null)
114
115
  val textErrorColor = getValOr(value, "textErrorColor", null)
@@ -281,9 +282,9 @@ class CardFieldView(
281
282
  cardAddress = null
282
283
  }
283
284
 
284
- mCardWidget.cardParams?.let {
285
- cardDetails["brand"] = mapCardBrand(it.brand)
286
- cardDetails["last4"] = it.last4
285
+ mCardWidget.paymentMethodCreateParams?.let {
286
+ cardDetails["brand"] = mapCardBrand(mCardWidget.brand)
287
+ cardDetails["last4"] = it.cardLast4()
287
288
  } ?: run {
288
289
  cardDetails["brand"] = null
289
290
  cardDetails["last4"] = null
@@ -6,7 +6,6 @@ import android.graphics.Color
6
6
  import android.os.Build
7
7
  import android.text.InputFilter
8
8
  import android.view.View
9
- import android.view.View.OnFocusChangeListener
10
9
  import android.widget.FrameLayout
11
10
  import androidx.core.view.setMargins
12
11
  import com.facebook.react.bridge.ReadableMap
@@ -18,6 +17,7 @@ import com.google.android.material.shape.CornerFamily
18
17
  import com.google.android.material.shape.MaterialShapeDrawable
19
18
  import com.google.android.material.shape.ShapeAppearanceModel
20
19
  import com.reactnativestripesdk.utils.PostalCodeUtilities
20
+ import com.reactnativestripesdk.utils.getIntOr
21
21
  import com.reactnativestripesdk.utils.getIntOrNull
22
22
  import com.reactnativestripesdk.utils.getValOr
23
23
  import com.reactnativestripesdk.utils.hideSoftKeyboard
@@ -143,10 +143,10 @@ class CardFormView(
143
143
  fun setCardStyle(value: ReadableMap?) {
144
144
  val backgroundColor = getValOr(value, "backgroundColor", null)
145
145
  val textColor = getValOr(value, "textColor", null)
146
- val borderWidth = getIntOrNull(value, "borderWidth")
146
+ val borderWidth = value.getIntOrNull("borderWidth")
147
147
  val borderColor = getValOr(value, "borderColor", null)
148
- val borderRadius = getIntOrNull(value, "borderRadius") ?: 0
149
- val fontSize = getIntOrNull(value, "fontSize")
148
+ val borderRadius = value.getIntOr("borderRadius", 0)
149
+ val fontSize = value.getIntOrNull("fontSize")
150
150
  val fontFamily = getValOr(value, "fontFamily")
151
151
  val placeholderColor = getValOr(value, "placeholderColor", null)
152
152
  val textErrorColor = getValOr(value, "textErrorColor", null)
@@ -245,16 +245,16 @@ class CardFormView(
245
245
  private fun setListeners() {
246
246
  cardForm.setCardValidCallback { isValid, _ ->
247
247
  if (isValid) {
248
- cardForm.cardParams?.let {
248
+ cardForm.paymentMethodCreateParams?.let {
249
249
  val cardParamsMap = it.toParamMap()["card"] as HashMap<*, *>
250
250
  val cardDetails: MutableMap<String, Any> =
251
251
  mutableMapOf(
252
252
  "expiryMonth" to cardParamsMap["exp_month"] as Int,
253
253
  "expiryYear" to cardParamsMap["exp_year"] as Int,
254
- "last4" to it.last4,
255
- "brand" to mapCardBrand(it.brand),
256
- "postalCode" to (it.address?.postalCode ?: ""),
257
- "country" to (it.address?.country ?: ""),
254
+ "last4" to (it.cardLast4() ?: ""),
255
+ "brand" to mapCardBrand(cardForm.brand),
256
+ "postalCode" to (it.billingDetails?.address?.postalCode ?: ""),
257
+ "country" to (it.billingDetails?.address?.country ?: ""),
258
258
  )
259
259
 
260
260
  if (dangerouslyGetFullCardDetails) {
@@ -277,8 +277,8 @@ class CardFormView(
277
277
  cardAddress =
278
278
  Address
279
279
  .Builder()
280
- .setPostalCode(it.address?.postalCode)
281
- .setCountry(it.address?.country)
280
+ .setPostalCode(it.billingDetails?.address?.postalCode)
281
+ .setCountry(it.billingDetails?.address?.country)
282
282
  .build()
283
283
 
284
284
  cardFormViewBinding.cardMultilineWidget.paymentMethodCard?.let { params ->
@@ -1,15 +1,15 @@
1
1
  package com.reactnativestripesdk
2
2
 
3
- import com.facebook.react.bridge.Promise
3
+ import androidx.activity.ComponentActivity
4
4
  import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.reactnativestripesdk.utils.ErrorType
6
- import com.reactnativestripesdk.utils.StripeFragment
6
+ import com.reactnativestripesdk.utils.StripeUIManager
7
7
  import com.reactnativestripesdk.utils.createError
8
8
  import com.reactnativestripesdk.utils.createResult
9
9
  import com.reactnativestripesdk.utils.mapFromFinancialConnectionsEvent
10
10
  import com.reactnativestripesdk.utils.mapFromPaymentIntentResult
11
11
  import com.reactnativestripesdk.utils.mapFromSetupIntentResult
12
- import com.reactnativestripesdk.utils.removeFragment
12
+ import com.stripe.android.core.reactnative.ReactNativeSdkInternal
13
13
  import com.stripe.android.financialconnections.FinancialConnections
14
14
  import com.stripe.android.model.PaymentIntent
15
15
  import com.stripe.android.model.SetupIntent
@@ -18,18 +18,20 @@ import com.stripe.android.payments.bankaccount.CollectBankAccountConfiguration
18
18
  import com.stripe.android.payments.bankaccount.CollectBankAccountLauncher
19
19
  import com.stripe.android.payments.bankaccount.navigation.CollectBankAccountResult
20
20
 
21
- class CollectBankAccountLauncherFragment : StripeFragment() {
22
- private lateinit var context: ReactApplicationContext
23
- private lateinit var publishableKey: String
24
- private var stripeAccountId: String? = null
25
- private lateinit var clientSecret: String
26
- private var isPaymentIntent: Boolean = false
27
- private lateinit var collectParams: CollectBankAccountConfiguration.USBankAccount
28
- private lateinit var promise: Promise
21
+ @OptIn(ReactNativeSdkInternal::class)
22
+ class CollectBankAccountLauncherManager(
23
+ context: ReactApplicationContext,
24
+ private val publishableKey: String,
25
+ private val stripeAccountId: String? = null,
26
+ private val clientSecret: String,
27
+ private val isPaymentIntent: Boolean,
28
+ private val collectParams: CollectBankAccountConfiguration.USBankAccount,
29
+ ) : StripeUIManager(context) {
29
30
  private lateinit var collectBankAccountLauncher: CollectBankAccountLauncher
30
31
 
31
- override fun prepare() {
32
- collectBankAccountLauncher = createBankAccountLauncher()
32
+ override fun onPresent() {
33
+ val activity = getCurrentActivityOrResolveWithError(promise) ?: return
34
+ collectBankAccountLauncher = createBankAccountLauncher(activity)
33
35
 
34
36
  val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
35
37
  if (stripeSdkModule != null) {
@@ -63,17 +65,17 @@ class CollectBankAccountLauncherFragment : StripeFragment() {
63
65
  FinancialConnections.clearEventListener()
64
66
  }
65
67
 
66
- private fun createBankAccountLauncher(): CollectBankAccountLauncher =
67
- CollectBankAccountLauncher.create(this) { result ->
68
+ private fun createBankAccountLauncher(activity: ComponentActivity): CollectBankAccountLauncher =
69
+ CollectBankAccountLauncher.create(activity, signal) { result ->
68
70
  when (result) {
69
71
  is CollectBankAccountResult.Completed -> {
70
72
  val intent = result.response.intent
71
73
  if (intent.status === StripeIntent.Status.RequiresPaymentMethod) {
72
- promise.resolve(
74
+ promise?.resolve(
73
75
  createError(ErrorType.Canceled.toString(), "Bank account collection was canceled."),
74
76
  )
75
77
  } else if (intent.status === StripeIntent.Status.RequiresConfirmation) {
76
- promise.resolve(
78
+ promise?.resolve(
77
79
  if (isPaymentIntent) {
78
80
  createResult(
79
81
  "paymentIntent",
@@ -87,39 +89,14 @@ class CollectBankAccountLauncherFragment : StripeFragment() {
87
89
  }
88
90
 
89
91
  is CollectBankAccountResult.Cancelled -> {
90
- promise.resolve(
92
+ promise?.resolve(
91
93
  createError(ErrorType.Canceled.toString(), "Bank account collection was canceled."),
92
94
  )
93
95
  }
94
96
 
95
97
  is CollectBankAccountResult.Failed -> {
96
- promise.resolve(createError(ErrorType.Failed.toString(), result.error))
98
+ promise?.resolve(createError(ErrorType.Failed.toString(), result.error))
97
99
  }
98
100
  }
99
- removeFragment(context)
100
101
  }
101
-
102
- companion object {
103
- internal const val TAG = "collect_bank_account_launcher_fragment"
104
-
105
- fun create(
106
- context: ReactApplicationContext,
107
- publishableKey: String,
108
- stripeAccountId: String? = null,
109
- clientSecret: String,
110
- isPaymentIntent: Boolean,
111
- collectParams: CollectBankAccountConfiguration.USBankAccount,
112
- promise: Promise,
113
- ): CollectBankAccountLauncherFragment {
114
- val instance = CollectBankAccountLauncherFragment()
115
- instance.context = context
116
- instance.publishableKey = publishableKey
117
- instance.stripeAccountId = stripeAccountId
118
- instance.clientSecret = clientSecret
119
- instance.isPaymentIntent = isPaymentIntent
120
- instance.collectParams = collectParams
121
- instance.promise = promise
122
- return instance
123
- }
124
- }
125
102
  }
@@ -12,15 +12,14 @@ import com.facebook.react.uimanager.ViewGroupManager
12
12
  import com.facebook.react.uimanager.annotations.ReactProp
13
13
  import com.facebook.react.viewmanagers.EmbeddedPaymentElementViewManagerDelegate
14
14
  import com.facebook.react.viewmanagers.EmbeddedPaymentElementViewManagerInterface
15
- import com.reactnativestripesdk.PaymentSheetFragment.Companion.buildCustomerConfiguration
16
- import com.reactnativestripesdk.PaymentSheetFragment.Companion.buildGooglePayConfig
15
+ import com.reactnativestripesdk.PaymentSheetManager.Companion.buildCustomerConfiguration
16
+ import com.reactnativestripesdk.PaymentSheetManager.Companion.buildGooglePayConfig
17
17
  import com.reactnativestripesdk.addresssheet.AddressSheetView
18
18
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
19
19
  import com.reactnativestripesdk.utils.PaymentSheetException
20
20
  import com.reactnativestripesdk.utils.getBooleanOr
21
21
  import com.reactnativestripesdk.utils.mapToPreferredNetworks
22
22
  import com.reactnativestripesdk.utils.parseCustomPaymentMethods
23
- import com.reactnativestripesdk.utils.toBundleObject
24
23
  import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
25
24
  import com.stripe.android.paymentelement.EmbeddedPaymentElement
26
25
  import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
@@ -113,15 +112,15 @@ class EmbeddedPaymentElementViewManager :
113
112
  var defaultBillingDetails: PaymentSheet.BillingDetails? = null
114
113
  val billingDetailsMap = map.getMap("defaultBillingDetails")
115
114
  if (billingDetailsMap != null) {
116
- val addressBundle = billingDetailsMap.getMap("address")
115
+ val addressMap = billingDetailsMap.getMap("address")
117
116
  val address =
118
117
  PaymentSheet.Address(
119
- addressBundle?.getString("city"),
120
- addressBundle?.getString("country"),
121
- addressBundle?.getString("line1"),
122
- addressBundle?.getString("line2"),
123
- addressBundle?.getString("postalCode"),
124
- addressBundle?.getString("state"),
118
+ addressMap?.getString("city"),
119
+ addressMap?.getString("country"),
120
+ addressMap?.getString("line1"),
121
+ addressMap?.getString("line2"),
122
+ addressMap?.getString("postalCode"),
123
+ addressMap?.getString("state"),
125
124
  )
126
125
  defaultBillingDetails =
127
126
  PaymentSheet.BillingDetails(
@@ -134,20 +133,20 @@ class EmbeddedPaymentElementViewManager :
134
133
 
135
134
  val customerConfiguration =
136
135
  try {
137
- buildCustomerConfiguration(toBundleObject(map))
136
+ buildCustomerConfiguration(map)
138
137
  } catch (error: PaymentSheetException) {
139
138
  throw Error() // TODO handle error
140
139
  }
141
140
 
142
- val googlePayConfig = buildGooglePayConfig(toBundleObject(map.getMap("googlePay")))
143
- val linkConfig = PaymentSheetFragment.buildLinkConfig(toBundleObject(map.getMap("link")))
141
+ val googlePayConfig = buildGooglePayConfig(map.getMap("googlePay"))
142
+ val linkConfig = PaymentSheetManager.buildLinkConfig(map.getMap("link"))
144
143
  val shippingDetails =
145
144
  map.getMap("defaultShippingDetails")?.let {
146
145
  AddressSheetView.buildAddressDetails(it)
147
146
  }
148
147
  val appearance =
149
148
  try {
150
- buildPaymentSheetAppearance(toBundleObject(map.getMap("appearance")), context)
149
+ buildPaymentSheetAppearance(map.getMap("appearance"), context)
151
150
  } catch (error: PaymentSheetAppearanceException) {
152
151
  throw Error() // TODO handle error
153
152
  }
@@ -201,7 +200,7 @@ class EmbeddedPaymentElementViewManager :
201
200
  ?.let { ArrayList(it) },
202
201
  ),
203
202
  ).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
204
- .cardBrandAcceptance(mapToCardBrandAcceptance(toBundleObject(map)))
203
+ .cardBrandAcceptance(mapToCardBrandAcceptance(map))
205
204
  .embeddedViewDisplaysMandateText(
206
205
  if (map.hasKey("embeddedViewDisplaysMandateText") &&
207
206
  map.getType("embeddedViewDisplaysMandateText") == ReadableType.Boolean
@@ -210,15 +209,9 @@ class EmbeddedPaymentElementViewManager :
210
209
  } else {
211
210
  true // default value
212
211
  },
213
- )
214
- // Serialize original ReadableMap because toBundleObject cannot keep arrays of objects
215
- .customPaymentMethods(
212
+ ).customPaymentMethods(
216
213
  parseCustomPaymentMethods(
217
- toBundleObject(map.getMap("customPaymentMethodConfiguration")).apply {
218
- map.getMap("customPaymentMethodConfiguration")?.let { readable ->
219
- putSerializable("customPaymentMethodConfigurationReadableMap", readable.toHashMap())
220
- }
221
- },
214
+ map.getMap("customPaymentMethodConfiguration"),
222
215
  ),
223
216
  )
224
217
 
@@ -244,7 +237,7 @@ class EmbeddedPaymentElementViewManager :
244
237
  }
245
238
 
246
239
  private fun parseIntentConfiguration(map: ReadableMap): PaymentSheet.IntentConfiguration {
247
- val intentConfig = PaymentSheetFragment.buildIntentConfiguration(toBundleObject(map))
240
+ val intentConfig = PaymentSheetManager.buildIntentConfiguration(map)
248
241
  return intentConfig ?: throw IllegalArgumentException("IntentConfiguration is null")
249
242
  }
250
243
 
@@ -60,6 +60,14 @@ class EventEmitterCompat(
60
60
  invoke("onCustomerAdapterSetupIntentClientSecretForCustomerAttachCallback")
61
61
  }
62
62
 
63
+ fun emitOnCustomerSessionProviderSetupIntentClientSecret() {
64
+ invoke("onCustomerSessionProviderSetupIntentClientSecret")
65
+ }
66
+
67
+ fun emitOnCustomerSessionProviderCustomerSessionClientSecret() {
68
+ invoke("onCustomerSessionProviderCustomerSessionClientSecret")
69
+ }
70
+
63
71
  fun emitEmbeddedPaymentElementDidUpdateHeight(value: ReadableMap?) {
64
72
  invoke("embeddedPaymentElementDidUpdateHeight", value)
65
73
  }
@@ -1,19 +1,18 @@
1
1
  package com.reactnativestripesdk
2
2
 
3
- import androidx.fragment.app.FragmentActivity
3
+ import android.annotation.SuppressLint
4
4
  import com.facebook.react.bridge.Arguments
5
- import com.facebook.react.bridge.Promise
6
5
  import com.facebook.react.bridge.ReactApplicationContext
7
6
  import com.facebook.react.bridge.ReadableArray
8
7
  import com.facebook.react.bridge.WritableArray
9
8
  import com.facebook.react.bridge.WritableMap
10
9
  import com.facebook.react.bridge.WritableNativeMap
11
10
  import com.reactnativestripesdk.utils.ErrorType
12
- import com.reactnativestripesdk.utils.StripeFragment
11
+ import com.reactnativestripesdk.utils.StripeUIManager
13
12
  import com.reactnativestripesdk.utils.createError
14
- import com.reactnativestripesdk.utils.createMissingActivityError
15
13
  import com.reactnativestripesdk.utils.mapFromFinancialConnectionsEvent
16
14
  import com.reactnativestripesdk.utils.mapFromToken
15
+ import com.stripe.android.core.reactnative.ReactNativeSdkInternal
17
16
  import com.stripe.android.financialconnections.FinancialConnections
18
17
  import com.stripe.android.financialconnections.FinancialConnectionsSheet
19
18
  import com.stripe.android.financialconnections.FinancialConnectionsSheetForTokenResult
@@ -24,18 +23,28 @@ import com.stripe.android.financialconnections.model.FinancialConnectionsAccount
24
23
  import com.stripe.android.financialconnections.model.FinancialConnectionsAccountList
25
24
  import com.stripe.android.financialconnections.model.FinancialConnectionsSession
26
25
 
27
- class FinancialConnectionsSheetFragment : StripeFragment() {
26
+ @OptIn(ReactNativeSdkInternal::class)
27
+ class FinancialConnectionsSheetManager(
28
+ context: ReactApplicationContext,
29
+ clientSecret: String,
30
+ private var mode: Mode,
31
+ publishableKey: String,
32
+ stripeAccountId: String?,
33
+ ) : StripeUIManager(context) {
28
34
  enum class Mode {
29
35
  ForToken,
30
36
  ForSession,
31
37
  }
32
38
 
33
- private lateinit var promise: Promise
34
- private lateinit var context: ReactApplicationContext
35
- private lateinit var configuration: FinancialConnectionsSheet.Configuration
36
- private lateinit var mode: Mode
39
+ private var configuration =
40
+ FinancialConnectionsSheet.Configuration(
41
+ financialConnectionsSessionClientSecret = clientSecret,
42
+ publishableKey = publishableKey,
43
+ stripeAccountId = stripeAccountId,
44
+ )
37
45
 
38
- override fun prepare() {
46
+ override fun onPresent() {
47
+ val activity = getCurrentActivityOrResolveWithError(promise) ?: return
39
48
  val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
40
49
  FinancialConnections.setEventListener { event ->
41
50
  val params = mapFromFinancialConnectionsEvent(event)
@@ -44,16 +53,19 @@ class FinancialConnectionsSheetFragment : StripeFragment() {
44
53
 
45
54
  when (mode) {
46
55
  Mode.ForToken -> {
56
+ @SuppressLint("RestrictedApi")
47
57
  FinancialConnectionsSheet
48
58
  .createForBankAccountToken(
49
- this,
59
+ activity,
60
+ signal,
50
61
  ::onFinancialConnectionsSheetForTokenResult,
51
62
  ).present(configuration = configuration)
52
63
  }
53
64
 
54
65
  Mode.ForSession -> {
66
+ @SuppressLint("RestrictedApi")
55
67
  FinancialConnectionsSheet
56
- .create(this, ::onFinancialConnectionsSheetForDataResult)
68
+ .create(activity, signal, ::onFinancialConnectionsSheetForDataResult)
57
69
  .present(configuration = configuration)
58
70
  }
59
71
  }
@@ -61,7 +73,6 @@ class FinancialConnectionsSheetFragment : StripeFragment() {
61
73
 
62
74
  override fun onDestroy() {
63
75
  super.onDestroy()
64
-
65
76
  // Remove any event listener that might be set
66
77
  FinancialConnections.clearEventListener()
67
78
  }
@@ -69,20 +80,15 @@ class FinancialConnectionsSheetFragment : StripeFragment() {
69
80
  private fun onFinancialConnectionsSheetForTokenResult(result: FinancialConnectionsSheetForTokenResult) {
70
81
  when (result) {
71
82
  is FinancialConnectionsSheetForTokenResult.Canceled -> {
72
- promise.resolve(createError(ErrorType.Canceled.toString(), "The flow has been canceled"))
83
+ promise?.resolve(createError(ErrorType.Canceled.toString(), "The flow has been canceled"))
73
84
  }
74
85
 
75
86
  is FinancialConnectionsSheetForTokenResult.Failed -> {
76
- promise.resolve(createError(ErrorType.Failed.toString(), result.error))
87
+ promise?.resolve(createError(ErrorType.Failed.toString(), result.error))
77
88
  }
78
89
 
79
90
  is FinancialConnectionsSheetForTokenResult.Completed -> {
80
- promise.resolve(createTokenResult(result))
81
- (context.currentActivity as? FragmentActivity)
82
- ?.supportFragmentManager
83
- ?.beginTransaction()
84
- ?.remove(this)
85
- ?.commitAllowingStateLoss()
91
+ promise?.resolve(createTokenResult(result))
86
92
  }
87
93
  }
88
94
  }
@@ -90,77 +96,24 @@ class FinancialConnectionsSheetFragment : StripeFragment() {
90
96
  private fun onFinancialConnectionsSheetForDataResult(result: FinancialConnectionsSheetResult) {
91
97
  when (result) {
92
98
  is FinancialConnectionsSheetResult.Canceled -> {
93
- promise.resolve(createError(ErrorType.Canceled.toString(), "The flow has been canceled"))
99
+ promise?.resolve(createError(ErrorType.Canceled.toString(), "The flow has been canceled"))
94
100
  }
95
101
 
96
102
  is FinancialConnectionsSheetResult.Failed -> {
97
- promise.resolve(createError(ErrorType.Failed.toString(), result.error))
103
+ promise?.resolve(createError(ErrorType.Failed.toString(), result.error))
98
104
  }
99
105
 
100
106
  is FinancialConnectionsSheetResult.Completed -> {
101
- promise.resolve(
107
+ promise?.resolve(
102
108
  WritableNativeMap().also {
103
109
  it.putMap("session", mapFromSession(result.financialConnectionsSession))
104
110
  },
105
111
  )
106
- (context.currentActivity as? FragmentActivity)
107
- ?.supportFragmentManager
108
- ?.beginTransaction()
109
- ?.remove(this)
110
- ?.commitAllowingStateLoss()
111
- }
112
- }
113
- }
114
-
115
- fun presentFinancialConnectionsSheet(
116
- clientSecret: String,
117
- mode: Mode,
118
- publishableKey: String,
119
- stripeAccountId: String?,
120
- promise: Promise,
121
- context: ReactApplicationContext,
122
- ) {
123
- this.promise = promise
124
- this.context = context
125
- this.mode = mode
126
- this.configuration =
127
- FinancialConnectionsSheet.Configuration(
128
- financialConnectionsSessionClientSecret = clientSecret,
129
- publishableKey = publishableKey,
130
- stripeAccountId = stripeAccountId,
131
- )
132
-
133
- (context.currentActivity as? FragmentActivity)?.let {
134
- attemptToCleanupPreviousFragment(it)
135
- commitFragmentAndStartFlow(it)
136
- }
137
- ?: run {
138
- promise.resolve(createMissingActivityError())
139
- return
140
112
  }
141
- }
142
-
143
- private fun attemptToCleanupPreviousFragment(currentActivity: FragmentActivity) {
144
- currentActivity.supportFragmentManager
145
- .beginTransaction()
146
- .remove(this)
147
- .commitAllowingStateLoss()
148
- }
149
-
150
- private fun commitFragmentAndStartFlow(currentActivity: FragmentActivity) {
151
- try {
152
- currentActivity.supportFragmentManager
153
- .beginTransaction()
154
- .add(this, TAG)
155
- .commit()
156
- } catch (error: IllegalStateException) {
157
- promise.resolve(createError(ErrorType.Failed.toString(), error.message))
158
113
  }
159
114
  }
160
115
 
161
116
  companion object {
162
- internal const val TAG = "financial_connections_sheet_launch_fragment"
163
-
164
117
  private fun createTokenResult(result: FinancialConnectionsSheetForTokenResult.Completed): WritableMap =
165
118
  WritableNativeMap().also {
166
119
  it.putMap("session", mapFromSession(result.financialConnectionsSession))
@@ -0,0 +1,107 @@
1
+ package com.reactnativestripesdk
2
+
3
+ import android.annotation.SuppressLint
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReadableMap
6
+ import com.facebook.react.bridge.WritableMap
7
+ import com.reactnativestripesdk.utils.GooglePayErrorType
8
+ import com.reactnativestripesdk.utils.StripeUIManager
9
+ import com.reactnativestripesdk.utils.createError
10
+ import com.reactnativestripesdk.utils.getBooleanOr
11
+ import com.reactnativestripesdk.utils.getIntOrNull
12
+ import com.stripe.android.core.reactnative.ReactNativeSdkInternal
13
+ import com.stripe.android.googlepaylauncher.GooglePayEnvironment
14
+ import com.stripe.android.googlepaylauncher.GooglePayLauncher
15
+
16
+ @OptIn(ReactNativeSdkInternal::class)
17
+ class GooglePayLauncherManager(
18
+ context: ReactApplicationContext,
19
+ private val clientSecret: String,
20
+ private val mode: Mode,
21
+ googlePayParams: ReadableMap,
22
+ private val callback: (GooglePayLauncher.Result?, error: WritableMap?) -> Unit,
23
+ ) : StripeUIManager(context) {
24
+ enum class Mode {
25
+ ForSetup,
26
+ ForPayment,
27
+ }
28
+
29
+ private var launcher: GooglePayLauncher? = null
30
+ private var configuration =
31
+ GooglePayLauncher.Config(
32
+ environment =
33
+ if (googlePayParams.getBoolean("testEnv")) {
34
+ GooglePayEnvironment.Test
35
+ } else {
36
+ GooglePayEnvironment.Production
37
+ },
38
+ merchantCountryCode = googlePayParams.getString("merchantCountryCode").orEmpty(),
39
+ merchantName = googlePayParams.getString("merchantName").orEmpty(),
40
+ isEmailRequired = googlePayParams.getBooleanOr("isEmailRequired", false),
41
+ billingAddressConfig =
42
+ buildBillingAddressParameters(googlePayParams.getMap("billingAddressConfig")),
43
+ existingPaymentMethodRequired =
44
+ googlePayParams.getBooleanOr("existingPaymentMethodRequired", false),
45
+ allowCreditCards = googlePayParams.getBooleanOr("allowCreditCards", true),
46
+ )
47
+ private var currencyCode = googlePayParams.getString("currencyCode") ?: "USD"
48
+ private var amount = googlePayParams.getIntOrNull("amount")
49
+ private var label = googlePayParams.getString("label")
50
+
51
+ override fun onPresent() {
52
+ val activity = getCurrentActivityOrResolveWithError(promise) ?: return
53
+ @SuppressLint("RestrictedApi")
54
+ launcher =
55
+ GooglePayLauncher(
56
+ activity = activity,
57
+ signal = signal,
58
+ config = configuration,
59
+ readyCallback = ::onGooglePayReady,
60
+ resultCallback = ::onGooglePayResult,
61
+ )
62
+ }
63
+
64
+ private fun onGooglePayReady(isReady: Boolean) {
65
+ if (isReady) {
66
+ when (mode) {
67
+ Mode.ForSetup -> {
68
+ launcher?.presentForSetupIntent(clientSecret, currencyCode, amount?.toLong(), label)
69
+ }
70
+ Mode.ForPayment -> {
71
+ launcher?.presentForPaymentIntent(clientSecret, label)
72
+ }
73
+ }
74
+ } else {
75
+ callback(
76
+ null,
77
+ createError(
78
+ GooglePayErrorType.Failed.toString(),
79
+ "Google Pay is not available on this device. You can use isPlatformPaySupported to preemptively check for Google Pay support.",
80
+ ),
81
+ )
82
+ }
83
+ }
84
+
85
+ private fun onGooglePayResult(result: GooglePayLauncher.Result) {
86
+ callback(result, null)
87
+ }
88
+
89
+ companion object {
90
+ private fun buildBillingAddressParameters(params: ReadableMap?): GooglePayLauncher.BillingAddressConfig {
91
+ val isRequired = params?.getBooleanOr("isRequired", false)
92
+ val isPhoneNumberRequired = params?.getBooleanOr("isPhoneNumberRequired", false)
93
+ val format =
94
+ when (params?.getString("format").orEmpty()) {
95
+ "FULL" -> GooglePayLauncher.BillingAddressConfig.Format.Full
96
+ "MIN" -> GooglePayLauncher.BillingAddressConfig.Format.Min
97
+ else -> GooglePayLauncher.BillingAddressConfig.Format.Min
98
+ }
99
+
100
+ return GooglePayLauncher.BillingAddressConfig(
101
+ isRequired = isRequired ?: false,
102
+ format = format,
103
+ isPhoneNumberRequired = isPhoneNumberRequired ?: false,
104
+ )
105
+ }
106
+ }
107
+ }