@stripe/stripe-react-native 0.66.0 → 0.68.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/build.gradle +3 -3
- package/android/gradle.properties +1 -1
- package/android/proguard-rules.txt +4 -0
- package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorAppearance.kt +229 -0
- package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementView.kt +8 -1
- package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +11 -0
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +0 -22
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +0 -22
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +11 -4
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +12 -25
- package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonView.kt +6 -0
- package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/PushProvisioningProxy.kt +6 -5
- package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/TapAndPayProxy.kt +91 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +11 -6
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerDelegate.java +3 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerInterface.java +1 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +0 -3
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +0 -1
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerDelegate.java +4 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerInterface.java +2 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeOnrampSdkModuleSpec.java +1 -1
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +0 -8
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampErrors.kt +145 -0
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampMappers.kt +10 -1
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +52 -38
- package/android/src/test/java/com/reactnativestripesdk/CurrencySelectorAppearanceTest.kt +137 -0
- package/android/src/test/java/com/reactnativestripesdk/OnrampErrorsTest.kt +168 -0
- package/ios/CurrencySelectorAppearance.swift +120 -0
- package/ios/CurrencySelectorElementManager.m +1 -0
- package/ios/CurrencySelectorElementView.swift +16 -1
- package/ios/Mappers.swift +8 -6
- package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +0 -4
- package/ios/NewArch/StripeCurrencySelectorElementComponentView.mm +1 -0
- package/ios/OnrampErrors.swift +132 -0
- package/ios/StripeOnrampSdk.mm +3 -3
- package/ios/StripeSdk.mm +0 -20
- package/ios/StripeSdkImpl+Checkout.swift +0 -17
- package/ios/StripeSdkImpl+Embedded.swift +0 -24
- package/ios/StripeSdkImpl+PaymentSheet.swift +1 -2
- package/ios/StripeSdkImpl.swift +34 -22
- package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
- package/lib/commonjs/components/CurrencySelectorElement.js +1 -1
- package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -1
- package/lib/commonjs/components/StripeProvider.js +1 -1
- package/lib/commonjs/components/StripeProvider.js.map +1 -1
- package/lib/commonjs/connect/EmbeddedComponent.js +2 -2
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/hooks/useCheckout.js +1 -1
- package/lib/commonjs/hooks/useCheckout.js.map +1 -1
- package/lib/commonjs/hooks/useOnramp.js +1 -1
- package/lib/commonjs/hooks/useOnramp.js.map +1 -1
- package/lib/commonjs/internal/stripeConfig.js +2 -0
- package/lib/commonjs/internal/stripeConfig.js.map +1 -0
- package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
- package/lib/commonjs/specs/NativeAddToWalletButton.js.map +1 -1
- package/lib/commonjs/specs/NativeCurrencySelectorElement.js +1 -1
- package/lib/commonjs/specs/NativeCurrencySelectorElement.js.map +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.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/Errors.js +1 -1
- package/lib/commonjs/types/Errors.js.map +1 -1
- package/lib/commonjs/types/Onramp.js +1 -1
- package/lib/commonjs/types/Onramp.js.map +1 -1
- package/lib/commonjs/types/PushProvisioning.js.map +1 -1
- package/lib/module/components/AddToWalletButton.js.map +1 -1
- package/lib/module/components/CurrencySelectorElement.js +1 -1
- package/lib/module/components/CurrencySelectorElement.js.map +1 -1
- package/lib/module/components/StripeProvider.js +1 -1
- package/lib/module/components/StripeProvider.js.map +1 -1
- package/lib/module/connect/EmbeddedComponent.js +2 -2
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/hooks/useCheckout.js +1 -1
- package/lib/module/hooks/useCheckout.js.map +1 -1
- package/lib/module/hooks/useOnramp.js +1 -1
- package/lib/module/hooks/useOnramp.js.map +1 -1
- package/lib/module/internal/stripeConfig.js +2 -0
- package/lib/module/internal/stripeConfig.js.map +1 -0
- package/lib/module/specs/NativeAddToWalletButton.js +1 -1
- package/lib/module/specs/NativeAddToWalletButton.js.map +1 -1
- package/lib/module/specs/NativeCurrencySelectorElement.js +1 -1
- package/lib/module/specs/NativeCurrencySelectorElement.js.map +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.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/Errors.js +1 -1
- package/lib/module/types/Errors.js.map +1 -1
- package/lib/module/types/Onramp.js +1 -1
- package/lib/module/types/Onramp.js.map +1 -1
- package/lib/module/types/PushProvisioning.js.map +1 -1
- package/lib/typescript/src/components/AddToWalletButton.d.ts +2 -0
- package/lib/typescript/src/components/AddToWalletButton.d.ts.map +1 -1
- package/lib/typescript/src/components/CurrencySelectorElement.d.ts +76 -1
- package/lib/typescript/src/components/CurrencySelectorElement.d.ts.map +1 -1
- package/lib/typescript/src/components/StripeProvider.d.ts.map +1 -1
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts +23 -0
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useCheckout.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useOnramp.d.ts +13 -13
- package/lib/typescript/src/hooks/useOnramp.d.ts.map +1 -1
- package/lib/typescript/src/internal/stripeConfig.d.ts +3 -0
- package/lib/typescript/src/internal/stripeConfig.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts +1 -0
- package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts +4 -0
- package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +0 -1
- package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts +1 -1
- package/lib/typescript/src/specs/NativeOnrampSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +0 -2
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/Checkout.d.ts +0 -8
- package/lib/typescript/src/types/Checkout.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +1 -10
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/Errors.d.ts +0 -5
- package/lib/typescript/src/types/Errors.d.ts.map +1 -1
- package/lib/typescript/src/types/Onramp.d.ts +84 -19
- package/lib/typescript/src/types/Onramp.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentMethod.d.ts +2 -0
- package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
- package/lib/typescript/src/types/PushProvisioning.d.ts +2 -0
- package/lib/typescript/src/types/PushProvisioning.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/AddToWalletButton.tsx +2 -0
- package/src/components/CurrencySelectorElement.tsx +101 -1
- package/src/components/StripeProvider.tsx +2 -0
- package/src/connect/EmbeddedComponent.tsx +47 -10
- package/src/hooks/useCheckout.tsx +0 -9
- package/src/hooks/useOnramp.tsx +101 -18
- package/src/internal/stripeConfig.ts +9 -0
- package/src/specs/NativeAddToWalletButton.ts +1 -0
- package/src/specs/NativeCurrencySelectorElement.ts +5 -0
- package/src/specs/NativeEmbeddedPaymentElement.ts +1 -10
- package/src/specs/NativeOnrampSdkModule.ts +1 -1
- package/src/specs/NativeStripeSdkModule.ts +0 -9
- package/src/types/Checkout.ts +0 -9
- package/src/types/EmbeddedPaymentElement.tsx +4 -27
- package/src/types/Errors.ts +0 -6
- package/src/types/Onramp.ts +93 -19
- package/src/types/PaymentMethod.ts +2 -0
- package/src/types/PushProvisioning.ts +2 -0
- package/stripe-react-native.podspec +3 -3
|
@@ -20,16 +20,15 @@ import com.reactnativestripesdk.utils.ErrorType
|
|
|
20
20
|
import com.reactnativestripesdk.utils.createCanceledError
|
|
21
21
|
import com.reactnativestripesdk.utils.createEmptyResult
|
|
22
22
|
import com.reactnativestripesdk.utils.createError
|
|
23
|
-
import com.reactnativestripesdk.utils.createFailedError
|
|
24
23
|
import com.reactnativestripesdk.utils.createMissingActivityError
|
|
25
24
|
import com.reactnativestripesdk.utils.createMissingInitError
|
|
26
|
-
import com.reactnativestripesdk.utils.createOnrampNotConfiguredError
|
|
27
25
|
import com.reactnativestripesdk.utils.createResult
|
|
28
26
|
import com.reactnativestripesdk.utils.getStringList
|
|
29
27
|
import com.reactnativestripesdk.utils.getValOr
|
|
30
28
|
import com.reactnativestripesdk.utils.mapToPaymentSheetAddress
|
|
31
29
|
import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
|
|
32
30
|
import com.stripe.android.crypto.onramp.OnrampCoordinator
|
|
31
|
+
import com.stripe.android.crypto.onramp.exception.SDKVersion
|
|
33
32
|
import com.stripe.android.crypto.onramp.model.CryptoNetwork
|
|
34
33
|
import com.stripe.android.crypto.onramp.model.KycInfo
|
|
35
34
|
import com.stripe.android.crypto.onramp.model.LinkUserInfo
|
|
@@ -40,7 +39,7 @@ import com.stripe.android.crypto.onramp.model.OnrampCheckoutResult
|
|
|
40
39
|
import com.stripe.android.crypto.onramp.model.OnrampCollectPaymentMethodResult
|
|
41
40
|
import com.stripe.android.crypto.onramp.model.OnrampConfigurationResult
|
|
42
41
|
import com.stripe.android.crypto.onramp.model.OnrampCreateCryptoPaymentTokenResult
|
|
43
|
-
import com.stripe.android.crypto.onramp.model.
|
|
42
|
+
import com.stripe.android.crypto.onramp.model.OnrampUserAttestationResult
|
|
44
43
|
import com.stripe.android.crypto.onramp.model.OnrampHasLinkAccountResult
|
|
45
44
|
import com.stripe.android.crypto.onramp.model.OnrampLogOutResult
|
|
46
45
|
import com.stripe.android.crypto.onramp.model.OnrampRegisterLinkUserResult
|
|
@@ -72,6 +71,7 @@ class OnrampSdkModule(
|
|
|
72
71
|
reactContext: ReactApplicationContext,
|
|
73
72
|
) : NativeOnrampSdkModuleSpec(reactContext) {
|
|
74
73
|
private val eventEmitterCompat = EventEmitterCompat(reactContext)
|
|
74
|
+
private var reactNativeSdkVersion: String? = null
|
|
75
75
|
private lateinit var publishableKey: String
|
|
76
76
|
private var stripeAccountId: String? = null
|
|
77
77
|
|
|
@@ -84,7 +84,7 @@ class OnrampSdkModule(
|
|
|
84
84
|
private var authorizePromise: Promise? = null
|
|
85
85
|
private var checkoutPromise: Promise? = null
|
|
86
86
|
private var verifyKycPromise: Promise? = null
|
|
87
|
-
private var
|
|
87
|
+
private var userAttestationPromise: Promise? = null
|
|
88
88
|
|
|
89
89
|
private var checkoutClientSecretDeferred: CompletableDeferred<String>? = null
|
|
90
90
|
private val rnScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
|
@@ -96,6 +96,10 @@ class OnrampSdkModule(
|
|
|
96
96
|
) {
|
|
97
97
|
// Note: This method depends on `StripeSdkModule#initialise()` being called as well.
|
|
98
98
|
val publishableKey = getValOr(params, "publishableKey", null) as String
|
|
99
|
+
reactNativeSdkVersion =
|
|
100
|
+
params.getMap("appInfo")
|
|
101
|
+
?.getString("version")
|
|
102
|
+
?.takeIf { it.isNotBlank() }
|
|
99
103
|
this.stripeAccountId = getValOr(params, "stripeAccountId", null)
|
|
100
104
|
this.publishableKey = publishableKey
|
|
101
105
|
|
|
@@ -148,9 +152,9 @@ class OnrampSdkModule(
|
|
|
148
152
|
handleOnrampCheckoutResult(result, checkoutPromise!!)
|
|
149
153
|
}.verifyKycCallback { result ->
|
|
150
154
|
handleOnrampKycVerificationResult(result, verifyKycPromise!!)
|
|
151
|
-
}.
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
}.userAttestationCallback { result ->
|
|
156
|
+
userAttestationPromise?.let {
|
|
157
|
+
handleUserAttestationResult(result, it)
|
|
154
158
|
}
|
|
155
159
|
}.onrampSessionClientSecretProvider { sessionId ->
|
|
156
160
|
checkoutClientSecretDeferred = CompletableDeferred()
|
|
@@ -170,7 +174,7 @@ class OnrampSdkModule(
|
|
|
170
174
|
.also { this.onrampCoordinator = it }
|
|
171
175
|
|
|
172
176
|
CoroutineScope(Dispatchers.IO).launch {
|
|
173
|
-
val configuration = mapConfig(config, publishableKey)
|
|
177
|
+
val configuration = mapConfig(config, publishableKey, onrampAdditionalSdkVersions())
|
|
174
178
|
val configureResult = coordinator.configure(configuration)
|
|
175
179
|
|
|
176
180
|
CoroutineScope(Dispatchers.Main).launch {
|
|
@@ -179,7 +183,7 @@ class OnrampSdkModule(
|
|
|
179
183
|
createOnrampPresenter(promise)
|
|
180
184
|
}
|
|
181
185
|
is OnrampConfigurationResult.Failed -> {
|
|
182
|
-
promise.resolve(
|
|
186
|
+
promise.resolve(createOnrampFailedError(configureResult.error))
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
189
|
}
|
|
@@ -206,7 +210,7 @@ class OnrampSdkModule(
|
|
|
206
210
|
onrampPresenter = onrampCoordinator!!.createPresenter(activity)
|
|
207
211
|
promise.resolveVoid()
|
|
208
212
|
} catch (e: Exception) {
|
|
209
|
-
promise.resolve(
|
|
213
|
+
promise.resolve(createOnrampFailedError(e))
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
216
|
|
|
@@ -226,7 +230,7 @@ class OnrampSdkModule(
|
|
|
226
230
|
promise.resolveBoolean("hasLinkAccount", result.hasLinkAccount)
|
|
227
231
|
}
|
|
228
232
|
is OnrampHasLinkAccountResult.Failed -> {
|
|
229
|
-
promise.resolve(
|
|
233
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
230
234
|
}
|
|
231
235
|
}
|
|
232
236
|
}
|
|
@@ -257,7 +261,7 @@ class OnrampSdkModule(
|
|
|
257
261
|
promise.resolveString("customerId", result.customerId)
|
|
258
262
|
}
|
|
259
263
|
is OnrampRegisterLinkUserResult.Failed -> {
|
|
260
|
-
promise.resolve(
|
|
264
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
261
265
|
}
|
|
262
266
|
}
|
|
263
267
|
}
|
|
@@ -286,7 +290,7 @@ class OnrampSdkModule(
|
|
|
286
290
|
promise.resolveVoid()
|
|
287
291
|
}
|
|
288
292
|
is OnrampRegisterWalletAddressResult.Failed -> {
|
|
289
|
-
promise.resolve(
|
|
293
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
290
294
|
}
|
|
291
295
|
}
|
|
292
296
|
}
|
|
@@ -350,7 +354,7 @@ class OnrampSdkModule(
|
|
|
350
354
|
promise.resolveVoid()
|
|
351
355
|
}
|
|
352
356
|
is OnrampAttachKycInfoResult.Failed -> {
|
|
353
|
-
promise.resolve(
|
|
357
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
354
358
|
}
|
|
355
359
|
}
|
|
356
360
|
}
|
|
@@ -370,7 +374,7 @@ class OnrampSdkModule(
|
|
|
370
374
|
promise.resolve(mapFromComplianceIdentifierRequirements(result.requirements))
|
|
371
375
|
}
|
|
372
376
|
is OnrampRetrieveMissingIdentifiersResult.Failed -> {
|
|
373
|
-
promise.resolve(
|
|
377
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
374
378
|
}
|
|
375
379
|
}
|
|
376
380
|
}
|
|
@@ -407,22 +411,22 @@ class OnrampSdkModule(
|
|
|
407
411
|
promise.resolve(mapFromSubmitIdentifiersResult(result.result))
|
|
408
412
|
}
|
|
409
413
|
is OnrampSubmitIdentifiersResult.Failed -> {
|
|
410
|
-
promise.resolve(
|
|
414
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
411
415
|
}
|
|
412
416
|
}
|
|
413
417
|
}
|
|
414
418
|
}
|
|
415
419
|
|
|
416
420
|
@ReactMethod
|
|
417
|
-
override fun
|
|
421
|
+
override fun presentUserAttestation(promise: Promise) {
|
|
418
422
|
val presenter =
|
|
419
423
|
onrampPresenter ?: run {
|
|
420
424
|
promise.resolve(createOnrampNotConfiguredError())
|
|
421
425
|
return
|
|
422
426
|
}
|
|
423
427
|
|
|
424
|
-
|
|
425
|
-
presenter.
|
|
428
|
+
userAttestationPromise = promise
|
|
429
|
+
presenter.presentUserAttestation()
|
|
426
430
|
}
|
|
427
431
|
|
|
428
432
|
@ReactMethod
|
|
@@ -441,7 +445,7 @@ class OnrampSdkModule(
|
|
|
441
445
|
promise.resolveVoid()
|
|
442
446
|
}
|
|
443
447
|
is OnrampUpdatePhoneNumberResult.Failed -> {
|
|
444
|
-
promise.resolve(
|
|
448
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
445
449
|
}
|
|
446
450
|
}
|
|
447
451
|
}
|
|
@@ -499,7 +503,7 @@ class OnrampSdkModule(
|
|
|
499
503
|
platformPayParams.getMap("googlePay")
|
|
500
504
|
?: run {
|
|
501
505
|
promise.resolve(
|
|
502
|
-
|
|
506
|
+
createOnrampFailedError(
|
|
503
507
|
IllegalArgumentException("Missing googlePay params in platformPayParams"),
|
|
504
508
|
),
|
|
505
509
|
)
|
|
@@ -520,7 +524,7 @@ class OnrampSdkModule(
|
|
|
520
524
|
}
|
|
521
525
|
else -> {
|
|
522
526
|
promise.resolve(
|
|
523
|
-
|
|
527
|
+
createOnrampFailedError(
|
|
524
528
|
IllegalArgumentException("Unsupported payment method: $paymentMethod"),
|
|
525
529
|
),
|
|
526
530
|
)
|
|
@@ -648,7 +652,7 @@ class OnrampSdkModule(
|
|
|
648
652
|
|
|
649
653
|
if (paymentDetails == null) {
|
|
650
654
|
promise.resolve(
|
|
651
|
-
|
|
655
|
+
createOnrampFailedError(
|
|
652
656
|
IllegalArgumentException("Unsupported payment method"),
|
|
653
657
|
),
|
|
654
658
|
)
|
|
@@ -749,7 +753,7 @@ class OnrampSdkModule(
|
|
|
749
753
|
promise.resolve(createCanceledError("Identity verification was cancelled"))
|
|
750
754
|
}
|
|
751
755
|
is OnrampVerifyIdentityResult.Failed -> {
|
|
752
|
-
promise.resolve(
|
|
756
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
753
757
|
}
|
|
754
758
|
}
|
|
755
759
|
}
|
|
@@ -773,26 +777,26 @@ class OnrampSdkModule(
|
|
|
773
777
|
promise.resolve(createCanceledError("KYC verification was cancelled"))
|
|
774
778
|
}
|
|
775
779
|
is OnrampVerifyKycInfoResult.Failed -> {
|
|
776
|
-
promise.resolve(
|
|
780
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
777
781
|
}
|
|
778
782
|
}
|
|
779
783
|
}
|
|
780
784
|
|
|
781
|
-
private fun
|
|
782
|
-
result:
|
|
785
|
+
private fun handleUserAttestationResult(
|
|
786
|
+
result: OnrampUserAttestationResult,
|
|
783
787
|
promise: Promise,
|
|
784
788
|
) {
|
|
785
789
|
when (result) {
|
|
786
|
-
is
|
|
790
|
+
is OnrampUserAttestationResult.Confirmed -> {
|
|
787
791
|
promise.resolve(
|
|
788
792
|
WritableNativeMap().apply { putString("status", "Confirmed") },
|
|
789
793
|
)
|
|
790
794
|
}
|
|
791
|
-
is
|
|
792
|
-
promise.resolve(createCanceledError("
|
|
795
|
+
is OnrampUserAttestationResult.Cancelled -> {
|
|
796
|
+
promise.resolve(createCanceledError("User attestation was canceled"))
|
|
793
797
|
}
|
|
794
|
-
is
|
|
795
|
-
promise.resolve(
|
|
798
|
+
is OnrampUserAttestationResult.Failed -> {
|
|
799
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
796
800
|
}
|
|
797
801
|
}
|
|
798
802
|
}
|
|
@@ -843,7 +847,7 @@ class OnrampSdkModule(
|
|
|
843
847
|
}
|
|
844
848
|
|
|
845
849
|
is OnrampCollectPaymentMethodResult.Failed -> {
|
|
846
|
-
promise.resolve(
|
|
850
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
847
851
|
}
|
|
848
852
|
}
|
|
849
853
|
}
|
|
@@ -872,7 +876,7 @@ class OnrampSdkModule(
|
|
|
872
876
|
promise.resolve(createCanceledError("Authorization was cancelled"))
|
|
873
877
|
}
|
|
874
878
|
is OnrampAuthorizeResult.Failed -> {
|
|
875
|
-
promise.resolve(
|
|
879
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
876
880
|
}
|
|
877
881
|
}
|
|
878
882
|
}
|
|
@@ -889,7 +893,7 @@ class OnrampSdkModule(
|
|
|
889
893
|
promise.resolve(createCanceledError("Checkout was cancelled"))
|
|
890
894
|
}
|
|
891
895
|
is OnrampCheckoutResult.Failed -> {
|
|
892
|
-
promise.resolve(
|
|
896
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
893
897
|
}
|
|
894
898
|
}
|
|
895
899
|
}
|
|
@@ -903,7 +907,7 @@ class OnrampSdkModule(
|
|
|
903
907
|
promise.resolveString("cryptoPaymentToken", result.cryptoPaymentToken)
|
|
904
908
|
}
|
|
905
909
|
is OnrampCreateCryptoPaymentTokenResult.Failed -> {
|
|
906
|
-
promise.resolve(
|
|
910
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
907
911
|
}
|
|
908
912
|
}
|
|
909
913
|
}
|
|
@@ -917,7 +921,7 @@ class OnrampSdkModule(
|
|
|
917
921
|
promise.resolveVoid()
|
|
918
922
|
}
|
|
919
923
|
is OnrampLogOutResult.Failed -> {
|
|
920
|
-
promise.resolve(
|
|
924
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
921
925
|
}
|
|
922
926
|
}
|
|
923
927
|
}
|
|
@@ -931,7 +935,7 @@ class OnrampSdkModule(
|
|
|
931
935
|
promise.resolveVoid()
|
|
932
936
|
}
|
|
933
937
|
is OnrampTokenAuthenticationResult.Failed -> {
|
|
934
|
-
promise.resolve(
|
|
938
|
+
promise.resolve(createOnrampFailedError(result.error))
|
|
935
939
|
}
|
|
936
940
|
}
|
|
937
941
|
}
|
|
@@ -953,4 +957,14 @@ class OnrampSdkModule(
|
|
|
953
957
|
) {
|
|
954
958
|
resolve(WritableNativeMap().apply { putBoolean(key, value) })
|
|
955
959
|
}
|
|
960
|
+
|
|
961
|
+
private fun onrampAdditionalSdkVersions(): List<SDKVersion> =
|
|
962
|
+
reactNativeSdkVersion?.let {
|
|
963
|
+
listOf(
|
|
964
|
+
SDKVersion(
|
|
965
|
+
name = "stripe-react-native",
|
|
966
|
+
version = it,
|
|
967
|
+
),
|
|
968
|
+
)
|
|
969
|
+
} ?: emptyList()
|
|
956
970
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
package com.reactnativestripesdk
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import androidx.test.core.app.ApplicationProvider
|
|
5
|
+
import com.reactnativestripesdk.utils.readableMapOf
|
|
6
|
+
import com.stripe.android.checkout.Checkout
|
|
7
|
+
import com.stripe.android.paymentelement.CheckoutSessionPreview
|
|
8
|
+
import org.junit.Assert.assertEquals
|
|
9
|
+
import org.junit.Assert.assertNotNull
|
|
10
|
+
import org.junit.Test
|
|
11
|
+
import org.junit.runner.RunWith
|
|
12
|
+
import org.robolectric.RobolectricTestRunner
|
|
13
|
+
|
|
14
|
+
@OptIn(CheckoutSessionPreview::class)
|
|
15
|
+
@RunWith(RobolectricTestRunner::class)
|
|
16
|
+
class CurrencySelectorAppearanceTest {
|
|
17
|
+
private val context: Context = ApplicationProvider.getApplicationContext()
|
|
18
|
+
|
|
19
|
+
@Test
|
|
20
|
+
fun buildCurrencySelectorAppearance_WithNullMap_ReturnsDefaultAppearance() {
|
|
21
|
+
val appearance = buildCurrencySelectorAppearance(null, context)
|
|
22
|
+
|
|
23
|
+
assertNotNull(appearance)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Test
|
|
27
|
+
fun buildCurrencySelectorAppearance_WithEmptyMap_ReturnsDefaultAppearance() {
|
|
28
|
+
val appearance = buildCurrencySelectorAppearance(readableMapOf(), context)
|
|
29
|
+
|
|
30
|
+
assertNotNull(appearance)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Test
|
|
34
|
+
fun buildCurrencySelectorAppearance_WithColorStrings_Success() {
|
|
35
|
+
val appearance =
|
|
36
|
+
buildCurrencySelectorAppearance(
|
|
37
|
+
readableMapOf(
|
|
38
|
+
"background" to "#111111",
|
|
39
|
+
"selectedBackground" to "#222222",
|
|
40
|
+
"borderColor" to "#333333",
|
|
41
|
+
"textColor" to "#444444",
|
|
42
|
+
"selectedTextColor" to "#555555",
|
|
43
|
+
"textSecondaryColor" to "#666666",
|
|
44
|
+
"dangerColor" to "#777777",
|
|
45
|
+
),
|
|
46
|
+
context,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
assertNotNull(getField(appearance, "background"))
|
|
50
|
+
assertNotNull(getField(appearance, "selectedBackground"))
|
|
51
|
+
assertNotNull(getField(appearance, "borderColor"))
|
|
52
|
+
assertNotNull(getField(appearance, "textColor"))
|
|
53
|
+
assertNotNull(getField(appearance, "selectedTextColor"))
|
|
54
|
+
assertNotNull(getField(appearance, "textSecondaryColor"))
|
|
55
|
+
assertNotNull(getField(appearance, "dangerColor"))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Test
|
|
59
|
+
fun buildCurrencySelectorAppearance_WithThemedColor_UsesLightColor() {
|
|
60
|
+
val appearance =
|
|
61
|
+
buildCurrencySelectorAppearance(
|
|
62
|
+
readableMapOf(
|
|
63
|
+
"textColor" to
|
|
64
|
+
readableMapOf(
|
|
65
|
+
"light" to "#000000",
|
|
66
|
+
"dark" to "#FFFFFF",
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
context,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
assertNotNull(getField(appearance, "textColor"))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@Test
|
|
76
|
+
fun buildCurrencySelectorAppearance_WithInvalidColor_IgnoresValue() {
|
|
77
|
+
val appearance =
|
|
78
|
+
buildCurrencySelectorAppearance(
|
|
79
|
+
readableMapOf(
|
|
80
|
+
"textColor" to "#FF",
|
|
81
|
+
),
|
|
82
|
+
context,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
// Invalid hex is silently ignored (logged as warning), color remains null/default
|
|
86
|
+
val field = appearance.javaClass.getDeclaredField("textColor")
|
|
87
|
+
field.isAccessible = true
|
|
88
|
+
val textColor = field.get(appearance)
|
|
89
|
+
assertEquals(null, textColor)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Test
|
|
93
|
+
fun buildCurrencySelectorAppearance_WithDimensionsAndFont_Success() {
|
|
94
|
+
val appearance =
|
|
95
|
+
buildCurrencySelectorAppearance(
|
|
96
|
+
readableMapOf(
|
|
97
|
+
"cornerRadius" to 12.0,
|
|
98
|
+
"borderWidth" to 2.0,
|
|
99
|
+
"contentVerticalPadding" to 6.0,
|
|
100
|
+
"font" to
|
|
101
|
+
readableMapOf(
|
|
102
|
+
"scale" to 1.2,
|
|
103
|
+
),
|
|
104
|
+
),
|
|
105
|
+
context,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
assertEquals(12f, getField(appearance, "cornerRadiusDp"))
|
|
109
|
+
assertEquals(2f, getField(appearance, "borderWidthDp"))
|
|
110
|
+
assertEquals(6f, getField(appearance, "contentVerticalPaddingDp"))
|
|
111
|
+
assertEquals(1.2f, getField(appearance, "sizeScaleFactor"))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Test
|
|
115
|
+
fun buildCurrencySelectorAppearance_WithLabelContentValues_Success() {
|
|
116
|
+
listOf("automatic", "currencyCode", "amount").forEach { labelContent ->
|
|
117
|
+
val appearance =
|
|
118
|
+
buildCurrencySelectorAppearance(
|
|
119
|
+
readableMapOf(
|
|
120
|
+
"labelContent" to labelContent,
|
|
121
|
+
),
|
|
122
|
+
context,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
assertNotNull(getField(appearance, "labelContent"))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private fun getField(
|
|
130
|
+
appearance: Checkout.CurrencySelectorContentAppearance,
|
|
131
|
+
fieldName: String,
|
|
132
|
+
): Any? {
|
|
133
|
+
val field = appearance.javaClass.getDeclaredField(fieldName)
|
|
134
|
+
field.isAccessible = true
|
|
135
|
+
return field.get(appearance)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
@file:OptIn(ExperimentalCryptoOnramp::class)
|
|
2
|
+
|
|
3
|
+
package com.reactnativestripesdk
|
|
4
|
+
|
|
5
|
+
import com.stripe.android.core.StripeError
|
|
6
|
+
import com.stripe.android.core.exception.APIException
|
|
7
|
+
import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
|
|
8
|
+
import com.stripe.android.crypto.onramp.exception.APIErrorContext
|
|
9
|
+
import com.stripe.android.crypto.onramp.exception.SDKVersion
|
|
10
|
+
import org.junit.Assert.assertEquals
|
|
11
|
+
import org.junit.Assert.assertNotNull
|
|
12
|
+
import org.junit.Assert.assertTrue
|
|
13
|
+
import org.junit.Test
|
|
14
|
+
import org.junit.runner.RunWith
|
|
15
|
+
import org.robolectric.RobolectricTestRunner
|
|
16
|
+
|
|
17
|
+
@RunWith(RobolectricTestRunner::class)
|
|
18
|
+
class OnrampErrorsTest {
|
|
19
|
+
@Test
|
|
20
|
+
fun createOnrampFailedError_withAppAttestationException_preservesOnrampDiagnostics() {
|
|
21
|
+
val error =
|
|
22
|
+
createOnrampException(
|
|
23
|
+
className = "com.stripe.android.crypto.onramp.exception.AppAttestationException",
|
|
24
|
+
reason = "android_package_name_mismatch",
|
|
25
|
+
operation = "configure",
|
|
26
|
+
appPackageName = "com.example.app",
|
|
27
|
+
mode = "test",
|
|
28
|
+
sdkVersions =
|
|
29
|
+
listOf(
|
|
30
|
+
SDKVersion(name = "stripe-android", version = "23.9.1"),
|
|
31
|
+
SDKVersion(name = "stripe-react-native", version = "0.66.0"),
|
|
32
|
+
),
|
|
33
|
+
userMessage = "App attestation failed.",
|
|
34
|
+
apiErrorCode = "link_failed_to_attest_request",
|
|
35
|
+
apiErrorType = "api_error",
|
|
36
|
+
apiErrorMessage = "Attestation request could not be verified.",
|
|
37
|
+
apiUserMessage = "App attestation failed.",
|
|
38
|
+
docUrl = "https://docs.stripe.com/errors/app-attestation",
|
|
39
|
+
requestId = "req_attestation",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
val details = createOnrampFailedError(error).getMap("error")
|
|
43
|
+
|
|
44
|
+
assertNotNull(details)
|
|
45
|
+
assertEquals("Failed", details!!.getString("code"))
|
|
46
|
+
assertEquals("AppAttestationError", details.getString("onrampErrorType"))
|
|
47
|
+
assertEquals("App attestation failed.", details.getString("message"))
|
|
48
|
+
assertEquals("App attestation failed.", details.getString("localizedMessage"))
|
|
49
|
+
assertEquals("App attestation failed.", details.getString("userMessage"))
|
|
50
|
+
assertEquals("link_failed_to_attest_request", details.getString("stripeErrorCode"))
|
|
51
|
+
assertEquals("link_failed_to_attest_request", details.getString("apiErrorCode"))
|
|
52
|
+
assertEquals("api_error", details.getString("type"))
|
|
53
|
+
assertEquals("api_error", details.getString("apiErrorType"))
|
|
54
|
+
assertEquals("android_package_name_mismatch", details.getString("reason"))
|
|
55
|
+
assertEquals("configure", details.getString("operation"))
|
|
56
|
+
assertEquals("com.example.app", details.getString("appPackageName"))
|
|
57
|
+
assertEquals("test", details.getString("mode"))
|
|
58
|
+
val sdkVersions = details.getArray("sdkVersions")
|
|
59
|
+
assertNotNull(sdkVersions)
|
|
60
|
+
val stripeAndroidVersion = sdkVersions!!.getMap(0)
|
|
61
|
+
assertEquals("stripe-android", stripeAndroidVersion!!.getString("name"))
|
|
62
|
+
assertEquals("23.9.1", stripeAndroidVersion.getString("version"))
|
|
63
|
+
val reactNativeVersion = sdkVersions.getMap(1)
|
|
64
|
+
assertEquals("stripe-react-native", reactNativeVersion!!.getString("name"))
|
|
65
|
+
assertEquals("0.66.0", reactNativeVersion.getString("version"))
|
|
66
|
+
assertEquals("req_attestation", details.getString("requestId"))
|
|
67
|
+
assertEquals(
|
|
68
|
+
"Attestation request could not be verified.",
|
|
69
|
+
details.getString("apiErrorMessage"),
|
|
70
|
+
)
|
|
71
|
+
assertEquals("App attestation failed.", details.getString("apiUserMessage"))
|
|
72
|
+
assertEquals(
|
|
73
|
+
"https://docs.stripe.com/errors/app-attestation",
|
|
74
|
+
details.getString("docUrl"),
|
|
75
|
+
)
|
|
76
|
+
assertTrue(details.getString("developerMessage")!!.contains("operation: configure"))
|
|
77
|
+
assertTrue(details.getString("developerMessage")!!.contains("request_id: req_attestation"))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@Test
|
|
81
|
+
fun createOnrampFailedError_withUncategorizedApiError_preservesStripeCodes() {
|
|
82
|
+
val error =
|
|
83
|
+
createOnrampException(
|
|
84
|
+
className = "com.stripe.android.crypto.onramp.exception.UncategorizedApiErrorException",
|
|
85
|
+
reason = "consumer_session_expired",
|
|
86
|
+
operation = "authorize",
|
|
87
|
+
appPackageName = "com.example.app",
|
|
88
|
+
mode = "live",
|
|
89
|
+
sdkVersions = listOf(SDKVersion(name = "stripe-android", version = "23.9.1")),
|
|
90
|
+
userMessage = "Session expired. Please sign in again.",
|
|
91
|
+
apiErrorCode = "consumer_session_expired",
|
|
92
|
+
apiErrorType = "authentication_error",
|
|
93
|
+
apiErrorMessage = "The consumer session has expired.",
|
|
94
|
+
apiUserMessage = "Session expired. Please sign in again.",
|
|
95
|
+
docUrl = "https://docs.stripe.com/error-codes/consumer-session-expired",
|
|
96
|
+
requestId = "req_auth",
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
val details = createOnrampFailedError(error).getMap("error")
|
|
100
|
+
|
|
101
|
+
assertNotNull(details)
|
|
102
|
+
assertEquals("UncategorizedApiError", details!!.getString("onrampErrorType"))
|
|
103
|
+
assertEquals("consumer_session_expired", details.getString("stripeErrorCode"))
|
|
104
|
+
assertEquals("authentication_error", details.getString("type"))
|
|
105
|
+
assertEquals("Session expired. Please sign in again.", details.getString("message"))
|
|
106
|
+
assertEquals("Session expired. Please sign in again.", details.getString("userMessage"))
|
|
107
|
+
assertEquals("authorize", details.getString("operation"))
|
|
108
|
+
assertEquals("req_auth", details.getString("requestId"))
|
|
109
|
+
assertTrue(details.getString("developerMessage")!!.contains("Code: consumer_session_expired"))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private fun createOnrampException(
|
|
113
|
+
className: String,
|
|
114
|
+
reason: String,
|
|
115
|
+
operation: String,
|
|
116
|
+
appPackageName: String,
|
|
117
|
+
mode: String,
|
|
118
|
+
sdkVersions: List<SDKVersion>,
|
|
119
|
+
userMessage: String,
|
|
120
|
+
apiErrorCode: String,
|
|
121
|
+
apiErrorType: String,
|
|
122
|
+
apiErrorMessage: String,
|
|
123
|
+
apiUserMessage: String,
|
|
124
|
+
docUrl: String,
|
|
125
|
+
requestId: String,
|
|
126
|
+
): Exception {
|
|
127
|
+
val stripeError =
|
|
128
|
+
StripeError(
|
|
129
|
+
type = apiErrorType,
|
|
130
|
+
message = apiErrorMessage,
|
|
131
|
+
code = apiErrorCode,
|
|
132
|
+
docUrl = docUrl,
|
|
133
|
+
)
|
|
134
|
+
val cause = APIException(stripeError = stripeError, requestId = requestId)
|
|
135
|
+
val context =
|
|
136
|
+
APIErrorContext(
|
|
137
|
+
reason = reason,
|
|
138
|
+
operation = operation,
|
|
139
|
+
appPackageName = appPackageName,
|
|
140
|
+
mode = mode,
|
|
141
|
+
apiErrorCode = apiErrorCode,
|
|
142
|
+
apiErrorType = apiErrorType,
|
|
143
|
+
apiErrorMessage = apiErrorMessage,
|
|
144
|
+
apiUserMessage = apiUserMessage,
|
|
145
|
+
docUrl = docUrl,
|
|
146
|
+
underlyingError = cause,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
// The exception classes in the `com.stripe.android.crypto.onramp.exception` package
|
|
150
|
+
// don't have public constructors, so we use reflection to create instances for testing.
|
|
151
|
+
val constructor =
|
|
152
|
+
Class
|
|
153
|
+
.forName(className)
|
|
154
|
+
.getDeclaredConstructor(
|
|
155
|
+
APIErrorContext::class.java,
|
|
156
|
+
List::class.java,
|
|
157
|
+
String::class.java,
|
|
158
|
+
).apply {
|
|
159
|
+
isAccessible = true
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return constructor.newInstance(
|
|
163
|
+
context,
|
|
164
|
+
sdkVersions,
|
|
165
|
+
userMessage,
|
|
166
|
+
) as Exception
|
|
167
|
+
}
|
|
168
|
+
}
|