@stripe/stripe-react-native 0.71.0 → 0.72.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/CurrencySelectorElementView.kt +7 -103
- package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +1 -5
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +0 -26
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +6 -21
- package/android/src/main/java/com/reactnativestripesdk/LinkControllerManager.kt +59 -18
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +14 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +6 -50
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +38 -187
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +2 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +4 -0
- package/android/src/onramp/java/com/reactnativestripesdk/OnrampMappers.kt +1 -0
- package/android/src/test/java/com/reactnativestripesdk/mappers/MappersTest.kt +0 -60
- package/ios/CurrencySelectorElementView.swift +18 -129
- package/ios/Mappers.swift +2 -0
- package/ios/PaymentMethodFactory.swift +14 -1
- package/ios/StripeSdk.mm +7 -0
- package/ios/StripeSdkImpl+Checkout.swift +35 -259
- package/ios/StripeSdkImpl+Embedded.swift +5 -28
- package/ios/StripeSdkImpl+LinkController.swift +40 -2
- package/ios/StripeSdkImpl+PaymentSheet.swift +2 -15
- package/ios/StripeSdkImpl.swift +2 -4
- package/lib/commonjs/connect/EmbeddedComponent.js +2 -2
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/functions.js +1 -1
- package/lib/commonjs/functions.js.map +1 -1
- package/lib/commonjs/hooks/useLinkController.js +1 -1
- package/lib/commonjs/hooks/useLinkController.js.map +1 -1
- package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/commonjs/types/PaymentIntent.js.map +1 -1
- package/lib/module/connect/EmbeddedComponent.js +2 -2
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/functions.js +1 -1
- package/lib/module/functions.js.map +1 -1
- package/lib/module/hooks/useLinkController.js +1 -1
- package/lib/module/hooks/useLinkController.js.map +1 -1
- package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/module/types/PaymentIntent.js.map +1 -1
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts +1 -0
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
- package/lib/typescript/src/functions.d.ts +11 -0
- package/lib/typescript/src/functions.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useLinkController.d.ts +7 -0
- package/lib/typescript/src/hooks/useLinkController.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +4 -0
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/LinkController.d.ts +10 -5
- package/lib/typescript/src/types/LinkController.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentIntent.d.ts +9 -1
- package/lib/typescript/src/types/PaymentIntent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/connect/EmbeddedComponent.tsx +14 -2
- package/src/functions.ts +26 -0
- package/src/hooks/useLinkController.tsx +24 -1
- package/src/specs/NativeStripeSdkModule.ts +5 -0
- package/src/types/LinkController.ts +9 -5
- package/src/types/PaymentIntent.ts +11 -1
- package/stripe-react-native.podspec +1 -1
- package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorAppearance.kt +0 -229
- package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutAddressUpdate.kt +0 -45
- package/android/src/main/java/com/reactnativestripesdk/utils/CheckoutMappers.kt +0 -127
- package/android/src/test/java/com/reactnativestripesdk/CurrencySelectorAppearanceTest.kt +0 -137
- package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutMappersTest.kt +0 -98
- package/android/src/test/java/com/reactnativestripesdk/utils/CheckoutTestFixtures.java +0 -57
- package/ios/CurrencySelectorAppearance.swift +0 -120
- package/ios/Mappers+Checkout.swift +0 -337
|
@@ -67,6 +67,8 @@ class PaymentMethodFactory {
|
|
|
67
67
|
return try createPayByBankPaymentMethodParams()
|
|
68
68
|
// case STPPaymentMethodType.weChatPay:
|
|
69
69
|
// return try createWeChatPayPaymentMethodParams()
|
|
70
|
+
case STPPaymentMethodType.twint:
|
|
71
|
+
return try createTwintPaymentMethodParams()
|
|
70
72
|
default:
|
|
71
73
|
throw PaymentMethodError.paymentNotSupported
|
|
72
74
|
}
|
|
@@ -122,7 +124,7 @@ class PaymentMethodFactory {
|
|
|
122
124
|
return nil
|
|
123
125
|
case STPPaymentMethodType.revolutPay:
|
|
124
126
|
return nil
|
|
125
|
-
case STPPaymentMethodType.payByBank:
|
|
127
|
+
case STPPaymentMethodType.payByBank, STPPaymentMethodType.twint:
|
|
126
128
|
return nil
|
|
127
129
|
default:
|
|
128
130
|
throw PaymentMethodError.paymentNotSupported
|
|
@@ -327,6 +329,14 @@ class PaymentMethodFactory {
|
|
|
327
329
|
return STPPaymentMethodParams(eps: params, billingDetails: billingDetails, metadata: metadata)
|
|
328
330
|
}
|
|
329
331
|
|
|
332
|
+
private func createTwintPaymentMethodParams() throws -> STPPaymentMethodParams {
|
|
333
|
+
let params = STPPaymentMethodTwintParams()
|
|
334
|
+
guard let billingDetails = billingDetailsParams else {
|
|
335
|
+
throw PaymentMethodError.twintPaymentMissingParams
|
|
336
|
+
}
|
|
337
|
+
return STPPaymentMethodParams(twint: params, billingDetails: billingDetails, metadata: metadata)
|
|
338
|
+
}
|
|
339
|
+
|
|
330
340
|
private func createBECSDebitPaymentMethodParams() throws -> STPPaymentMethodParams {
|
|
331
341
|
let params = STPPaymentMethodAUBECSDebitParams()
|
|
332
342
|
|
|
@@ -424,6 +434,7 @@ class PaymentMethodFactory {
|
|
|
424
434
|
enum PaymentMethodError: Error {
|
|
425
435
|
case cardPaymentMissingParams
|
|
426
436
|
case epsPaymentMissingParams
|
|
437
|
+
case twintPaymentMissingParams
|
|
427
438
|
case idealPaymentMissingParams
|
|
428
439
|
case paymentNotSupported
|
|
429
440
|
case cardPaymentOptionsMissingParams
|
|
@@ -459,6 +470,8 @@ extension PaymentMethodError: LocalizedError {
|
|
|
459
470
|
return NSLocalizedString("Multibanco requires that you provide the following billing details: email", comment: "Create payment error")
|
|
460
471
|
case .epsPaymentMissingParams:
|
|
461
472
|
return NSLocalizedString("You must provide billing details", comment: "Create payment error")
|
|
473
|
+
case .twintPaymentMissingParams:
|
|
474
|
+
return NSLocalizedString("You must provide billing details", comment: "Create payment error")
|
|
462
475
|
case .afterpayClearpayPaymentMissingParams:
|
|
463
476
|
return NSLocalizedString("You must provide billing details", comment: "Create payment error")
|
|
464
477
|
case .paymentNotSupported:
|
package/ios/StripeSdk.mm
CHANGED
|
@@ -599,6 +599,13 @@ RCT_EXPORT_METHOD(presentLinkController:(nonnull RCTPromiseResolveBlock)resolve
|
|
|
599
599
|
[StripeSdkImpl.shared presentLinkController:resolve rejecter:reject];
|
|
600
600
|
}
|
|
601
601
|
|
|
602
|
+
RCT_EXPORT_METHOD(confirmLinkControllerSetupIntent:(nonnull NSDictionary *)params
|
|
603
|
+
resolve:(nonnull RCTPromiseResolveBlock)resolve
|
|
604
|
+
reject:(nonnull RCTPromiseRejectBlock)reject)
|
|
605
|
+
{
|
|
606
|
+
[StripeSdkImpl.shared confirmLinkControllerSetupIntent:params resolver:resolve rejecter:reject];
|
|
607
|
+
}
|
|
608
|
+
|
|
602
609
|
/* clang-format on */
|
|
603
610
|
|
|
604
611
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
@@ -5,315 +5,91 @@
|
|
|
5
5
|
// Created by Nick Porter on 4/29/26.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Combine
|
|
9
8
|
import Foundation
|
|
10
|
-
@_spi(ReactNativeSDK) import StripePaymentSheet
|
|
11
9
|
|
|
12
10
|
extension StripeSdkImpl {
|
|
13
|
-
internal func currentCheckoutStateResult(checkout: Checkout) -> NSDictionary {
|
|
14
|
-
Mappers.mapFromCheckoutState(isLoading: checkout.isLoading, session: checkout.session)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
@objc(initCheckoutSession:configuration:resolver:rejecter:)
|
|
18
12
|
public func initCheckoutSession(
|
|
19
|
-
clientSecret: String,
|
|
20
|
-
configuration: NSDictionary,
|
|
21
|
-
resolver
|
|
13
|
+
clientSecret _: String,
|
|
14
|
+
configuration _: NSDictionary,
|
|
15
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
22
16
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
23
17
|
) {
|
|
24
|
-
|
|
25
|
-
clientSecret: clientSecret,
|
|
26
|
-
params: configuration
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
Task { @MainActor [weak self] in
|
|
30
|
-
guard let self else {
|
|
31
|
-
reject(ErrorType.Failed, "Stripe SDK is unavailable", nil)
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
do {
|
|
36
|
-
let checkout = try await Checkout(configuration: checkoutConfiguration)
|
|
37
|
-
let sessionKey = UUID().uuidString
|
|
38
|
-
|
|
39
|
-
let cancellable = checkout.$isLoading
|
|
40
|
-
.combineLatest(checkout.$session)
|
|
41
|
-
.dropFirst()
|
|
42
|
-
.sink { [weak self] isLoading, session in
|
|
43
|
-
self?.emitter?.emitCheckoutSessionDidChangeState([
|
|
44
|
-
"sessionKey": sessionKey,
|
|
45
|
-
"state": Mappers.mapFromCheckoutState(isLoading: isLoading, session: session),
|
|
46
|
-
])
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
self.checkoutInstances[sessionKey] = checkout
|
|
50
|
-
self.checkoutStateCancellables[sessionKey] = cancellable
|
|
51
|
-
|
|
52
|
-
resolve([
|
|
53
|
-
"sessionKey": sessionKey,
|
|
54
|
-
"state": self.currentCheckoutStateResult(checkout: checkout),
|
|
55
|
-
])
|
|
56
|
-
} catch {
|
|
57
|
-
reject(self.checkoutErrorCode(for: error), error.localizedDescription, error)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
18
|
+
rejectCheckoutUnavailable(reject)
|
|
60
19
|
}
|
|
61
20
|
|
|
62
21
|
@objc(checkoutUpdateShippingAddress:address:name:phone:resolver:rejecter:)
|
|
63
22
|
public func checkoutUpdateShippingAddress(
|
|
64
|
-
sessionKey: String,
|
|
65
|
-
address: NSDictionary,
|
|
66
|
-
name: String?,
|
|
67
|
-
phone: String?,
|
|
68
|
-
resolver
|
|
23
|
+
sessionKey _: String,
|
|
24
|
+
address _: NSDictionary,
|
|
25
|
+
name _: String?,
|
|
26
|
+
phone _: String?,
|
|
27
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
69
28
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
70
29
|
) {
|
|
71
|
-
|
|
72
|
-
sessionKey: sessionKey,
|
|
73
|
-
address: address,
|
|
74
|
-
name: name,
|
|
75
|
-
phone: phone,
|
|
76
|
-
missingCountryMessage: "A shipping address country is required.",
|
|
77
|
-
resolver: resolve,
|
|
78
|
-
rejecter: reject
|
|
79
|
-
) { checkout, addressUpdate in
|
|
80
|
-
try await checkout.updateShippingAddress(
|
|
81
|
-
name: addressUpdate.name,
|
|
82
|
-
phone: addressUpdate.phone,
|
|
83
|
-
address: addressUpdate.address
|
|
84
|
-
)
|
|
85
|
-
}
|
|
30
|
+
rejectCheckoutUnavailable(reject)
|
|
86
31
|
}
|
|
87
32
|
|
|
88
33
|
@objc(checkoutApplyPromotionCode:code:resolver:rejecter:)
|
|
89
34
|
public func checkoutApplyPromotionCode(
|
|
90
|
-
sessionKey: String,
|
|
91
|
-
code: String,
|
|
92
|
-
resolver
|
|
35
|
+
sessionKey _: String,
|
|
36
|
+
code _: String,
|
|
37
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
93
38
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
94
39
|
) {
|
|
95
|
-
|
|
96
|
-
sessionKey: sessionKey,
|
|
97
|
-
resolver: resolve,
|
|
98
|
-
rejecter: reject
|
|
99
|
-
) { checkout in
|
|
100
|
-
try await checkout.applyPromotionCode(code)
|
|
101
|
-
}
|
|
40
|
+
rejectCheckoutUnavailable(reject)
|
|
102
41
|
}
|
|
103
42
|
|
|
104
43
|
@objc(checkoutRemovePromotionCode:resolver:rejecter:)
|
|
105
44
|
public func checkoutRemovePromotionCode(
|
|
106
|
-
sessionKey: String,
|
|
107
|
-
resolver
|
|
45
|
+
sessionKey _: String,
|
|
46
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
108
47
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
109
48
|
) {
|
|
110
|
-
|
|
111
|
-
sessionKey: sessionKey,
|
|
112
|
-
resolver: resolve,
|
|
113
|
-
rejecter: reject
|
|
114
|
-
) { checkout in
|
|
115
|
-
try await checkout.removePromotionCode()
|
|
116
|
-
}
|
|
49
|
+
rejectCheckoutUnavailable(reject)
|
|
117
50
|
}
|
|
118
51
|
|
|
119
52
|
@objc(checkoutUpdateLineItemQuantity:lineItemId:quantity:resolver:rejecter:)
|
|
120
53
|
public func checkoutUpdateLineItemQuantity(
|
|
121
|
-
sessionKey: String,
|
|
122
|
-
lineItemId: String,
|
|
123
|
-
quantity: Double,
|
|
124
|
-
resolver
|
|
54
|
+
sessionKey _: String,
|
|
55
|
+
lineItemId _: String,
|
|
56
|
+
quantity _: Double,
|
|
57
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
125
58
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
126
59
|
) {
|
|
127
|
-
|
|
128
|
-
reject(ErrorType.Failed, "Line item quantity must be an integer.", nil)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
performCheckoutMutation(
|
|
133
|
-
sessionKey: sessionKey,
|
|
134
|
-
resolver: resolve,
|
|
135
|
-
rejecter: reject
|
|
136
|
-
) { checkout in
|
|
137
|
-
try await checkout.updateQuantity(lineItemId: lineItemId, quantity: integerQuantity)
|
|
138
|
-
}
|
|
60
|
+
rejectCheckoutUnavailable(reject)
|
|
139
61
|
}
|
|
140
62
|
|
|
141
63
|
@objc(checkoutSelectShippingOption:id:resolver:rejecter:)
|
|
142
64
|
public func checkoutSelectShippingOption(
|
|
143
|
-
sessionKey: String,
|
|
144
|
-
id: String,
|
|
145
|
-
resolver
|
|
65
|
+
sessionKey _: String,
|
|
66
|
+
id _: String,
|
|
67
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
146
68
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
147
69
|
) {
|
|
148
|
-
|
|
149
|
-
sessionKey: sessionKey,
|
|
150
|
-
resolver: resolve,
|
|
151
|
-
rejecter: reject
|
|
152
|
-
) { checkout in
|
|
153
|
-
try await checkout.selectShippingOption(id)
|
|
154
|
-
}
|
|
70
|
+
rejectCheckoutUnavailable(reject)
|
|
155
71
|
}
|
|
156
72
|
|
|
157
73
|
@objc(checkoutRunServerUpdateStart:resolver:rejecter:)
|
|
158
74
|
public func checkoutRunServerUpdateStart(
|
|
159
|
-
sessionKey: String,
|
|
160
|
-
resolver
|
|
75
|
+
sessionKey _: String,
|
|
76
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
161
77
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
162
78
|
) {
|
|
163
|
-
|
|
164
|
-
guard let self else {
|
|
165
|
-
reject(ErrorType.Failed, "Stripe SDK is unavailable", nil)
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
guard let checkout = self.checkoutInstances[sessionKey] else {
|
|
170
|
-
reject(ErrorType.Failed, "Checkout session not found", nil)
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
guard self.serverUpdateContinuations[sessionKey] == nil else {
|
|
175
|
-
reject(ErrorType.Failed, "A server update is already in progress for this session", nil)
|
|
176
|
-
return
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
do {
|
|
180
|
-
try await checkout.runServerUpdate {
|
|
181
|
-
try await withCheckedThrowingContinuation { continuation in
|
|
182
|
-
self.serverUpdateContinuations[sessionKey] = continuation
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
resolve(self.currentCheckoutStateResult(checkout: checkout))
|
|
186
|
-
} catch {
|
|
187
|
-
reject(self.checkoutErrorCode(for: error), error.localizedDescription, error)
|
|
188
|
-
}
|
|
189
|
-
}
|
|
79
|
+
rejectCheckoutUnavailable(reject)
|
|
190
80
|
}
|
|
191
81
|
|
|
192
82
|
@objc(checkoutRunServerUpdateComplete:error:resolver:rejecter:)
|
|
193
83
|
public func checkoutRunServerUpdateComplete(
|
|
194
|
-
sessionKey: String,
|
|
195
|
-
error: String?,
|
|
196
|
-
resolver
|
|
84
|
+
sessionKey _: String,
|
|
85
|
+
error _: String?,
|
|
86
|
+
resolver _: @escaping RCTPromiseResolveBlock,
|
|
197
87
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
198
88
|
) {
|
|
199
|
-
|
|
200
|
-
reject(ErrorType.Failed, "No pending server update for this session", nil)
|
|
201
|
-
return
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if let error {
|
|
205
|
-
continuation.resume(throwing: CheckoutError.apiError(message: error))
|
|
206
|
-
} else {
|
|
207
|
-
continuation.resume()
|
|
208
|
-
}
|
|
209
|
-
resolve(nil)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
internal func buildCheckoutConfiguration(
|
|
213
|
-
clientSecret: String,
|
|
214
|
-
params: NSDictionary
|
|
215
|
-
) -> Checkout.Configuration {
|
|
216
|
-
var configuration = Checkout.Configuration(clientSecret: clientSecret)
|
|
217
|
-
|
|
218
|
-
if let adaptivePricing = params["adaptivePricing"] as? NSDictionary,
|
|
219
|
-
let allowed = adaptivePricing["allowed"] as? Bool {
|
|
220
|
-
configuration.adaptivePricing.allowed = allowed
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return configuration
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private func performCheckoutMutation(
|
|
227
|
-
sessionKey: String,
|
|
228
|
-
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
229
|
-
rejecter reject: @escaping RCTPromiseRejectBlock,
|
|
230
|
-
operation: @escaping (Checkout) async throws -> Void
|
|
231
|
-
) {
|
|
232
|
-
Task { @MainActor [weak self] in
|
|
233
|
-
guard let self else {
|
|
234
|
-
reject(ErrorType.Failed, "Stripe SDK is unavailable", nil)
|
|
235
|
-
return
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
guard let checkout = self.checkoutInstances[sessionKey] else {
|
|
239
|
-
reject(ErrorType.Failed, "Checkout session not found", nil)
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
do {
|
|
244
|
-
try await operation(checkout)
|
|
245
|
-
resolve(self.currentCheckoutStateResult(checkout: checkout))
|
|
246
|
-
} catch {
|
|
247
|
-
reject(self.checkoutErrorCode(for: error), error.localizedDescription, error)
|
|
248
|
-
}
|
|
249
|
-
}
|
|
89
|
+
rejectCheckoutUnavailable(reject)
|
|
250
90
|
}
|
|
251
91
|
|
|
252
|
-
private func
|
|
253
|
-
|
|
254
|
-
address: NSDictionary,
|
|
255
|
-
name: String?,
|
|
256
|
-
phone: String?,
|
|
257
|
-
missingCountryMessage: String,
|
|
258
|
-
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
259
|
-
rejecter reject: @escaping RCTPromiseRejectBlock,
|
|
260
|
-
operation: @escaping (Checkout, Checkout.ContactAddress) async throws -> Void
|
|
261
|
-
) {
|
|
262
|
-
guard let addressUpdate = buildCheckoutAddressUpdate(
|
|
263
|
-
address: address,
|
|
264
|
-
name: name,
|
|
265
|
-
phone: phone
|
|
266
|
-
) else {
|
|
267
|
-
reject(ErrorType.Failed, missingCountryMessage, nil)
|
|
268
|
-
return
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
performCheckoutMutation(
|
|
272
|
-
sessionKey: sessionKey,
|
|
273
|
-
resolver: resolve,
|
|
274
|
-
rejecter: reject
|
|
275
|
-
) { checkout in
|
|
276
|
-
try await operation(checkout, addressUpdate)
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
private func buildCheckoutAddressUpdate(
|
|
281
|
-
address: NSDictionary,
|
|
282
|
-
name: String?,
|
|
283
|
-
phone: String?
|
|
284
|
-
) -> Checkout.ContactAddress? {
|
|
285
|
-
guard let country = address["country"] as? String, !country.isEmpty else {
|
|
286
|
-
return nil
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
let checkoutAddress = Checkout.Address(
|
|
290
|
-
country: country,
|
|
291
|
-
line1: address["line1"] as? String,
|
|
292
|
-
line2: address["line2"] as? String,
|
|
293
|
-
city: address["city"] as? String,
|
|
294
|
-
state: address["state"] as? String,
|
|
295
|
-
postalCode: address["postalCode"] as? String
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
return Checkout.ContactAddress(
|
|
299
|
-
name: name,
|
|
300
|
-
phone: phone,
|
|
301
|
-
address: checkoutAddress
|
|
302
|
-
)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
private func checkoutErrorCode(for error: Error) -> String {
|
|
306
|
-
if let checkoutError = error as? CheckoutError {
|
|
307
|
-
switch checkoutError {
|
|
308
|
-
case .invalidClientSecret:
|
|
309
|
-
return "InvalidClientSecret"
|
|
310
|
-
case .sheetCurrentlyPresented:
|
|
311
|
-
return "SheetCurrentlyPresented"
|
|
312
|
-
default:
|
|
313
|
-
return ErrorType.Failed
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return ErrorType.Failed
|
|
92
|
+
private func rejectCheckoutUnavailable(_ reject: RCTPromiseRejectBlock) {
|
|
93
|
+
reject(ErrorType.Failed, StripeSdkImpl.checkoutUnavailableMessage, nil)
|
|
318
94
|
}
|
|
319
95
|
}
|
|
@@ -71,36 +71,13 @@ extension StripeSdkImpl {
|
|
|
71
71
|
|
|
72
72
|
@objc(createEmbeddedPaymentElementWithCheckout:configuration:resolve:reject:)
|
|
73
73
|
public func createEmbeddedPaymentElementWithCheckout(
|
|
74
|
-
sessionKey: String,
|
|
75
|
-
configuration: NSDictionary,
|
|
74
|
+
sessionKey _: String,
|
|
75
|
+
configuration _: NSDictionary,
|
|
76
76
|
resolve: @escaping RCTPromiseResolveBlock,
|
|
77
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
77
|
+
reject _: @escaping RCTPromiseRejectBlock
|
|
78
78
|
) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
resolve(nil)
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
guard let configuration = buildEmbeddedPaymentElementConfiguration(params: configuration).configuration else {
|
|
86
|
-
emitLoadingFailed(message: "Invalid configuration")
|
|
87
|
-
resolve(nil)
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
Task {
|
|
92
|
-
do {
|
|
93
|
-
let embeddedPaymentElement = try await EmbeddedPaymentElement.create(
|
|
94
|
-
checkout: checkout,
|
|
95
|
-
configuration: configuration
|
|
96
|
-
)
|
|
97
|
-
attachEmbedded(embeddedPaymentElement)
|
|
98
|
-
resolve(nil)
|
|
99
|
-
} catch {
|
|
100
|
-
emitLoadingFailed(error: error)
|
|
101
|
-
resolve(nil)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
79
|
+
emitLoadingFailed(message: StripeSdkImpl.checkoutUnavailableMessage)
|
|
80
|
+
resolve(nil)
|
|
104
81
|
}
|
|
105
82
|
|
|
106
83
|
/// Wires up a freshly created element and emits its initial height /
|
|
@@ -19,7 +19,6 @@ extension StripeSdkImpl {
|
|
|
19
19
|
let phoneNumber = params["phoneNumber"] as? String
|
|
20
20
|
let merchantDisplayName = params["merchantDisplayName"] as? String
|
|
21
21
|
let allowLogout = params["allowLogout"] as? Bool ?? true
|
|
22
|
-
let setupIntentClientSecret = params["setupIntentClientSecret"] as? String
|
|
23
22
|
|
|
24
23
|
var supportedPaymentMethodTypes: [LinkPaymentMethodType]?
|
|
25
24
|
if let rawTypes = params["supportedPaymentMethodTypes"] as? [String] {
|
|
@@ -32,15 +31,17 @@ extension StripeSdkImpl {
|
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
|
|
34
|
+
let paymentMethodTypes = params["paymentMethodTypes"] as? [String]
|
|
35
|
+
|
|
35
36
|
let configuration = LinkConfiguration(
|
|
36
37
|
supportedPaymentMethodTypes: supportedPaymentMethodTypes,
|
|
38
|
+
paymentMethodTypes: paymentMethodTypes,
|
|
37
39
|
allowLogout: allowLogout,
|
|
38
40
|
merchantDisplayName: merchantDisplayName
|
|
39
41
|
)
|
|
40
42
|
|
|
41
43
|
LinkController.create(
|
|
42
44
|
apiClient: STPAPIClient.shared,
|
|
43
|
-
setupIntentClientSecret: setupIntentClientSecret,
|
|
44
45
|
configuration: configuration
|
|
45
46
|
) { [weak self] result in
|
|
46
47
|
switch result {
|
|
@@ -94,6 +95,43 @@ extension StripeSdkImpl {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
@objc(confirmLinkControllerSetupIntent:resolver:rejecter:)
|
|
99
|
+
public func confirmLinkControllerSetupIntent(
|
|
100
|
+
_ params: NSDictionary,
|
|
101
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
102
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
103
|
+
) {
|
|
104
|
+
guard let clientSecret = params["clientSecret"] as? String else {
|
|
105
|
+
resolve(Errors.createError(ErrorType.Failed, "clientSecret is required."))
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
guard let controller = linkController else {
|
|
110
|
+
resolve(Errors.createError(ErrorType.Failed, "LinkController has not been initialized. Call initLinkController first."))
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Task { @MainActor in
|
|
115
|
+
let presentingViewController = findViewControllerPresenter(
|
|
116
|
+
from: RCTKeyWindow()?.rootViewController ?? UIViewController()
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
controller.confirmSetupIntent(
|
|
120
|
+
clientSecret: clientSecret,
|
|
121
|
+
from: presentingViewController
|
|
122
|
+
) { result in
|
|
123
|
+
switch result {
|
|
124
|
+
case .success(.completed):
|
|
125
|
+
resolve([:])
|
|
126
|
+
case .success(.canceled):
|
|
127
|
+
resolve(Errors.createError(ErrorType.Canceled, "The customer canceled SetupIntent confirmation."))
|
|
128
|
+
case .failure(let error):
|
|
129
|
+
resolve(Errors.createError(ErrorType.Failed, error))
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
97
135
|
private static func mapLinkPaymentMethodPreview(_ preview: LinkController.PaymentMethodPreview) -> [String: Any] {
|
|
98
136
|
let iconBase64 = "data:image/png;base64," + (preview.icon.pngData()?.base64EncodedString(options: []) ?? "")
|
|
99
137
|
var result: [String: Any] = [
|
|
@@ -183,21 +183,8 @@ extension StripeSdkImpl {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
if
|
|
187
|
-
|
|
188
|
-
guard let checkout = checkoutInstances[sessionKey] else {
|
|
189
|
-
resolve(Errors.createError(ErrorType.Failed, "Checkout session not found"))
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if params["customFlow"] as? Bool == true {
|
|
194
|
-
PaymentSheet.FlowController.create(checkout: checkout,
|
|
195
|
-
configuration: configuration) { [weak self] result in
|
|
196
|
-
handlePaymentSheetFlowControllerResult(result: result, stripeSdk: self)
|
|
197
|
-
}
|
|
198
|
-
} else {
|
|
199
|
-
resolve(Errors.createError(ErrorType.Failed, "PaymentSheet with checkout is not supported. Use customFlow: true instead."))
|
|
200
|
-
}
|
|
186
|
+
if params["checkout"] != nil {
|
|
187
|
+
resolve(Errors.createError(ErrorType.Failed, StripeSdkImpl.checkoutUnavailableMessage))
|
|
201
188
|
} else if let paymentIntentClientSecret = params["paymentIntentClientSecret"] as? String {
|
|
202
189
|
if !Errors.isPIClientSecretValid(clientSecret: paymentIntentClientSecret) {
|
|
203
190
|
resolve(Errors.createError(ErrorType.Failed, "`secret` format does not match expected client secret formatting."))
|
package/ios/StripeSdkImpl.swift
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import AuthenticationServices
|
|
2
|
-
import Combine
|
|
3
2
|
import Foundation
|
|
4
3
|
import PassKit
|
|
5
4
|
@_spi(DashboardOnly) @_spi(STP) import Stripe
|
|
@@ -38,6 +37,8 @@ private func getDeviceType() -> String {
|
|
|
38
37
|
public class StripeSdkImpl: NSObject, UIAdaptivePresentationControllerDelegate {
|
|
39
38
|
@objc public static let shared = StripeSdkImpl()
|
|
40
39
|
|
|
40
|
+
static let checkoutUnavailableMessage = "Checkout Sessions are temporarily unavailable while the native integration is being rebuilt."
|
|
41
|
+
|
|
41
42
|
static var isNewArchitecture: Bool {
|
|
42
43
|
#if RCT_NEW_ARCH_ENABLED
|
|
43
44
|
return true
|
|
@@ -63,9 +64,6 @@ public class StripeSdkImpl: NSObject, UIAdaptivePresentationControllerDelegate {
|
|
|
63
64
|
|
|
64
65
|
internal var paymentSheet: PaymentSheet?
|
|
65
66
|
internal var paymentSheetFlowController: PaymentSheet.FlowController?
|
|
66
|
-
internal var checkoutInstances: [String: Checkout] = [:]
|
|
67
|
-
internal var checkoutStateCancellables: [String: AnyCancellable] = [:]
|
|
68
|
-
internal var serverUpdateContinuations: [String: CheckedContinuation<Void, Error>] = [:]
|
|
69
67
|
var paymentSheetIntentCreationCallback: ((Result<String, Error>) -> Void)?
|
|
70
68
|
var paymentSheetConfirmationTokenIntentCreationCallback: ((Result<String, Error>) -> Void)?
|
|
71
69
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.EmbeddedComponent=EmbeddedComponent;exports.toStripeJsBankAccountToken=toStripeJsBankAccountToken;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _toConsumableArray2=_interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _package=_interopRequireDefault(require("../../../package.json"));var _NativeStripeSdkModule=_interopRequireDefault(require("../specs/NativeStripeSdkModule"));var _events=require("../events");var _ConnectComponentsProvider=require("./ConnectComponentsProvider");var _FinancialConnections=require("../types/FinancialConnections");var _ComponentAnalyticsClient=require("./analytics/ComponentAnalyticsClient");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="/Users/mats/stripe/stripe-react-native/src/connect/EmbeddedComponent.tsx";function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(var _t in e)"default"!==_t&&{}.hasOwnProperty.call(e,_t)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,_t))&&(i.get||i.set)?o(f,_t,i):f[_t]=e[_t]);return f;})(e,t);}var DEVELOPMENT_MODE=false;var DEVELOPMENT_URL=_reactNative.Platform.OS==='android'?'http://10.0.2.2:3001':'http://localhost:3001';var PRODUCTION_URL='https://connect-js.stripe.com';var BASE_URL=DEVELOPMENT_MODE?DEVELOPMENT_URL:PRODUCTION_URL;var sdkVersion=_package.default.version;var POLLING_INTERVAL_MS=500;var URL_DEDUPLICATION_TIMEOUT_MS=1000;var DEEP_LINK_GRACE_PERIOD_MS=500;if(!/^\d+\.\d+\.\d+$/.test(sdkVersion)){throw new Error(`Invalid SDK version: ${sdkVersion}. Must be in format X.Y.Z`);}var platformPrefix=_reactNative.Platform.select({ios:'iPhone',android:'Android',default:'Mobile'});var userAgent=[platformPrefix,`Stripe ReactNative SDK ${_reactNative.Platform.OS}/${_reactNative.Platform.Version}`,`stripe-react_native/${sdkVersion}`].join(' - ');var ALLOWED_STRIPE_HOSTS=['connect-js.stripe.com','connect.stripe.com','verify.stripe.com'].concat((0,_toConsumableArray2.default)(DEVELOPMENT_MODE?['10.0.2.2:3001','localhost:3001']:[]));function EmbeddedComponent(props){var _appearance$variables;var _useState=(0,_react.useState)(null),_useState2=(0,_slicedToArray2.default)(_useState,2),dynamicWebview=_useState2[0],setDynamicWebview=_useState2[1];var pendingAuthWebViewPromises=(0,_react.useRef)(new Map());var pendingFinancialConnectionsPromise=(0,_react.useRef)(null);var recentlyHandledUrls=(0,_react.useRef)(new Set());var loadWebViewComponent=(0,_react.useCallback)((0,_asyncToGenerator2.default)(function*(){if(dynamicWebview)return;setDynamicWebview({WebView:null});try{var mod=yield import('react-native-webview');setDynamicWebview({WebView:mod.WebView});}catch(err){console.error('Failed to import react-native-webview:',err);}}),[dynamicWebview]);(0,_react.useEffect)(function(){loadWebViewComponent();},[loadWebViewComponent]);var appState=(0,_react.useRef)(_reactNative.AppState.currentState);(0,_react.useEffect)(function(){if(_reactNative.Platform.OS!=='android')return;var pollInterval=setInterval((0,_asyncToGenerator2.default)(function*(){if(pendingAuthWebViewPromises.current.size===0){return;}try{var pendingUrls=yield _NativeStripeSdkModule.default.pollAndClearPendingStripeConnectUrls();if(pendingUrls&&pendingUrls.length>0){pendingUrls.forEach(function(url){if(url.startsWith('stripe-connect://')){if(recentlyHandledUrls.current.has(url)){return;}recentlyHandledUrls.current.add(url);setTimeout(function(){recentlyHandledUrls.current.delete(url);},URL_DEDUPLICATION_TIMEOUT_MS);var firstEntry=pendingAuthWebViewPromises.current.entries().next().value;if(firstEntry){var _firstEntry=(0,_slicedToArray2.default)(firstEntry,2),id=_firstEntry[0],promiseData=_firstEntry[1];if(promiseData.timeoutId){clearTimeout(promiseData.timeoutId);}pendingAuthWebViewPromises.current.delete(id);promiseData.callback(id,url);_NativeStripeSdkModule.default.authWebViewDeepLinkHandled(id).catch(function(){});}}});}}catch(_error){}}),POLLING_INTERVAL_MS);return function(){clearInterval(pollInterval);};},[]);(0,_react.useEffect)(function(){var subscription=_reactNative.AppState.addEventListener('change',function(nextAppState){if(appState.current.match(/inactive|background/)&&nextAppState==='active'){if(pendingAuthWebViewPromises.current.size>0){pendingAuthWebViewPromises.current.forEach(function(promiseData,id){if(!promiseData.timeoutId){var timeoutId=setTimeout(function(){var stillPending=pendingAuthWebViewPromises.current.get(id);if(stillPending){pendingAuthWebViewPromises.current.delete(id);stillPending.callback(id,null);}},DEEP_LINK_GRACE_PERIOD_MS);promiseData.timeoutId=timeoutId;}});}}appState.current=nextAppState;});return function(){var _pendingFinancialConn;var promises=pendingAuthWebViewPromises.current;promises.forEach(function(promiseData,_id){if(promiseData.timeoutId){clearTimeout(promiseData.timeoutId);}});promises.clear();(_pendingFinancialConn=pendingFinancialConnectionsPromise.current)==null||_pendingFinancialConn.cleanup();subscription.remove();};},[]);var _useConnectComponents=(0,_ConnectComponentsProvider.useConnectComponents)(),connectInstance=_useConnectComponents.connectInstance,appearance=_useConnectComponents.appearance,locale=_useConnectComponents.locale,analyticsClient=_useConnectComponents.analyticsClient;var _ref3=connectInstance.initParams,fonts=_ref3.fonts,publishableKey=_ref3.publishableKey,fetchClientSecret=_ref3.fetchClientSecret,overrides=_ref3.overrides;var component=props.component,componentProps=props.componentProps,onLoadError=props.onLoadError,onLoaderStart=props.onLoaderStart,onPageDidLoad=props.onPageDidLoad,callbacks=props.callbacks,style=props.style;var componentAnalytics=(0,_react.useMemo)(function(){return new _ComponentAnalyticsClient.ComponentAnalyticsClient(analyticsClient,{publishableKey:publishableKey,platformId:overrides==null?void 0:overrides.platformId,merchantId:overrides==null?void 0:overrides.merchantId,livemode:typeof(overrides==null?void 0:overrides.livemode)==='boolean'?overrides.livemode:publishableKey==null?void 0:publishableKey.startsWith('pk_live_'),component:component});},[analyticsClient,publishableKey,overrides,component]);var hashParams={component:component,publicKey:publishableKey,merchantIdOverride:overrides==null?void 0:overrides.merchantId,platformIdOverride:overrides==null?void 0:overrides.platformId,apiKeyOverride:overrides==null?void 0:overrides.apiKey,livemodeOverride:overrides==null?void 0:overrides.livemode};var hash=Object.entries(hashParams).filter(function(_ref4){var _ref5=(0,_slicedToArray2.default)(_ref4,2),_=_ref5[0],value=_ref5[1];return value!=null;}).map(function(_ref6){var _ref7=(0,_slicedToArray2.default)(_ref6,2),key=_ref7[0],value=_ref7[1];return`${encodeURIComponent(key)}=${encodeURIComponent(value)}`;}).join('&');var connectURL=`${BASE_URL}/v1.0/react_native_webview.html#${hash}`;var source=(0,_react.useMemo)(function(){return{uri:connectURL};},[connectURL]);var ref=(0,_react.useRef)(null);var hasTriedSourceReload=(0,_react.useRef)(false);var _useState3=(0,_react.useState)(appearance),_useState4=(0,_slicedToArray2.default)(_useState3,2),prevAppearance=_useState4[0],setPrevAppearance=_useState4[1];var _useState5=(0,_react.useState)(locale),_useState6=(0,_slicedToArray2.default)(_useState5,2),prevLocale=_useState6[0],setPrevLocale=_useState6[1];if(prevAppearance!==appearance||prevLocale!==locale){var _ref$current;setPrevAppearance(appearance);setPrevLocale(locale);var patchedAppearance=withDefaultFontFamily(appearance);(_ref$current=ref.current)==null||_ref$current.injectJavaScript(`
|
|
1
|
+
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.EmbeddedComponent=EmbeddedComponent;exports.isAllowedStripeHost=isAllowedStripeHost;exports.toStripeJsBankAccountToken=toStripeJsBankAccountToken;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _toConsumableArray2=_interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _package=_interopRequireDefault(require("../../../package.json"));var _NativeStripeSdkModule=_interopRequireDefault(require("../specs/NativeStripeSdkModule"));var _events=require("../events");var _ConnectComponentsProvider=require("./ConnectComponentsProvider");var _FinancialConnections=require("../types/FinancialConnections");var _ComponentAnalyticsClient=require("./analytics/ComponentAnalyticsClient");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="/Users/mats/stripe/stripe-react-native/src/connect/EmbeddedComponent.tsx";function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f);}for(var _t in e)"default"!==_t&&{}.hasOwnProperty.call(e,_t)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,_t))&&(i.get||i.set)?o(f,_t,i):f[_t]=e[_t]);return f;})(e,t);}var DEVELOPMENT_MODE=false;var DEVELOPMENT_URL=_reactNative.Platform.OS==='android'?'http://10.0.2.2:3001':'http://localhost:3001';var PRODUCTION_URL='https://connect-js.stripe.com';var BASE_URL=DEVELOPMENT_MODE?DEVELOPMENT_URL:PRODUCTION_URL;var sdkVersion=_package.default.version;var POLLING_INTERVAL_MS=500;var URL_DEDUPLICATION_TIMEOUT_MS=1000;var DEEP_LINK_GRACE_PERIOD_MS=500;if(!/^\d+\.\d+\.\d+$/.test(sdkVersion)){throw new Error(`Invalid SDK version: ${sdkVersion}. Must be in format X.Y.Z`);}var platformPrefix=_reactNative.Platform.select({ios:'iPhone',android:'Android',default:'Mobile'});var userAgent=[platformPrefix,`Stripe ReactNative SDK ${_reactNative.Platform.OS}/${_reactNative.Platform.Version}`,`stripe-react_native/${sdkVersion}`].join(' - ');var ALLOWED_STRIPE_HOSTS=['connect-js.stripe.com','connect.stripe.com','verify.stripe.com'].concat((0,_toConsumableArray2.default)(DEVELOPMENT_MODE?['10.0.2.2:3001','localhost:3001']:[]));function EmbeddedComponent(props){var _appearance$variables;var _useState=(0,_react.useState)(null),_useState2=(0,_slicedToArray2.default)(_useState,2),dynamicWebview=_useState2[0],setDynamicWebview=_useState2[1];var pendingAuthWebViewPromises=(0,_react.useRef)(new Map());var pendingFinancialConnectionsPromise=(0,_react.useRef)(null);var recentlyHandledUrls=(0,_react.useRef)(new Set());var loadWebViewComponent=(0,_react.useCallback)((0,_asyncToGenerator2.default)(function*(){if(dynamicWebview)return;setDynamicWebview({WebView:null});try{var mod=yield import('react-native-webview');setDynamicWebview({WebView:mod.WebView});}catch(err){console.error('Failed to import react-native-webview:',err);}}),[dynamicWebview]);(0,_react.useEffect)(function(){loadWebViewComponent();},[loadWebViewComponent]);var appState=(0,_react.useRef)(_reactNative.AppState.currentState);(0,_react.useEffect)(function(){if(_reactNative.Platform.OS!=='android')return;var pollInterval=setInterval((0,_asyncToGenerator2.default)(function*(){if(pendingAuthWebViewPromises.current.size===0){return;}try{var pendingUrls=yield _NativeStripeSdkModule.default.pollAndClearPendingStripeConnectUrls();if(pendingUrls&&pendingUrls.length>0){pendingUrls.forEach(function(url){if(url.startsWith('stripe-connect://')){if(recentlyHandledUrls.current.has(url)){return;}recentlyHandledUrls.current.add(url);setTimeout(function(){recentlyHandledUrls.current.delete(url);},URL_DEDUPLICATION_TIMEOUT_MS);var firstEntry=pendingAuthWebViewPromises.current.entries().next().value;if(firstEntry){var _firstEntry=(0,_slicedToArray2.default)(firstEntry,2),id=_firstEntry[0],promiseData=_firstEntry[1];if(promiseData.timeoutId){clearTimeout(promiseData.timeoutId);}pendingAuthWebViewPromises.current.delete(id);promiseData.callback(id,url);_NativeStripeSdkModule.default.authWebViewDeepLinkHandled(id).catch(function(){});}}});}}catch(_error){}}),POLLING_INTERVAL_MS);return function(){clearInterval(pollInterval);};},[]);(0,_react.useEffect)(function(){var subscription=_reactNative.AppState.addEventListener('change',function(nextAppState){if(appState.current.match(/inactive|background/)&&nextAppState==='active'){if(pendingAuthWebViewPromises.current.size>0){pendingAuthWebViewPromises.current.forEach(function(promiseData,id){if(!promiseData.timeoutId){var timeoutId=setTimeout(function(){var stillPending=pendingAuthWebViewPromises.current.get(id);if(stillPending){pendingAuthWebViewPromises.current.delete(id);stillPending.callback(id,null);}},DEEP_LINK_GRACE_PERIOD_MS);promiseData.timeoutId=timeoutId;}});}}appState.current=nextAppState;});return function(){var _pendingFinancialConn;var promises=pendingAuthWebViewPromises.current;promises.forEach(function(promiseData,_id){if(promiseData.timeoutId){clearTimeout(promiseData.timeoutId);}});promises.clear();(_pendingFinancialConn=pendingFinancialConnectionsPromise.current)==null||_pendingFinancialConn.cleanup();subscription.remove();};},[]);var _useConnectComponents=(0,_ConnectComponentsProvider.useConnectComponents)(),connectInstance=_useConnectComponents.connectInstance,appearance=_useConnectComponents.appearance,locale=_useConnectComponents.locale,analyticsClient=_useConnectComponents.analyticsClient;var _ref3=connectInstance.initParams,fonts=_ref3.fonts,publishableKey=_ref3.publishableKey,fetchClientSecret=_ref3.fetchClientSecret,overrides=_ref3.overrides;var component=props.component,componentProps=props.componentProps,onLoadError=props.onLoadError,onLoaderStart=props.onLoaderStart,onPageDidLoad=props.onPageDidLoad,callbacks=props.callbacks,style=props.style;var componentAnalytics=(0,_react.useMemo)(function(){return new _ComponentAnalyticsClient.ComponentAnalyticsClient(analyticsClient,{publishableKey:publishableKey,platformId:overrides==null?void 0:overrides.platformId,merchantId:overrides==null?void 0:overrides.merchantId,livemode:typeof(overrides==null?void 0:overrides.livemode)==='boolean'?overrides.livemode:publishableKey==null?void 0:publishableKey.startsWith('pk_live_'),component:component});},[analyticsClient,publishableKey,overrides,component]);var hashParams={component:component,publicKey:publishableKey,merchantIdOverride:overrides==null?void 0:overrides.merchantId,platformIdOverride:overrides==null?void 0:overrides.platformId,apiKeyOverride:overrides==null?void 0:overrides.apiKey,livemodeOverride:overrides==null?void 0:overrides.livemode};var hash=Object.entries(hashParams).filter(function(_ref4){var _ref5=(0,_slicedToArray2.default)(_ref4,2),_=_ref5[0],value=_ref5[1];return value!=null;}).map(function(_ref6){var _ref7=(0,_slicedToArray2.default)(_ref6,2),key=_ref7[0],value=_ref7[1];return`${encodeURIComponent(key)}=${encodeURIComponent(value)}`;}).join('&');var connectURL=`${BASE_URL}/v1.0/react_native_webview.html#${hash}`;var source=(0,_react.useMemo)(function(){return{uri:connectURL};},[connectURL]);var ref=(0,_react.useRef)(null);var hasTriedSourceReload=(0,_react.useRef)(false);var _useState3=(0,_react.useState)(appearance),_useState4=(0,_slicedToArray2.default)(_useState3,2),prevAppearance=_useState4[0],setPrevAppearance=_useState4[1];var _useState5=(0,_react.useState)(locale),_useState6=(0,_slicedToArray2.default)(_useState5,2),prevLocale=_useState6[0],setPrevLocale=_useState6[1];if(prevAppearance!==appearance||prevLocale!==locale){var _ref$current;setPrevAppearance(appearance);setPrevLocale(locale);var patchedAppearance=withDefaultFontFamily(appearance);(_ref$current=ref.current)==null||_ref$current.injectJavaScript(`
|
|
2
2
|
(function() {
|
|
3
3
|
window.updateConnectInstance(${JSON.stringify({appearance:patchedAppearance,locale:locale})});
|
|
4
4
|
true;
|
|
@@ -20,5 +20,5 @@ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault
|
|
|
20
20
|
})();
|
|
21
21
|
`);};var onMessageCallback=(0,_react.useCallback)(function(){var _ref0=(0,_asyncToGenerator2.default)(function*(event){var message;try{message=JSON.parse(event.nativeEvent.data);}catch(error){componentAnalytics.logDeserializeMessageError('unknown',error instanceof Error?error:new Error(String(error)));return;}if(message.type==='fetchClientSecret'){var _ref$current6;var clientSecret=yield fetchClientSecret().catch(function(error){handleUnexpectedError(error);return null;});if(!clientSecret)return;(_ref$current6=ref.current)==null||_ref$current6.injectJavaScript(`
|
|
22
22
|
window.clientSecretDeferred.resolve(${JSON.stringify(clientSecret)});
|
|
23
|
-
`);}else if(message.type==='debug'){console.debug(`[EmbeddedComponent ${component}]: ${message.data}`);}else if(message.type==='pageDidLoad'){var _message$data;var pageViewId=(_message$data=message.data)==null?void 0:_message$data.pageViewId;componentAnalytics.logComponentWebPageLoaded(pageViewId);onPageDidLoad==null||onPageDidLoad();}else if(message.type==='componentLoaded'){componentAnalytics.logComponentLoaded();}else if(message.type==='accountSessionClaimed'){}else if(message.type==='openFinancialConnections'){var messageData=message.data;var _clientSecret=messageData.clientSecret,id=messageData.id,connectedAccountId=messageData.connectedAccountId;if(!_clientSecret||typeof _clientSecret!=='string'){handleFinancialConnectionsResult(id,{error:{code:'InvalidClientSecret',message:'Invalid or missing clientSecret parameter'}});return;}if(pendingFinancialConnectionsPromise.current){handleFinancialConnectionsResult(id,{error:{code:'AlreadyInProgress',message:'Financial Connections flow already in progress'}});return;}var eventListener=null;if(__DEV__){eventListener=(0,_events.addListener)('onFinancialConnectionsEvent',function(fcEvent){console.debug(`[FinancialConnections ${component}]: ${fcEvent.name}`,fcEvent.metadata);});}var cleanup=function cleanup(){var _eventListener;(_eventListener=eventListener)==null||_eventListener.remove();pendingFinancialConnectionsPromise.current=null;};pendingFinancialConnectionsPromise.current={id:id,cleanup:cleanup};_NativeStripeSdkModule.default.collectBankAccountToken(_clientSecret,{connectedAccountId:connectedAccountId}).then(function(_ref1){var session=_ref1.session,token=_ref1.token,error=_ref1.error;cleanup();if(error){if(error.code===_FinancialConnections.FinancialConnectionsSheetError.Canceled){handleFinancialConnectionsResult(id,{session:undefined,token:undefined,error:undefined});return;}handleFinancialConnectionsResult(id,{session:undefined,token:undefined,error:{code:error.code,message:error.message,localizedMessage:error.localizedMessage,type:error.type}});}else if(token||session){handleFinancialConnectionsResult(id,{session:session,token:token?toStripeJsBankAccountToken(token):null,error:undefined});}else{handleFinancialConnectionsResult(id,{error:{code:'UnexpectedError',message:'No session, token, or error returned from Financial Connections'}});}}).catch(function(unexpectedError){cleanup();handleUnexpectedError(unexpectedError);handleFinancialConnectionsResult(id,{error:{code:'UnexpectedError',message:unexpectedError instanceof Error?unexpectedError.message:'An unexpected error occurred during Financial Connections'}});});}else if(message.type==='closeWebView'){callbacks==null||callbacks.onCloseWebView==null||callbacks.onCloseWebView({});}else if(message.type==='callSupplementalFunction'){}else if(message.type==='onSetterFunctionCalled'){var _ref10=message.data,setter=_ref10.setter,value=_ref10.value;if(setter==='setOnLoaderStart'){onLoaderStart==null||onLoaderStart(value);}else if(setter==='setOnLoadError'){onLoadError==null||onLoadError(value);}else{var functionName=setter.charAt(3).toLowerCase()+setter.substring(4);if(callbacks!=null&&callbacks[functionName]){callbacks[functionName](value);}else{componentAnalytics.logUnrecognizedSetter(setter);}}}else if(message.type==='openAuthenticatedWebView'){var _ref11=message.data,url=_ref11.url,_id2=_ref11.id;if(!isValidUrl(url)){handleUnexpectedError(new Error(`Invalid URL for authenticated webview: ${url}`));return;}componentAnalytics.logAuthenticatedWebViewOpened(_id2);_NativeStripeSdkModule.default.openAuthenticatedWebView(_id2,url).then(function(result){if(_reactNative.Platform.OS==='ios'){var _result$url;var resultUrl=(_result$url=result==null?void 0:result.url)!=null?_result$url:null;if(resultUrl){componentAnalytics.logAuthenticatedWebViewRedirected(_id2);}else{componentAnalytics.logAuthenticatedWebViewCanceled(_id2);}handleAuthWebViewResult(_id2,resultUrl);}else{pendingAuthWebViewPromises.current.set(_id2,{callback:function callback(authId,resultUrl){if(resultUrl){componentAnalytics.logAuthenticatedWebViewRedirected(authId);}else{componentAnalytics.logAuthenticatedWebViewCanceled(authId);}handleAuthWebViewResult(authId,resultUrl);}});}}).catch(function(error){if(__DEV__){console.error(`[EmbeddedComponent] Error opening authenticated webview:`,error);}componentAnalytics.logAuthenticatedWebViewError(_id2,error instanceof Error?error:new Error(String(error)));handleUnexpectedError(error);});}else{}});return function(_x){return _ref0.apply(this,arguments);};}(),[callbacks,component,componentAnalytics,fetchClientSecret,handleUnexpectedError,onLoadError,onLoaderStart,onPageDidLoad]);var onShouldStartLoadWithRequest=(0,_react.useCallback)(function(event){var url=event.url,navigationType=event.navigationType;if(isCsvExportUrl(url)){_NativeStripeSdkModule.default.downloadAndShareFile(url,null).then(function(result){if(!result.success){console.warn('CSV export share failed:',result.error);}}).catch(function(error){handleUnexpectedError(error);});return false;}if(navigationType!=='click')return true;if(
|
|
23
|
+
`);}else if(message.type==='debug'){console.debug(`[EmbeddedComponent ${component}]: ${message.data}`);}else if(message.type==='pageDidLoad'){var _message$data;var pageViewId=(_message$data=message.data)==null?void 0:_message$data.pageViewId;componentAnalytics.logComponentWebPageLoaded(pageViewId);onPageDidLoad==null||onPageDidLoad();}else if(message.type==='componentLoaded'){componentAnalytics.logComponentLoaded();}else if(message.type==='accountSessionClaimed'){}else if(message.type==='openFinancialConnections'){var messageData=message.data;var _clientSecret=messageData.clientSecret,id=messageData.id,connectedAccountId=messageData.connectedAccountId;if(!_clientSecret||typeof _clientSecret!=='string'){handleFinancialConnectionsResult(id,{error:{code:'InvalidClientSecret',message:'Invalid or missing clientSecret parameter'}});return;}if(pendingFinancialConnectionsPromise.current){handleFinancialConnectionsResult(id,{error:{code:'AlreadyInProgress',message:'Financial Connections flow already in progress'}});return;}var eventListener=null;if(__DEV__){eventListener=(0,_events.addListener)('onFinancialConnectionsEvent',function(fcEvent){console.debug(`[FinancialConnections ${component}]: ${fcEvent.name}`,fcEvent.metadata);});}var cleanup=function cleanup(){var _eventListener;(_eventListener=eventListener)==null||_eventListener.remove();pendingFinancialConnectionsPromise.current=null;};pendingFinancialConnectionsPromise.current={id:id,cleanup:cleanup};_NativeStripeSdkModule.default.collectBankAccountToken(_clientSecret,{connectedAccountId:connectedAccountId}).then(function(_ref1){var session=_ref1.session,token=_ref1.token,error=_ref1.error;cleanup();if(error){if(error.code===_FinancialConnections.FinancialConnectionsSheetError.Canceled){handleFinancialConnectionsResult(id,{session:undefined,token:undefined,error:undefined});return;}handleFinancialConnectionsResult(id,{session:undefined,token:undefined,error:{code:error.code,message:error.message,localizedMessage:error.localizedMessage,type:error.type}});}else if(token||session){handleFinancialConnectionsResult(id,{session:session,token:token?toStripeJsBankAccountToken(token):null,error:undefined});}else{handleFinancialConnectionsResult(id,{error:{code:'UnexpectedError',message:'No session, token, or error returned from Financial Connections'}});}}).catch(function(unexpectedError){cleanup();handleUnexpectedError(unexpectedError);handleFinancialConnectionsResult(id,{error:{code:'UnexpectedError',message:unexpectedError instanceof Error?unexpectedError.message:'An unexpected error occurred during Financial Connections'}});});}else if(message.type==='closeWebView'){callbacks==null||callbacks.onCloseWebView==null||callbacks.onCloseWebView({});}else if(message.type==='callSupplementalFunction'){}else if(message.type==='onSetterFunctionCalled'){var _ref10=message.data,setter=_ref10.setter,value=_ref10.value;if(setter==='setOnLoaderStart'){onLoaderStart==null||onLoaderStart(value);}else if(setter==='setOnLoadError'){onLoadError==null||onLoadError(value);}else{var functionName=setter.charAt(3).toLowerCase()+setter.substring(4);if(callbacks!=null&&callbacks[functionName]){callbacks[functionName](value);}else{componentAnalytics.logUnrecognizedSetter(setter);}}}else if(message.type==='openAuthenticatedWebView'){var _ref11=message.data,url=_ref11.url,_id2=_ref11.id;if(!isValidUrl(url)){handleUnexpectedError(new Error(`Invalid URL for authenticated webview: ${url}`));return;}componentAnalytics.logAuthenticatedWebViewOpened(_id2);_NativeStripeSdkModule.default.openAuthenticatedWebView(_id2,url).then(function(result){if(_reactNative.Platform.OS==='ios'){var _result$url;var resultUrl=(_result$url=result==null?void 0:result.url)!=null?_result$url:null;if(resultUrl){componentAnalytics.logAuthenticatedWebViewRedirected(_id2);}else{componentAnalytics.logAuthenticatedWebViewCanceled(_id2);}handleAuthWebViewResult(_id2,resultUrl);}else{pendingAuthWebViewPromises.current.set(_id2,{callback:function callback(authId,resultUrl){if(resultUrl){componentAnalytics.logAuthenticatedWebViewRedirected(authId);}else{componentAnalytics.logAuthenticatedWebViewCanceled(authId);}handleAuthWebViewResult(authId,resultUrl);}});}}).catch(function(error){if(__DEV__){console.error(`[EmbeddedComponent] Error opening authenticated webview:`,error);}componentAnalytics.logAuthenticatedWebViewError(_id2,error instanceof Error?error:new Error(String(error)));handleUnexpectedError(error);});}else{}});return function(_x){return _ref0.apply(this,arguments);};}(),[callbacks,component,componentAnalytics,fetchClientSecret,handleUnexpectedError,onLoadError,onLoaderStart,onPageDidLoad]);var onShouldStartLoadWithRequest=(0,_react.useCallback)(function(event){var url=event.url,navigationType=event.navigationType;if(isCsvExportUrl(url)){_NativeStripeSdkModule.default.downloadAndShareFile(url,null).then(function(result){if(!result.success){console.warn('CSV export share failed:',result.error);}}).catch(function(error){handleUnexpectedError(error);});return false;}if(navigationType!=='click')return true;if(isAllowedStripeHost(url)){return true;}_reactNative.Linking.openURL(url).catch(function(error){handleUnexpectedError(error);});return false;},[handleUnexpectedError]);var backgroundColor=(appearance==null||(_appearance$variables=appearance.variables)==null?void 0:_appearance$variables.colorBackground)||'#FFFFFF';var mergedStyle=(0,_react.useMemo)(function(){return[{backgroundColor:backgroundColor},style];},[backgroundColor,style]);if(!WebViewComponent)return null;return(0,_jsxRuntime.jsx)(WebViewComponent,{ref:ref,style:mergedStyle,webviewDebuggingEnabled:DEVELOPMENT_MODE,source:source,userAgent:userAgent,injectedJavaScriptObject:{initParams:{appearance:withDefaultFontFamily(appearance),locale:locale,fonts:fonts},initComponentProps:componentProps,appInfo:{applicationId:overrides==null?void 0:overrides.applicationId}},injectedJavaScriptBeforeContentLoaded:'(function() {})();',onMessage:onMessageCallback,onShouldStartLoadWithRequest:onShouldStartLoadWithRequest,onLayout:handleLayout,mediaCapturePermissionGrantType:"grantIfSameHostElsePrompt",allowsInlineMediaPlayback:true,mediaPlaybackRequiresUserAction:false});}var DEFAULT_FONT="-apple-system, 'system-ui', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'";function withDefaultFontFamily(appearance){var _appearance$variables2;if(appearance!=null&&(_appearance$variables2=appearance.variables)!=null&&_appearance$variables2.fontFamily){return appearance;}return Object.assign({},appearance,{variables:Object.assign({},appearance==null?void 0:appearance.variables,{fontFamily:DEFAULT_FONT})});}function toStripeJsBankAccountToken(token){var ba=token.bankAccount;return{id:token.id,object:'token',type:'bank_account',used:token.used,livemode:token.livemode,created:token.created,bank_account:ba?{id:ba.id,object:'bank_account',account_holder_name:ba.accountHolderName,account_holder_type:ba.accountHolderType,bank_name:ba.bankName,country:ba.country,currency:ba.currency,fingerprint:ba.fingerprint,last4:ba.last4,routing_number:ba.routingNumber,status:ba.status}:null};}function isValidUrl(url){try{var parsedUrl=new URL(url);return parsedUrl.protocol==='http:'||parsedUrl.protocol==='https:';}catch(_unused){return false;}}function isAllowedStripeHost(url){try{var parsedUrl=new URL(url);return ALLOWED_STRIPE_HOSTS.some(function(host){return parsedUrl.hostname===host||parsedUrl.host===host;});}catch(_unused2){return false;}}function isCsvExportUrl(url){try{var parsedUrl=new URL(url);return parsedUrl.hostname==='stripe-data-exports.com'||parsedUrl.hostname.endsWith('.stripe-data-exports.com')||parsedUrl.pathname.includes('stripe-data-exports');}catch(_unused3){return false;}}
|
|
24
24
|
//# sourceMappingURL=EmbeddedComponent.js.map
|