@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.
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormView.kt +4 -3
- package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +7 -6
- package/android/src/main/java/com/reactnativestripesdk/CardFormView.kt +11 -11
- package/android/src/main/java/com/reactnativestripesdk/{CollectBankAccountLauncherFragment.kt → CollectBankAccountLauncherManager.kt} +21 -44
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +17 -24
- package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/{FinancialConnectionsSheetFragment.kt → FinancialConnectionsSheetManager.kt} +30 -77
- package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherManager.kt +107 -0
- package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherManager.kt +37 -0
- package/android/src/main/java/com/reactnativestripesdk/{PaymentLauncherFragment.kt → PaymentLauncherManager.kt} +39 -77
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +8 -20
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +366 -483
- package/android/src/main/java/com/reactnativestripesdk/{PaymentSheetFragment.kt → PaymentSheetManager.kt} +79 -88
- package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +3 -2
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +213 -210
- package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherManager.kt +78 -0
- package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +48 -35
- package/android/src/main/java/com/reactnativestripesdk/customersheet/{CustomerSheetFragment.kt → CustomerSheetManager.kt} +127 -104
- package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerSessionProvider.kt +35 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +47 -12
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +87 -142
- package/android/src/main/java/com/reactnativestripesdk/utils/StripeUIManager.kt +62 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +12 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +4 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -64
- package/ios/AddressSheet/AddressSheetView.swift +1 -1
- package/ios/ApplePayButtonManager.m +1 -1
- package/ios/ApplePayButtonView.swift +2 -2
- package/ios/FinancialConnections.swift +2 -2
- package/ios/Mappers.swift +2 -4
- package/ios/NewArch/ApplePayButtonComponentView.mm +1 -1
- package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.m +12 -0
- package/ios/PaymentMethodFactory.swift +0 -17
- package/ios/PushProvisioning/AddToWalletButtonView.swift +1 -1
- package/ios/StripeSdk.mm +14 -0
- package/ios/StripeSdkEmitter.swift +2 -0
- package/ios/StripeSdkImpl+CustomerSheet.swift +71 -20
- package/ios/StripeSdkImpl+PaymentSheet.swift +29 -13
- package/ios/StripeSdkImpl.swift +9 -7
- package/lib/commonjs/components/AddToWalletButton.js +1 -1
- package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
- package/lib/commonjs/components/AddressSheet.js +1 -1
- package/lib/commonjs/components/AddressSheet.js.map +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
- package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
- package/lib/commonjs/components/CardField.js +1 -1
- package/lib/commonjs/components/CardField.js.map +1 -1
- package/lib/commonjs/components/CardForm.js +1 -1
- package/lib/commonjs/components/CardForm.js.map +1 -1
- package/lib/commonjs/components/CustomerSheet.js +1 -1
- package/lib/commonjs/components/CustomerSheet.js.map +1 -1
- package/lib/commonjs/components/PlatformPayButton.js +1 -1
- package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
- package/lib/commonjs/components/StripeContainer.js +1 -1
- package/lib/commonjs/components/StripeContainer.js.map +1 -1
- package/lib/commonjs/events.js.map +1 -1
- package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
- package/lib/commonjs/specs/NativeApplePayButton.js.map +1 -1
- package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/PaymentIntent.js.map +1 -1
- package/lib/commonjs/types/PaymentSheet.js.map +1 -1
- package/lib/module/components/AddToWalletButton.js +1 -1
- package/lib/module/components/AddToWalletButton.js.map +1 -1
- package/lib/module/components/AddressSheet.js +1 -1
- package/lib/module/components/AddressSheet.js.map +1 -1
- package/lib/module/components/AuBECSDebitForm.js +1 -1
- package/lib/module/components/AuBECSDebitForm.js.map +1 -1
- package/lib/module/components/CardField.js +1 -1
- package/lib/module/components/CardField.js.map +1 -1
- package/lib/module/components/CardForm.js +1 -1
- package/lib/module/components/CardForm.js.map +1 -1
- package/lib/module/components/CustomerSheet.js +1 -1
- package/lib/module/components/CustomerSheet.js.map +1 -1
- package/lib/module/components/PlatformPayButton.js +1 -1
- package/lib/module/components/PlatformPayButton.js.map +1 -1
- package/lib/module/components/StripeContainer.js +1 -1
- package/lib/module/components/StripeContainer.js.map +1 -1
- package/lib/module/events.js.map +1 -1
- package/lib/module/specs/NativeApplePayButton.js +1 -1
- package/lib/module/specs/NativeApplePayButton.js.map +1 -1
- package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/PaymentIntent.js.map +1 -1
- package/lib/module/types/PaymentSheet.js.map +1 -1
- package/lib/typescript/src/components/CustomerSheet.d.ts +1 -1
- package/lib/typescript/src/components/CustomerSheet.d.ts.map +1 -1
- package/lib/typescript/src/events.d.ts +2 -0
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeApplePayButton.d.ts +1 -1
- package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +3 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/ConfirmationToken.d.ts +0 -3
- package/lib/typescript/src/types/ConfirmationToken.d.ts.map +1 -1
- package/lib/typescript/src/types/CustomerSheet.d.ts +70 -12
- package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +2 -4
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentIntent.d.ts +1 -9
- package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentMethod.d.ts +2 -8
- package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +1 -6
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/CustomerSheet.tsx +65 -9
- package/src/components/PlatformPayButton.tsx +1 -1
- package/src/events.ts +2 -0
- package/src/specs/NativeApplePayButton.ts +1 -1
- package/src/specs/NativeStripeSdkModule.ts +7 -0
- package/src/types/ConfirmationToken.ts +0 -3
- package/src/types/CustomerSheet.ts +80 -12
- package/src/types/EmbeddedPaymentElement.tsx +2 -4
- package/src/types/PaymentIntent.ts +0 -10
- package/src/types/PaymentMethod.ts +0 -9
- package/src/types/PaymentSheet.ts +1 -6
- package/stripe-react-native.podspec +1 -1
- package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherFragment.kt +0 -146
- package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +0 -68
- package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherFragment.kt +0 -102
- 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.
|
|
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(
|
|
69
|
+
buildPaymentSheetAppearance(appearanceParams, context)
|
|
63
70
|
} catch (error: PaymentSheetAppearanceException) {
|
|
64
71
|
onError(createError(ErrorType.Failed.toString(), error))
|
|
65
72
|
return
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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(
|
|
135
|
+
internal fun buildAddressDetails(map: ReadableMap): AddressDetails =
|
|
121
136
|
AddressDetails(
|
|
122
|
-
name =
|
|
123
|
-
address = buildAddress(
|
|
124
|
-
phoneNumber =
|
|
125
|
-
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
|
|
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 =
|
|
136
|
-
country =
|
|
137
|
-
line1 =
|
|
138
|
-
line2 =
|
|
139
|
-
state =
|
|
140
|
-
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,12 +10,16 @@ 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
|
+
import com.reactnativestripesdk.ReactNativeCustomerSessionProvider
|
|
16
18
|
import com.reactnativestripesdk.buildPaymentSheetAppearance
|
|
17
19
|
import com.reactnativestripesdk.getBase64FromBitmap
|
|
18
20
|
import com.reactnativestripesdk.getBitmapFromDrawable
|
|
21
|
+
import com.reactnativestripesdk.getIntegerArrayList
|
|
22
|
+
import com.reactnativestripesdk.getStringArrayList
|
|
19
23
|
import com.reactnativestripesdk.mapToAddressCollectionMode
|
|
20
24
|
import com.reactnativestripesdk.mapToCardBrandAcceptance
|
|
21
25
|
import com.reactnativestripesdk.mapToCollectionMode
|
|
@@ -23,11 +27,13 @@ import com.reactnativestripesdk.utils.CreateTokenErrorType
|
|
|
23
27
|
import com.reactnativestripesdk.utils.ErrorType
|
|
24
28
|
import com.reactnativestripesdk.utils.KeepJsAwakeTask
|
|
25
29
|
import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
|
|
26
|
-
import com.reactnativestripesdk.utils.
|
|
30
|
+
import com.reactnativestripesdk.utils.StripeUIManager
|
|
27
31
|
import com.reactnativestripesdk.utils.createError
|
|
32
|
+
import com.reactnativestripesdk.utils.getBooleanOr
|
|
28
33
|
import com.reactnativestripesdk.utils.mapFromPaymentMethod
|
|
29
34
|
import com.reactnativestripesdk.utils.mapToPreferredNetworks
|
|
30
35
|
import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
|
|
36
|
+
import com.stripe.android.core.reactnative.ReactNativeSdkInternal
|
|
31
37
|
import com.stripe.android.customersheet.CustomerAdapter
|
|
32
38
|
import com.stripe.android.customersheet.CustomerEphemeralKey
|
|
33
39
|
import com.stripe.android.customersheet.CustomerSheet
|
|
@@ -39,66 +45,32 @@ import kotlinx.coroutines.CoroutineScope
|
|
|
39
45
|
import kotlinx.coroutines.Dispatchers
|
|
40
46
|
import kotlinx.coroutines.launch
|
|
41
47
|
|
|
42
|
-
@OptIn(ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class)
|
|
43
|
-
class
|
|
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) {
|
|
44
55
|
private var customerSheet: CustomerSheet? = null
|
|
45
56
|
internal var customerAdapter: ReactNativeCustomerAdapter? = null
|
|
46
|
-
internal var
|
|
47
|
-
internal var initPromise: Promise? = null
|
|
57
|
+
internal var customerSessionProvider: ReactNativeCustomerSessionProvider? = null
|
|
48
58
|
private var presentPromise: Promise? = null
|
|
49
59
|
private var keepJsAwake: KeepJsAwakeTask? = null
|
|
50
60
|
|
|
51
|
-
override fun
|
|
52
|
-
val
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"No context found during CustomerSheet.initialize. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
|
|
58
|
-
)
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
val initPromise =
|
|
62
|
-
initPromise
|
|
63
|
-
?: run {
|
|
64
|
-
Log.e(
|
|
65
|
-
"StripeReactNative",
|
|
66
|
-
"No promise found for CustomerSheet.initialize. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
|
|
67
|
-
)
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
val headerTextForSelectionScreen = arguments?.getString("headerTextForSelectionScreen")
|
|
72
|
-
val merchantDisplayName = arguments?.getString("merchantDisplayName")
|
|
73
|
-
val googlePayEnabled = arguments?.getBoolean("googlePayEnabled") ?: false
|
|
74
|
-
val billingDetailsBundle = arguments?.getBundle("defaultBillingDetails")
|
|
75
|
-
val billingConfigParams = arguments?.getBundle("billingDetailsCollectionConfiguration")
|
|
76
|
-
val setupIntentClientSecret = arguments?.getString("setupIntentClientSecret")
|
|
77
|
-
val customerId = arguments?.getString("customerId")
|
|
78
|
-
val customerEphemeralKeySecret = arguments?.getString("customerEphemeralKeySecret")
|
|
79
|
-
val customerAdapterOverrideParams = arguments?.getBundle("customerAdapter")
|
|
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")
|
|
80
67
|
val allowsRemovalOfLastSavedPaymentMethod =
|
|
81
|
-
arguments
|
|
82
|
-
val paymentMethodOrder = arguments
|
|
83
|
-
if (customerId == null) {
|
|
84
|
-
initPromise.resolve(
|
|
85
|
-
createError(ErrorType.Failed.toString(), "You must provide a value for `customerId`"),
|
|
86
|
-
)
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
if (customerEphemeralKeySecret == null) {
|
|
90
|
-
initPromise.resolve(
|
|
91
|
-
createError(
|
|
92
|
-
ErrorType.Failed.toString(),
|
|
93
|
-
"You must provide a value for `customerEphemeralKeySecret`",
|
|
94
|
-
),
|
|
95
|
-
)
|
|
96
|
-
return
|
|
97
|
-
}
|
|
68
|
+
arguments.getBooleanOr("allowsRemovalOfLastSavedPaymentMethod", true)
|
|
69
|
+
val paymentMethodOrder = arguments.getStringArrayList("paymentMethodOrder")
|
|
98
70
|
|
|
99
71
|
val appearance =
|
|
100
72
|
try {
|
|
101
|
-
buildPaymentSheetAppearance(arguments
|
|
73
|
+
buildPaymentSheetAppearance(arguments.getMap("appearance"), context)
|
|
102
74
|
} catch (error: PaymentSheetAppearanceException) {
|
|
103
75
|
initPromise.resolve(createError(ErrorType.Failed.toString(), error))
|
|
104
76
|
return
|
|
@@ -111,13 +83,13 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
111
83
|
.googlePayEnabled(googlePayEnabled)
|
|
112
84
|
.headerTextForSelectionScreen(headerTextForSelectionScreen)
|
|
113
85
|
.preferredNetworks(
|
|
114
|
-
mapToPreferredNetworks(arguments
|
|
86
|
+
mapToPreferredNetworks(arguments.getIntegerArrayList("preferredNetworks")),
|
|
115
87
|
).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
|
|
116
88
|
.cardBrandAcceptance(mapToCardBrandAcceptance(arguments))
|
|
117
89
|
|
|
118
90
|
paymentMethodOrder?.let { configuration.paymentMethodOrder(it) }
|
|
119
|
-
|
|
120
|
-
configuration.defaultBillingDetails(createDefaultBillingDetails(
|
|
91
|
+
billingDetailsMap?.let {
|
|
92
|
+
configuration.defaultBillingDetails(createDefaultBillingDetails(billingDetailsMap))
|
|
121
93
|
}
|
|
122
94
|
billingConfigParams?.let {
|
|
123
95
|
configuration.billingDetailsCollectionConfiguration(
|
|
@@ -125,21 +97,63 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
125
97
|
)
|
|
126
98
|
}
|
|
127
99
|
|
|
128
|
-
val
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
CustomerSheet.create(
|
|
139
|
-
fragment = this,
|
|
140
|
-
customerAdapter = customerAdapter,
|
|
141
|
-
callback = ::handleResult,
|
|
100
|
+
val activity = getCurrentActivityOrResolveWithError(initPromise) ?: return
|
|
101
|
+
|
|
102
|
+
val customerEphemeralKeySecret = arguments.getString("customerEphemeralKeySecret")
|
|
103
|
+
val intentConfiguration = createIntentConfiguration(arguments.getMap("intentConfiguration"))
|
|
104
|
+
if (customerEphemeralKeySecret == null && intentConfiguration == null) {
|
|
105
|
+
initPromise.resolve(
|
|
106
|
+
createError(
|
|
107
|
+
ErrorType.Failed.toString(),
|
|
108
|
+
"You must provide either `customerEphemeralKeySecret` or `intentConfiguration`",
|
|
109
|
+
),
|
|
142
110
|
)
|
|
111
|
+
return
|
|
112
|
+
} else if (customerEphemeralKeySecret == null) {
|
|
113
|
+
val customerSessionProvider =
|
|
114
|
+
ReactNativeCustomerSessionProvider(
|
|
115
|
+
context = context,
|
|
116
|
+
intentConfiguration = intentConfiguration!!,
|
|
117
|
+
).also { this.customerSessionProvider = it }
|
|
118
|
+
|
|
119
|
+
customerSheet =
|
|
120
|
+
CustomerSheet.create(
|
|
121
|
+
activity = activity,
|
|
122
|
+
customerSessionProvider = customerSessionProvider,
|
|
123
|
+
callback = ::handleResult,
|
|
124
|
+
)
|
|
125
|
+
} else if (intentConfiguration == null) {
|
|
126
|
+
val customerId = arguments.getString("customerId")
|
|
127
|
+
if (customerId == null) {
|
|
128
|
+
initPromise.resolve(
|
|
129
|
+
createError(ErrorType.Failed.toString(), "When using `customerEphemeralKeySecret` you must provide a value for `customerId`"),
|
|
130
|
+
)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
val setupIntentClientSecret = arguments.getString("setupIntentClientSecret")
|
|
134
|
+
val customerAdapter =
|
|
135
|
+
createCustomerAdapter(
|
|
136
|
+
context,
|
|
137
|
+
customerId,
|
|
138
|
+
customerEphemeralKeySecret,
|
|
139
|
+
setupIntentClientSecret,
|
|
140
|
+
customerAdapterOverrides,
|
|
141
|
+
).also { this.customerAdapter = it }
|
|
142
|
+
|
|
143
|
+
customerSheet =
|
|
144
|
+
CustomerSheet.create(
|
|
145
|
+
activity = activity,
|
|
146
|
+
customerAdapter = customerAdapter,
|
|
147
|
+
callback = ::handleResult,
|
|
148
|
+
)
|
|
149
|
+
} else {
|
|
150
|
+
initPromise.resolve(
|
|
151
|
+
createError(
|
|
152
|
+
ErrorType.Failed.toString(),
|
|
153
|
+
"You must provide either `customerEphemeralKeySecret` or `intentConfiguration`, but not both",
|
|
154
|
+
),
|
|
155
|
+
)
|
|
156
|
+
}
|
|
143
157
|
|
|
144
158
|
customerSheet?.configure(configuration.build())
|
|
145
159
|
|
|
@@ -168,16 +182,15 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
168
182
|
resolvePresentPromise(promiseResult)
|
|
169
183
|
}
|
|
170
184
|
|
|
171
|
-
fun
|
|
172
|
-
|
|
173
|
-
promise: Promise,
|
|
174
|
-
) {
|
|
175
|
-
keepJsAwake = context?.let { KeepJsAwakeTask(it).apply { start() } }
|
|
185
|
+
override fun onPresent() {
|
|
186
|
+
keepJsAwake = context.let { KeepJsAwakeTask(it).apply { start() } }
|
|
176
187
|
presentPromise = promise
|
|
188
|
+
val timeout = timeout
|
|
177
189
|
if (timeout != null) {
|
|
178
190
|
presentWithTimeout(timeout)
|
|
191
|
+
} else {
|
|
192
|
+
customerSheet?.present() ?: run { resolvePresentPromise(createMissingInitError()) }
|
|
179
193
|
}
|
|
180
|
-
customerSheet?.present() ?: run { resolvePresentPromise(createMissingInitError()) }
|
|
181
194
|
}
|
|
182
195
|
|
|
183
196
|
private fun presentWithTimeout(timeout: Long) {
|
|
@@ -207,7 +220,7 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
207
220
|
|
|
208
221
|
override fun onActivityDestroyed(activity: Activity) {
|
|
209
222
|
activities = mutableListOf()
|
|
210
|
-
context
|
|
223
|
+
context.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
|
|
211
224
|
}
|
|
212
225
|
}
|
|
213
226
|
|
|
@@ -223,7 +236,7 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
223
236
|
)
|
|
224
237
|
|
|
225
238
|
context
|
|
226
|
-
|
|
239
|
+
.currentActivity
|
|
227
240
|
?.application
|
|
228
241
|
?.registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
|
|
229
242
|
|
|
@@ -279,37 +292,35 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
279
292
|
}
|
|
280
293
|
|
|
281
294
|
companion object {
|
|
282
|
-
internal const val TAG = "customer_sheet_launch_fragment"
|
|
283
|
-
|
|
284
295
|
internal fun createMissingInitError(): WritableMap =
|
|
285
296
|
createError(ErrorType.Failed.toString(), "No customer sheet has been initialized yet.")
|
|
286
297
|
|
|
287
|
-
internal fun createDefaultBillingDetails(
|
|
288
|
-
val
|
|
298
|
+
internal fun createDefaultBillingDetails(map: ReadableMap): PaymentSheet.BillingDetails {
|
|
299
|
+
val addressMap = map.getMap("address")
|
|
289
300
|
val address =
|
|
290
301
|
PaymentSheet.Address(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
302
|
+
addressMap?.getString("city"),
|
|
303
|
+
addressMap?.getString("country"),
|
|
304
|
+
addressMap?.getString("line1"),
|
|
305
|
+
addressMap?.getString("line2"),
|
|
306
|
+
addressMap?.getString("postalCode"),
|
|
307
|
+
addressMap?.getString("state"),
|
|
297
308
|
)
|
|
298
309
|
return PaymentSheet.BillingDetails(
|
|
299
310
|
address,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
311
|
+
map.getString("email"),
|
|
312
|
+
map.getString("name"),
|
|
313
|
+
map.getString("phone"),
|
|
303
314
|
)
|
|
304
315
|
}
|
|
305
316
|
|
|
306
|
-
internal fun createBillingDetailsCollectionConfiguration(
|
|
317
|
+
internal fun createBillingDetailsCollectionConfiguration(map: ReadableMap): PaymentSheet.BillingDetailsCollectionConfiguration =
|
|
307
318
|
PaymentSheet.BillingDetailsCollectionConfiguration(
|
|
308
|
-
name = mapToCollectionMode(
|
|
309
|
-
phone = mapToCollectionMode(
|
|
310
|
-
email = mapToCollectionMode(
|
|
311
|
-
address = mapToAddressCollectionMode(
|
|
312
|
-
attachDefaultsToPaymentMethod =
|
|
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),
|
|
313
324
|
)
|
|
314
325
|
|
|
315
326
|
internal fun createCustomerAdapter(
|
|
@@ -317,7 +328,7 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
317
328
|
customerId: String,
|
|
318
329
|
customerEphemeralKeySecret: String,
|
|
319
330
|
setupIntentClientSecret: String?,
|
|
320
|
-
customerAdapterOverrideParams:
|
|
331
|
+
customerAdapterOverrideParams: ReadableMap?,
|
|
321
332
|
): ReactNativeCustomerAdapter {
|
|
322
333
|
val ephemeralKeyProvider = {
|
|
323
334
|
CustomerAdapter.Result.success(
|
|
@@ -350,18 +361,17 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
350
361
|
context = context,
|
|
351
362
|
adapter = customerAdapter,
|
|
352
363
|
overridesFetchPaymentMethods =
|
|
353
|
-
customerAdapterOverrideParams
|
|
364
|
+
customerAdapterOverrideParams.getBooleanOr("fetchPaymentMethods", false),
|
|
354
365
|
overridesAttachPaymentMethod =
|
|
355
|
-
customerAdapterOverrideParams
|
|
366
|
+
customerAdapterOverrideParams.getBooleanOr("attachPaymentMethod", false),
|
|
356
367
|
overridesDetachPaymentMethod =
|
|
357
|
-
customerAdapterOverrideParams
|
|
368
|
+
customerAdapterOverrideParams.getBooleanOr("detachPaymentMethod", false),
|
|
358
369
|
overridesSetSelectedPaymentOption =
|
|
359
|
-
customerAdapterOverrideParams
|
|
370
|
+
customerAdapterOverrideParams.getBooleanOr("setSelectedPaymentOption", false),
|
|
360
371
|
overridesFetchSelectedPaymentOption =
|
|
361
|
-
customerAdapterOverrideParams
|
|
372
|
+
customerAdapterOverrideParams.getBooleanOr("fetchSelectedPaymentOption", false),
|
|
362
373
|
overridesSetupIntentClientSecretForCustomerAttach =
|
|
363
|
-
customerAdapterOverrideParams
|
|
364
|
-
?: false,
|
|
374
|
+
customerAdapterOverrideParams.getBooleanOr("setupIntentClientSecretForCustomerAttach", false),
|
|
365
375
|
)
|
|
366
376
|
}
|
|
367
377
|
|
|
@@ -389,6 +399,19 @@ class CustomerSheetFragment : StripeFragment() {
|
|
|
389
399
|
return paymentOptionResult
|
|
390
400
|
}
|
|
391
401
|
|
|
402
|
+
internal fun createIntentConfiguration(intentConfigurationBundle: ReadableMap?): CustomerSheet.IntentConfiguration? =
|
|
403
|
+
intentConfigurationBundle?.let { bundle ->
|
|
404
|
+
val onBehalfOf = bundle.getString("onBehalfOf")
|
|
405
|
+
CustomerSheet.IntentConfiguration
|
|
406
|
+
.Builder()
|
|
407
|
+
.paymentMethodTypes(bundle.getStringArrayList("paymentMethodTypes") ?: emptyList())
|
|
408
|
+
.apply {
|
|
409
|
+
if (onBehalfOf != null) {
|
|
410
|
+
this.onBehalfOf(onBehalfOf)
|
|
411
|
+
}
|
|
412
|
+
}.build()
|
|
413
|
+
}
|
|
414
|
+
|
|
392
415
|
private fun buildResult(
|
|
393
416
|
label: String,
|
|
394
417
|
drawable: Drawable,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
package com.reactnativestripesdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.stripe.android.customersheet.CustomerSheet
|
|
5
|
+
import kotlinx.coroutines.CompletableDeferred
|
|
6
|
+
|
|
7
|
+
class ReactNativeCustomerSessionProvider(
|
|
8
|
+
val context: ReactApplicationContext,
|
|
9
|
+
val intentConfiguration: CustomerSheet.IntentConfiguration,
|
|
10
|
+
) : CustomerSheet.CustomerSessionProvider() {
|
|
11
|
+
private val stripeSdkModule = context.getNativeModule(StripeSdkModule::class.java)
|
|
12
|
+
|
|
13
|
+
internal var provideSetupIntentClientSecretCallback: CompletableDeferred<String>? = null
|
|
14
|
+
internal var providesCustomerSessionClientSecretCallback: CompletableDeferred<CustomerSheet.CustomerSessionClientSecret>? = null
|
|
15
|
+
|
|
16
|
+
override suspend fun intentConfiguration(): Result<CustomerSheet.IntentConfiguration> = Result.success(intentConfiguration)
|
|
17
|
+
|
|
18
|
+
override suspend fun provideSetupIntentClientSecret(customerId: String): Result<String> {
|
|
19
|
+
CompletableDeferred<String>().also {
|
|
20
|
+
provideSetupIntentClientSecretCallback = it
|
|
21
|
+
stripeSdkModule?.eventEmitter?.emitOnCustomerSessionProviderSetupIntentClientSecret()
|
|
22
|
+
val resultFromJavascript = it.await()
|
|
23
|
+
return Result.success(resultFromJavascript)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override suspend fun providesCustomerSessionClientSecret(): Result<CustomerSheet.CustomerSessionClientSecret> {
|
|
28
|
+
CompletableDeferred<CustomerSheet.CustomerSessionClientSecret>().also {
|
|
29
|
+
providesCustomerSessionClientSecretCallback = it
|
|
30
|
+
stripeSdkModule?.eventEmitter?.emitOnCustomerSessionProviderCustomerSessionClientSecret()
|
|
31
|
+
val resultFromJavascript = it.await()
|
|
32
|
+
return Result.success(resultFromJavascript)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -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.
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|