@stripe/stripe-react-native 0.49.0 → 0.50.1
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/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/android/.gradle/8.11.1/checksums/checksums.lock +0 -0
- package/android/.gradle/8.11.1/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.11.1/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.11.1/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.11.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.11.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.11.1/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/src/main/AndroidManifest.xml +10 -0
- package/android/src/main/java/com/reactnativestripesdk/CustomPaymentMethodActivity.kt +81 -0
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +96 -1
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +26 -5
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +0 -17
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +17 -6
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +116 -20
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +22 -0
- package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetFragment.kt +1 -1
- package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +6 -2
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +52 -6
- package/android/src/main/res/values/styles.xml +27 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -0
- package/ios/ApplePayButtonManager.m +4 -0
- package/ios/ApplePayButtonView.swift +11 -4
- package/ios/Mappers.swift +0 -5
- package/ios/NewArch/ApplePayButtonComponentView.mm +6 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.h +1 -1
- package/ios/OldArch/StripeSdkEventEmitterCompat.m +7 -1
- package/ios/PaymentMethodFactory.swift +0 -17
- package/ios/PaymentSheetAppearance.swift +81 -67
- package/ios/StripeSdk.mm +7 -0
- package/ios/StripeSdkEmitter.swift +1 -0
- package/ios/StripeSdkImpl+Embedded.swift +39 -17
- package/ios/StripeSdkImpl+PaymentSheet.swift +114 -1
- package/ios/StripeSdkImpl.swift +38 -9
- 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/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/functions.js +1 -1
- package/lib/commonjs/functions.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 +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/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/functions.js +1 -1
- package/lib/module/functions.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 +1 -1
- package/lib/module/types/PaymentSheet.js.map +1 -1
- package/lib/typescript/src/components/PlatformPayButton.d.ts.map +1 -1
- package/lib/typescript/src/events.d.ts +1 -1
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/functions.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeApplePayButton.d.ts +4 -0
- package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +2 -0
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +2 -0
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentIntent.d.ts +1 -10
- package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentMethod.d.ts +2 -13
- package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +55 -0
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/package.json +1 -1
- package/patches/README.md +55 -0
- package/patches/old-arch-codegen-fix.patch +87 -0
- package/src/components/PlatformPayButton.tsx +12 -4
- package/src/events.ts +2 -1
- package/src/functions.ts +36 -1
- package/src/specs/NativeApplePayButton.ts +5 -0
- package/src/specs/NativeStripeSdkModule.ts +4 -0
- package/src/types/EmbeddedPaymentElement.tsx +33 -0
- package/src/types/PaymentIntent.ts +0 -10
- package/src/types/PaymentMethod.ts +0 -14
- package/src/types/PaymentSheet.ts +59 -0
- package/.env +0 -19
- package/ios/StripeSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/StripeSdk.xcodeproj/project.xcworkspace/xcuserdata/wooj.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/StripeSdk.xcodeproj/xcuserdata/wooj.xcuserdatad/xcschemes/xcschememanagement.plist +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.50.1 - 2025-07-22
|
|
4
|
+
|
|
5
|
+
**Fixes**
|
|
6
|
+
- Fixed embedded payment element color support to accept both single color strings and light/dark color objects for `ThemedColor` properties (separatorColor, selectedColor, unselectedColor, checkmark color, chevron color).
|
|
7
|
+
- Fixed Android crash when providing partial `billingDetailsCollectionConfiguration` objects. Now gracefully handles missing fields like `attachDefaultsToPaymentMethod` by using safe accessor methods with default values.
|
|
8
|
+
- Fixed Android Kotlin compilation errors where nullable `ReadableMap?` was passed to functions expecting non-nullable `ReadableMap`. Added null checks in `EmbeddedPaymentElementViewManager` and `AddToWalletButtonManager`. [#1988](https://github.com/stripe/stripe-react-native/issues/1988)
|
|
9
|
+
|
|
10
|
+
## 0.50.0 - 2025-07-17
|
|
11
|
+
|
|
12
|
+
**Features**
|
|
13
|
+
- Added support for Custom Payment Methods in PaymentSheet and Embedded Payment Element.
|
|
14
|
+
|
|
15
|
+
**Fixes**
|
|
16
|
+
- Removed Sofort from playground pages. Sofort is no longer support by Stripe.
|
|
17
|
+
- **Patches**
|
|
18
|
+
- Fixed codegen error when using React Native 0.74+ with old architecture by converting EventEmitter properties to callback functions in TurboModule interface. [#1977](https://github.com/stripe/stripe-react-native/issues/1977). See `patches/README.md` for more info.
|
|
19
|
+
|
|
3
20
|
## 0.49.0 - 2025-07-02
|
|
4
21
|
|
|
5
22
|
**Features**
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Get started with our [📚 integration guides](https://stripe.com/docs/payments/
|
|
|
23
23
|
|
|
24
24
|
**Native UI**: We provide native screens and elements to securely collect payment details on Android and iOS.
|
|
25
25
|
|
|
26
|
-
**PaymentSheet**: [Learn how to integrate](https://stripe.com/docs/payments/accept-a-payment) PaymentSheet, our new pre-built payments UI for mobile apps. PaymentSheet lets you accept cards, Apple Pay, Google Pay, and much more out of the box and also supports saving & reusing payment methods. PaymentSheet currently accepts the following payment methods: Card, Apple Pay, Google Pay, SEPA Debit, Bancontact, iDEAL, EPS, P24, Afterpay/Clearpay, Klarna, Giropay,
|
|
26
|
+
**PaymentSheet**: [Learn how to integrate](https://stripe.com/docs/payments/accept-a-payment) PaymentSheet, our new pre-built payments UI for mobile apps. PaymentSheet lets you accept cards, Apple Pay, Google Pay, and much more out of the box and also supports saving & reusing payment methods. PaymentSheet currently accepts the following payment methods: Card, Apple Pay, Google Pay, SEPA Debit, Bancontact, iDEAL, EPS, P24, Afterpay/Clearpay, Klarna, Giropay, and ACH.
|
|
27
27
|
|
|
28
28
|
#### Recommended usage
|
|
29
29
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
2
|
package="com.reactnativestripesdk">
|
|
3
|
+
|
|
4
|
+
<application>
|
|
5
|
+
<activity
|
|
6
|
+
android:name=".CustomPaymentMethodActivity"
|
|
7
|
+
android:theme="@style/Theme.StripeReactNative.Transparent"
|
|
8
|
+
android:exported="false"
|
|
9
|
+
android:launchMode="singleTop"
|
|
10
|
+
android:excludeFromRecents="true"
|
|
11
|
+
android:noHistory="true" />
|
|
12
|
+
</application>
|
|
3
13
|
</manifest>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package com.reactnativestripesdk
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle
|
|
4
|
+
import android.view.MotionEvent
|
|
5
|
+
import com.facebook.react.ReactActivity
|
|
6
|
+
import java.lang.ref.WeakReference
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A transparent activity that is launched when the Payment Element requests the
|
|
10
|
+
* `confirmCustomPaymentMethodCallback`.
|
|
11
|
+
*
|
|
12
|
+
* Its only purpose is to bring the app back to the foreground (the Stripe
|
|
13
|
+
* SDK launches its own proxy activity which pauses the host React Native
|
|
14
|
+
* activity). Having a React (transparent) activity on top ensures that React
|
|
15
|
+
* Native can display UI elements such as `Alert` dialogs coming from
|
|
16
|
+
* JavaScript.
|
|
17
|
+
*
|
|
18
|
+
* The activity uses a translucent theme to minimize visibility and is excluded
|
|
19
|
+
* from recents, though it may still be briefly visible to the end-user during
|
|
20
|
+
* certain operations.
|
|
21
|
+
*/
|
|
22
|
+
class CustomPaymentMethodActivity : ReactActivity() {
|
|
23
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
24
|
+
// Disable the transition animation to make it truly invisible
|
|
25
|
+
overridePendingTransition(0, 0)
|
|
26
|
+
super.onCreate(savedInstanceState)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun getMainComponentName(): String? {
|
|
30
|
+
// We don't want to mount another React Native root – returning null is
|
|
31
|
+
// enough to make ReactActivity skip loading a JS component while still
|
|
32
|
+
// hooking into the lifecycle so that ReactContext is aware of this
|
|
33
|
+
// activity.
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
|
38
|
+
// Ensure touch events are properly handled by React Native
|
|
39
|
+
return super.onTouchEvent(event)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
|
|
43
|
+
// Ensure touch events are properly dispatched to React Native
|
|
44
|
+
return super.dispatchTouchEvent(event)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun onResume() {
|
|
48
|
+
super.onResume()
|
|
49
|
+
// Ensure the activity is properly focused for touch events
|
|
50
|
+
currentFocus?.requestFocus()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override fun finish() {
|
|
54
|
+
super.finish()
|
|
55
|
+
// Disable the exit animation as well
|
|
56
|
+
overridePendingTransition(0, 0)
|
|
57
|
+
|
|
58
|
+
// Clear the weak reference when finished
|
|
59
|
+
if (currentActivityRef?.get() == this) {
|
|
60
|
+
currentActivityRef = null
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
companion object {
|
|
65
|
+
@Volatile
|
|
66
|
+
private var currentActivityRef: WeakReference<CustomPaymentMethodActivity>? = null
|
|
67
|
+
|
|
68
|
+
fun finishCurrent() {
|
|
69
|
+
currentActivityRef?.get()?.let { activity ->
|
|
70
|
+
activity.runOnUiThread {
|
|
71
|
+
activity.finish()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override fun onStart() {
|
|
78
|
+
super.onStart()
|
|
79
|
+
currentActivityRef = WeakReference(this)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.reactnativestripesdk
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.util.Log
|
|
4
6
|
import androidx.compose.foundation.layout.Box
|
|
5
7
|
import androidx.compose.foundation.layout.requiredHeight
|
|
6
8
|
import androidx.compose.runtime.Composable
|
|
@@ -9,6 +11,7 @@ import androidx.compose.runtime.getValue
|
|
|
9
11
|
import androidx.compose.runtime.mutableIntStateOf
|
|
10
12
|
import androidx.compose.runtime.mutableStateOf
|
|
11
13
|
import androidx.compose.runtime.remember
|
|
14
|
+
import androidx.compose.runtime.rememberCoroutineScope
|
|
12
15
|
import androidx.compose.runtime.setValue
|
|
13
16
|
import androidx.compose.ui.Modifier
|
|
14
17
|
import androidx.compose.ui.layout.layout
|
|
@@ -19,14 +22,21 @@ import androidx.compose.ui.unit.dp
|
|
|
19
22
|
import com.facebook.react.bridge.Arguments
|
|
20
23
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
21
24
|
import com.reactnativestripesdk.utils.KeepJsAwakeTask
|
|
25
|
+
import com.reactnativestripesdk.utils.mapFromCustomPaymentMethod
|
|
22
26
|
import com.reactnativestripesdk.utils.mapFromPaymentMethod
|
|
27
|
+
import com.stripe.android.model.PaymentMethod
|
|
28
|
+
import com.stripe.android.paymentelement.CustomPaymentMethodResult
|
|
29
|
+
import com.stripe.android.paymentelement.CustomPaymentMethodResultHandler
|
|
23
30
|
import com.stripe.android.paymentelement.EmbeddedPaymentElement
|
|
31
|
+
import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
|
|
24
32
|
import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement
|
|
25
33
|
import com.stripe.android.paymentsheet.CreateIntentResult
|
|
26
34
|
import com.stripe.android.paymentsheet.PaymentSheet
|
|
27
35
|
import kotlinx.coroutines.CompletableDeferred
|
|
28
36
|
import kotlinx.coroutines.channels.Channel
|
|
37
|
+
import kotlinx.coroutines.delay
|
|
29
38
|
import kotlinx.coroutines.flow.consumeAsFlow
|
|
39
|
+
import kotlinx.coroutines.launch
|
|
30
40
|
import toWritableMap
|
|
31
41
|
|
|
32
42
|
enum class RowSelectionBehaviorType {
|
|
@@ -34,6 +44,7 @@ enum class RowSelectionBehaviorType {
|
|
|
34
44
|
ImmediateAction,
|
|
35
45
|
}
|
|
36
46
|
|
|
47
|
+
@OptIn(ExperimentalCustomPaymentMethodsApi::class)
|
|
37
48
|
class EmbeddedPaymentElementView(
|
|
38
49
|
context: Context,
|
|
39
50
|
) : StripeAbstractComposeView(context) {
|
|
@@ -56,9 +67,92 @@ class EmbeddedPaymentElementView(
|
|
|
56
67
|
private val reactContext get() = context as ThemedReactContext
|
|
57
68
|
private val events = Channel<Event>(Channel.UNLIMITED)
|
|
58
69
|
|
|
70
|
+
@OptIn(ExperimentalCustomPaymentMethodsApi::class)
|
|
59
71
|
@Composable
|
|
60
72
|
override fun Content() {
|
|
61
73
|
val type by remember { rowSelectionBehaviorType }
|
|
74
|
+
val coroutineScope = rememberCoroutineScope()
|
|
75
|
+
|
|
76
|
+
val confirmCustomPaymentMethodCallback =
|
|
77
|
+
remember(coroutineScope) {
|
|
78
|
+
{
|
|
79
|
+
customPaymentMethod: PaymentSheet.CustomPaymentMethod,
|
|
80
|
+
billingDetails: PaymentMethod.BillingDetails,
|
|
81
|
+
->
|
|
82
|
+
// Launch a transparent Activity to ensure React Native UI can appear on top of the Stripe proxy activity.
|
|
83
|
+
try {
|
|
84
|
+
val intent =
|
|
85
|
+
Intent(reactContext, CustomPaymentMethodActivity::class.java).apply {
|
|
86
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
87
|
+
addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
|
|
88
|
+
}
|
|
89
|
+
reactContext.startActivity(intent)
|
|
90
|
+
} catch (e: Exception) {
|
|
91
|
+
Log.e("StripeReactNative", "Failed to start CustomPaymentMethodActivity", e)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
val stripeSdkModule =
|
|
95
|
+
try {
|
|
96
|
+
requireStripeSdkModule()
|
|
97
|
+
} catch (ex: IllegalArgumentException) {
|
|
98
|
+
Log.e("StripeReactNative", "StripeSdkModule not found for CPM callback", ex)
|
|
99
|
+
CustomPaymentMethodActivity.finishCurrent()
|
|
100
|
+
return@remember
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Keep JS awake while React Native is backgrounded by Stripe SDK.
|
|
104
|
+
val keepJsAwakeTask =
|
|
105
|
+
KeepJsAwakeTask(reactContext.reactApplicationContext).apply { start() }
|
|
106
|
+
|
|
107
|
+
// Run on coroutine scope.
|
|
108
|
+
coroutineScope.launch {
|
|
109
|
+
try {
|
|
110
|
+
// Give the CustomPaymentMethodActivity a moment to fully initialize
|
|
111
|
+
delay(100)
|
|
112
|
+
|
|
113
|
+
// Emit event so JS can show the Alert and eventually respond via `customPaymentMethodResultCallback`.
|
|
114
|
+
stripeSdkModule.emitOnCustomPaymentMethodConfirmHandlerCallback(
|
|
115
|
+
mapFromCustomPaymentMethod(customPaymentMethod, billingDetails),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Await JS result.
|
|
119
|
+
val resultFromJs = stripeSdkModule.customPaymentMethodResultCallback.await()
|
|
120
|
+
|
|
121
|
+
keepJsAwakeTask.stop()
|
|
122
|
+
|
|
123
|
+
val status = resultFromJs.getString("status")
|
|
124
|
+
|
|
125
|
+
val nativeResult =
|
|
126
|
+
when (status) {
|
|
127
|
+
"completed" ->
|
|
128
|
+
CustomPaymentMethodResult
|
|
129
|
+
.completed()
|
|
130
|
+
"canceled" ->
|
|
131
|
+
CustomPaymentMethodResult
|
|
132
|
+
.canceled()
|
|
133
|
+
"failed" -> {
|
|
134
|
+
val errMsg = resultFromJs.getString("error") ?: "Custom payment failed"
|
|
135
|
+
CustomPaymentMethodResult
|
|
136
|
+
.failed(displayMessage = errMsg)
|
|
137
|
+
}
|
|
138
|
+
else ->
|
|
139
|
+
CustomPaymentMethodResult
|
|
140
|
+
.failed(displayMessage = "Unknown status")
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Return result to Stripe SDK.
|
|
144
|
+
CustomPaymentMethodResultHandler.handleCustomPaymentMethodResult(
|
|
145
|
+
reactContext,
|
|
146
|
+
nativeResult,
|
|
147
|
+
)
|
|
148
|
+
} finally {
|
|
149
|
+
// Clean up the transparent activity
|
|
150
|
+
CustomPaymentMethodActivity.finishCurrent()
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
62
156
|
val builder =
|
|
63
157
|
remember(type) {
|
|
64
158
|
EmbeddedPaymentElement
|
|
@@ -125,7 +219,8 @@ class EmbeddedPaymentElementView(
|
|
|
125
219
|
}
|
|
126
220
|
requireStripeSdkModule().emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
|
|
127
221
|
},
|
|
128
|
-
).
|
|
222
|
+
).confirmCustomPaymentMethodCallback(confirmCustomPaymentMethodCallback)
|
|
223
|
+
.rowSelectionBehavior(
|
|
129
224
|
if (type == RowSelectionBehaviorType.Default) {
|
|
130
225
|
EmbeddedPaymentElement.RowSelectionBehavior.default()
|
|
131
226
|
} else {
|
|
@@ -17,10 +17,13 @@ import com.reactnativestripesdk.PaymentSheetFragment.Companion.buildGooglePayCon
|
|
|
17
17
|
import com.reactnativestripesdk.addresssheet.AddressSheetView
|
|
18
18
|
import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
|
|
19
19
|
import com.reactnativestripesdk.utils.PaymentSheetException
|
|
20
|
+
import com.reactnativestripesdk.utils.getBooleanOr
|
|
20
21
|
import com.reactnativestripesdk.utils.mapToPreferredNetworks
|
|
22
|
+
import com.reactnativestripesdk.utils.parseCustomPaymentMethods
|
|
21
23
|
import com.reactnativestripesdk.utils.toBundleObject
|
|
22
24
|
import com.stripe.android.ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi
|
|
23
25
|
import com.stripe.android.paymentelement.EmbeddedPaymentElement
|
|
26
|
+
import com.stripe.android.paymentelement.ExperimentalCustomPaymentMethodsApi
|
|
24
27
|
import com.stripe.android.paymentsheet.PaymentSheet
|
|
25
28
|
|
|
26
29
|
@ReactModule(name = EmbeddedPaymentElementViewManager.NAME)
|
|
@@ -52,10 +55,13 @@ class EmbeddedPaymentElementViewManager :
|
|
|
52
55
|
view: EmbeddedPaymentElementView,
|
|
53
56
|
cfg: Dynamic,
|
|
54
57
|
) {
|
|
55
|
-
val
|
|
58
|
+
val readableMap = cfg.asMap()
|
|
59
|
+
if (readableMap == null) return
|
|
60
|
+
|
|
61
|
+
val rowSelectionBehaviorType = parseRowSelectionBehavior(readableMap)
|
|
56
62
|
view.rowSelectionBehaviorType.value = rowSelectionBehaviorType
|
|
57
63
|
|
|
58
|
-
val elementConfig = parseElementConfiguration(
|
|
64
|
+
val elementConfig = parseElementConfiguration(readableMap, view.context)
|
|
59
65
|
view.latestElementConfig = elementConfig
|
|
60
66
|
// if intentConfig is already set, configure immediately:
|
|
61
67
|
view.latestIntentConfig?.let { intentCfg ->
|
|
@@ -72,7 +78,9 @@ class EmbeddedPaymentElementViewManager :
|
|
|
72
78
|
view: EmbeddedPaymentElementView,
|
|
73
79
|
cfg: Dynamic,
|
|
74
80
|
) {
|
|
75
|
-
val
|
|
81
|
+
val readableMap = cfg.asMap()
|
|
82
|
+
if (readableMap == null) return
|
|
83
|
+
val intentConfig = parseIntentConfiguration(readableMap)
|
|
76
84
|
view.latestIntentConfig = intentConfig
|
|
77
85
|
view.latestElementConfig?.let { elemCfg ->
|
|
78
86
|
view.configure(elemCfg, intentConfig)
|
|
@@ -80,7 +88,10 @@ class EmbeddedPaymentElementViewManager :
|
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
@SuppressLint("RestrictedApi")
|
|
83
|
-
@OptIn(
|
|
91
|
+
@OptIn(
|
|
92
|
+
ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class,
|
|
93
|
+
ExperimentalCustomPaymentMethodsApi::class,
|
|
94
|
+
)
|
|
84
95
|
private fun parseElementConfiguration(
|
|
85
96
|
map: ReadableMap,
|
|
86
97
|
context: Context,
|
|
@@ -142,7 +153,7 @@ class EmbeddedPaymentElementViewManager :
|
|
|
142
153
|
email = mapToCollectionMode(billingConfigParams?.getString("email")),
|
|
143
154
|
address = mapToAddressCollectionMode(billingConfigParams?.getString("address")),
|
|
144
155
|
attachDefaultsToPaymentMethod =
|
|
145
|
-
billingConfigParams?.
|
|
156
|
+
billingConfigParams?.getBooleanOr("attachDefaultsToPaymentMethod", false) ?: false,
|
|
146
157
|
)
|
|
147
158
|
val allowsRemovalOfLastSavedPaymentMethod =
|
|
148
159
|
if (map.hasKey("allowsRemovalOfLastSavedPaymentMethod")) {
|
|
@@ -184,6 +195,16 @@ class EmbeddedPaymentElementViewManager :
|
|
|
184
195
|
),
|
|
185
196
|
).allowsRemovalOfLastSavedPaymentMethod(allowsRemovalOfLastSavedPaymentMethod)
|
|
186
197
|
.cardBrandAcceptance(mapToCardBrandAcceptance(toBundleObject(map)))
|
|
198
|
+
// Serialize original ReadableMap because toBundleObject cannot keep arrays of objects
|
|
199
|
+
.customPaymentMethods(
|
|
200
|
+
parseCustomPaymentMethods(
|
|
201
|
+
toBundleObject(map.getMap("customPaymentMethodConfiguration")).apply {
|
|
202
|
+
map.getMap("customPaymentMethodConfiguration")?.let { readable ->
|
|
203
|
+
putSerializable("customPaymentMethodConfigurationReadableMap", readable.toHashMap())
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
),
|
|
207
|
+
)
|
|
187
208
|
|
|
188
209
|
primaryButtonLabel?.let { configurationBuilder.primaryButtonLabel(it) }
|
|
189
210
|
paymentMethodOrder?.let { configurationBuilder.paymentMethodOrder(it) }
|
|
@@ -38,7 +38,6 @@ class PaymentMethodCreateParamsFactory(
|
|
|
38
38
|
PaymentMethod.Type.Card -> createCardPaymentMethodParams()
|
|
39
39
|
PaymentMethod.Type.Ideal -> createIDEALParams()
|
|
40
40
|
PaymentMethod.Type.Alipay -> createAlipayParams()
|
|
41
|
-
PaymentMethod.Type.Sofort -> createSofortParams()
|
|
42
41
|
PaymentMethod.Type.Bancontact -> createBancontactParams()
|
|
43
42
|
PaymentMethod.Type.SepaDebit -> createSepaParams()
|
|
44
43
|
PaymentMethod.Type.Oxxo -> createOXXOParams()
|
|
@@ -79,21 +78,6 @@ class PaymentMethodCreateParamsFactory(
|
|
|
79
78
|
@Throws(PaymentMethodCreateParamsException::class)
|
|
80
79
|
private fun createAlipayParams(): PaymentMethodCreateParams = PaymentMethodCreateParams.createAlipay()
|
|
81
80
|
|
|
82
|
-
@Throws(PaymentMethodCreateParamsException::class)
|
|
83
|
-
private fun createSofortParams(): PaymentMethodCreateParams {
|
|
84
|
-
val country =
|
|
85
|
-
getValOr(paymentMethodData, "country", null)
|
|
86
|
-
?: run {
|
|
87
|
-
throw PaymentMethodCreateParamsException("You must provide bank account country")
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return PaymentMethodCreateParams.create(
|
|
91
|
-
PaymentMethodCreateParams.Sofort(country = country),
|
|
92
|
-
billingDetailsParams,
|
|
93
|
-
metadata = metadataParams,
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
81
|
@Throws(PaymentMethodCreateParamsException::class)
|
|
98
82
|
private fun createBancontactParams(): PaymentMethodCreateParams {
|
|
99
83
|
billingDetailsParams?.let {
|
|
@@ -271,7 +255,6 @@ class PaymentMethodCreateParamsFactory(
|
|
|
271
255
|
PaymentMethod.Type.Affirm -> createAffirmStripeIntentParams(clientSecret, isPaymentIntent)
|
|
272
256
|
PaymentMethod.Type.Ideal,
|
|
273
257
|
PaymentMethod.Type.Alipay,
|
|
274
|
-
PaymentMethod.Type.Sofort,
|
|
275
258
|
PaymentMethod.Type.Bancontact,
|
|
276
259
|
PaymentMethod.Type.SepaDebit,
|
|
277
260
|
PaymentMethod.Type.Oxxo,
|
|
@@ -478,9 +478,11 @@ private fun buildFormInsets(insetParams: Bundle?): PaymentSheet.Insets {
|
|
|
478
478
|
}
|
|
479
479
|
|
|
480
480
|
/**
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
481
|
+
* Parses a ThemedColor from [params] at [key]. Supports both:
|
|
482
|
+
* - Single hex string: "#RRGGBB"
|
|
483
|
+
* - Light/dark object: { "light": "#RRGGBB", "dark": "#RRGGBB" }
|
|
484
|
+
* For light/dark objects, chooses the appropriate color based on current UI mode.
|
|
485
|
+
* Falls back to [defaultColor] if no color is provided.
|
|
484
486
|
*/
|
|
485
487
|
private fun dynamicColorFromParams(
|
|
486
488
|
context: Context,
|
|
@@ -488,8 +490,12 @@ private fun dynamicColorFromParams(
|
|
|
488
490
|
key: String,
|
|
489
491
|
defaultColor: Int,
|
|
490
492
|
): Int {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
+
if (params == null) {
|
|
494
|
+
return defaultColor
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// First check if it's a nested Bundle { "light": "#RRGGBB", "dark": "#RRGGBB" }
|
|
498
|
+
val colorBundle = params.getBundle(key)
|
|
493
499
|
if (colorBundle != null) {
|
|
494
500
|
val isDark =
|
|
495
501
|
(
|
|
@@ -508,7 +514,12 @@ private fun dynamicColorFromParams(
|
|
|
508
514
|
return colorFromHexOrDefault(hex, defaultColor)
|
|
509
515
|
}
|
|
510
516
|
|
|
511
|
-
//
|
|
517
|
+
// Check if it's a single color string
|
|
518
|
+
params.getString(key)?.let { colorString ->
|
|
519
|
+
return colorFromHexOrDefault(colorString, defaultColor)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// no override → just use default
|
|
512
523
|
return defaultColor
|
|
513
524
|
}
|
|
514
525
|
|