@stripe/stripe-react-native 0.57.2 → 0.58.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 +1 -0
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +0 -3
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +5 -3
- package/android/src/main/java/com/reactnativestripesdk/NavigationBarView.kt +12 -1
- package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +18 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +136 -35
- package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +17 -5
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +9 -2
- package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +38 -13
- package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +0 -2
- package/android/src/test/java/com/reactnativestripesdk/DrawableConversionPropertyTest.kt +224 -0
- package/android/src/test/java/com/reactnativestripesdk/DrawableConversionTest.kt +146 -0
- package/android/src/test/java/com/reactnativestripesdk/DrawableLoadingTest.kt +150 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentElementConfigTest.kt +138 -1
- package/android/src/test/java/com/reactnativestripesdk/PaymentOptionImageConsistencyTest.kt +186 -0
- package/ios/ConnectAccountOnboarding/ConnectAccountOnboardingView.swift +13 -19
- package/ios/StripeSdkImpl+Embedded.swift +4 -1
- package/ios/StripeSdkImpl+PaymentSheet.swift +28 -1
- package/ios/StripeSdkImpl.swift +26 -2
- package/jest/mock.js +6 -0
- package/jest/setup.js +30 -0
- 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/connect/Components.js +1 -1
- package/lib/commonjs/connect/Components.js.map +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/commonjs/connect/EmbeddedComponent.js +9 -4
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/connect/ModalCloseButton.js +1 -1
- package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
- package/lib/commonjs/connect/NavigationBar.js +1 -1
- package/lib/commonjs/connect/NavigationBar.js.map +1 -1
- package/lib/commonjs/helpers.js +1 -1
- package/lib/commonjs/hooks/useOnramp.js +1 -1
- package/lib/commonjs/hooks/useOnramp.js.map +1 -1
- package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
- package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
- package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
- package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
- package/lib/commonjs/specs/NativeCardField.js +1 -1
- package/lib/commonjs/specs/NativeCardField.js.map +1 -1
- package/lib/commonjs/specs/NativeCardForm.js +1 -1
- package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
- package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
- package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
- package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/FinancialConnections.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/connect/Components.js +1 -1
- package/lib/module/connect/Components.js.map +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/module/connect/EmbeddedComponent.js +9 -4
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/connect/ModalCloseButton.js +1 -1
- package/lib/module/connect/ModalCloseButton.js.map +1 -1
- package/lib/module/connect/NavigationBar.js +1 -1
- package/lib/module/connect/NavigationBar.js.map +1 -1
- package/lib/module/helpers.js +1 -1
- package/lib/module/hooks/useOnramp.js +1 -1
- package/lib/module/hooks/useOnramp.js.map +1 -1
- package/lib/module/specs/NativeAddToWalletButton.js +1 -1
- package/lib/module/specs/NativeAddressSheet.js +1 -1
- package/lib/module/specs/NativeApplePayButton.js +1 -1
- package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
- package/lib/module/specs/NativeCardField.js +1 -1
- package/lib/module/specs/NativeCardField.js.map +1 -1
- package/lib/module/specs/NativeCardForm.js +1 -1
- package/lib/module/specs/NativeCardForm.js.map +1 -1
- package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
- package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
- package/lib/module/specs/NativeGooglePayButton.js +1 -1
- package/lib/module/specs/NativeNavigationBar.js +1 -1
- package/lib/module/specs/NativeStripeContainer.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/FinancialConnections.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/connect/Components.d.ts.map +1 -1
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
- package/lib/typescript/src/connect/connectTypes.d.ts +5 -1
- package/lib/typescript/src/connect/connectTypes.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useOnramp.d.ts +2 -1
- package/lib/typescript/src/hooks/useOnramp.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +6 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/FinancialConnections.d.ts +2 -0
- package/lib/typescript/src/types/FinancialConnections.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +30 -0
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/package.json +15 -5
- package/src/connect/Components.tsx +18 -11
- package/src/connect/EmbeddedComponent.tsx +223 -12
- package/src/connect/connectTypes.ts +5 -1
- package/src/hooks/useOnramp.tsx +5 -1
- package/src/types/EmbeddedPaymentElement.tsx +6 -1
- package/src/types/FinancialConnections.ts +2 -0
- package/src/types/PaymentSheet.ts +32 -0
- package/stripe-react-native.podspec +1 -1
- package/android/.idea/AndroidProjectSystem.xml +0 -6
- package/android/.idea/caches/deviceStreaming.xml +0 -1029
- package/android/.idea/compiler.xml +0 -6
- package/android/.idea/gradle.xml +0 -19
- package/android/.idea/migrations.xml +0 -10
- package/android/.idea/misc.xml +0 -10
- package/android/.idea/runConfigurations.xml +0 -17
- package/android/.idea/vcs.xml +0 -6
- package/android/local.properties +0 -8
- package/ios/StripeSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/StripeSdk.xcodeproj/project.xcworkspace/xcuserdata/tianzhao.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/StripeSdk.xcodeproj/xcuserdata/tianzhao.xcuserdatad/xcschemes/xcschememanagement.plist +0 -19
|
@@ -8,18 +8,24 @@ import React, {
|
|
|
8
8
|
import {
|
|
9
9
|
AppState,
|
|
10
10
|
AppStateStatus,
|
|
11
|
+
Linking,
|
|
11
12
|
Platform,
|
|
12
13
|
StyleProp,
|
|
13
14
|
ViewStyle,
|
|
14
15
|
} from 'react-native';
|
|
15
16
|
import type { WebView, WebViewMessageEvent } from 'react-native-webview';
|
|
17
|
+
import type { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes';
|
|
18
|
+
import type { EventSubscription } from 'react-native';
|
|
16
19
|
import pjson from '../../package.json';
|
|
17
20
|
import NativeStripeSdk from '../specs/NativeStripeSdkModule';
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
import { addListener } from '../events';
|
|
22
|
+
import { useConnectComponents } from './ConnectComponentsProvider';
|
|
23
|
+
import type {
|
|
24
|
+
LoadError,
|
|
25
|
+
LoaderStart,
|
|
26
|
+
StripeConnectInitParams,
|
|
27
|
+
} from './connectTypes';
|
|
28
|
+
import type { FinancialConnections } from '../types';
|
|
23
29
|
|
|
24
30
|
const DEVELOPMENT_MODE = false;
|
|
25
31
|
const DEVELOPMENT_URL =
|
|
@@ -36,12 +42,26 @@ if (!/^\d+\.\d+\.\d+$/.test(sdkVersion)) {
|
|
|
36
42
|
);
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
// Required for ua-parser-js to detect mobile platforms correctly
|
|
46
|
+
const platformPrefix = Platform.select({
|
|
47
|
+
ios: 'iPhone',
|
|
48
|
+
android: 'Android',
|
|
49
|
+
default: 'Mobile',
|
|
50
|
+
});
|
|
39
51
|
const userAgent = [
|
|
40
|
-
|
|
52
|
+
platformPrefix,
|
|
41
53
|
`Stripe ReactNative SDK ${Platform.OS}/${Platform.Version}`,
|
|
42
54
|
`stripe-react_native/${sdkVersion}`,
|
|
43
55
|
].join(' - ');
|
|
44
56
|
|
|
57
|
+
// Allowed domains for in-WebView navigation (matching iOS SDK behavior)
|
|
58
|
+
const ALLOWED_STRIPE_HOSTS = [
|
|
59
|
+
'connect-js.stripe.com',
|
|
60
|
+
'connect.stripe.com',
|
|
61
|
+
'verify.stripe.com',
|
|
62
|
+
...(DEVELOPMENT_MODE ? ['10.0.2.2:3001', 'localhost:3001'] : []),
|
|
63
|
+
];
|
|
64
|
+
|
|
45
65
|
export interface CommonComponentProps {
|
|
46
66
|
onLoaderStart?: ({ elementTagName }: LoaderStart) => void;
|
|
47
67
|
onLoadError?: ({ error, elementTagName }: LoadError) => void;
|
|
@@ -110,7 +130,7 @@ type EmbeddedComponentProps = CommonComponentProps & {
|
|
|
110
130
|
callbacks?: Record<string, ((data: any) => void) | undefined>;
|
|
111
131
|
};
|
|
112
132
|
|
|
113
|
-
type
|
|
133
|
+
type StripeConnectInitParamsInternal = StripeConnectInitParams & {
|
|
114
134
|
overrides?: Record<string, string>;
|
|
115
135
|
};
|
|
116
136
|
|
|
@@ -125,6 +145,12 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
125
145
|
callback: (id: string, url: string | null) => void;
|
|
126
146
|
} | null>(null);
|
|
127
147
|
|
|
148
|
+
// Store pending Financial Connections promise
|
|
149
|
+
const pendingFinancialConnectionsPromise = useRef<{
|
|
150
|
+
id: string;
|
|
151
|
+
cleanup: () => void;
|
|
152
|
+
} | null>(null);
|
|
153
|
+
|
|
128
154
|
const loadWebViewComponent = useCallback(async () => {
|
|
129
155
|
if (dynamicWebview) return;
|
|
130
156
|
|
|
@@ -162,14 +188,14 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
162
188
|
|
|
163
189
|
return () => {
|
|
164
190
|
pendingAuthWebViewPromise.current = null;
|
|
191
|
+
pendingFinancialConnectionsPromise.current?.cleanup();
|
|
165
192
|
subscription.remove();
|
|
166
193
|
};
|
|
167
194
|
}, []);
|
|
168
195
|
|
|
169
|
-
const { connectInstance, appearance, locale
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
connectInstance.initParams;
|
|
196
|
+
const { connectInstance, appearance, locale } = useConnectComponents();
|
|
197
|
+
const { fonts, publishableKey, fetchClientSecret, overrides } =
|
|
198
|
+
connectInstance.initParams as StripeConnectInitParamsInternal;
|
|
173
199
|
|
|
174
200
|
const {
|
|
175
201
|
component,
|
|
@@ -202,6 +228,7 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
202
228
|
const source = useMemo(() => ({ uri: connectURL }), [connectURL]);
|
|
203
229
|
|
|
204
230
|
const ref = useRef<WebView>(null);
|
|
231
|
+
const hasTriedSourceReload = useRef(false);
|
|
205
232
|
|
|
206
233
|
const [prevAppearance, setPrevAppearance] = useState(appearance);
|
|
207
234
|
const [prevLocale, setPrevLocale] = useState(locale);
|
|
@@ -244,6 +271,27 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
244
271
|
|
|
245
272
|
const WebViewComponent = dynamicWebview?.WebView;
|
|
246
273
|
|
|
274
|
+
// Workaround for react-native-webview new architecture bug on iOS
|
|
275
|
+
// https://github.com/react-native-webview/react-native-webview/pull/3880
|
|
276
|
+
// The source prop doesn't get set properly on iOS with new architecture,
|
|
277
|
+
// so we force reload after the component mounts
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
if (
|
|
280
|
+
Platform.OS === 'ios' &&
|
|
281
|
+
!hasTriedSourceReload.current &&
|
|
282
|
+
WebViewComponent &&
|
|
283
|
+
ref.current
|
|
284
|
+
) {
|
|
285
|
+
hasTriedSourceReload.current = true;
|
|
286
|
+
// Force reload after mount to ensure source is set
|
|
287
|
+
const timer = setTimeout(() => {
|
|
288
|
+
ref.current?.reload();
|
|
289
|
+
}, 100);
|
|
290
|
+
return () => clearTimeout(timer);
|
|
291
|
+
}
|
|
292
|
+
return undefined;
|
|
293
|
+
}, [WebViewComponent]);
|
|
294
|
+
|
|
247
295
|
const handleAuthWebViewResult = (id: string, resultUrl: string | null) => {
|
|
248
296
|
ref.current?.injectJavaScript(`
|
|
249
297
|
(function() {
|
|
@@ -256,6 +304,39 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
256
304
|
`);
|
|
257
305
|
};
|
|
258
306
|
|
|
307
|
+
const handleFinancialConnectionsResult = (
|
|
308
|
+
id: string,
|
|
309
|
+
result: {
|
|
310
|
+
session?: FinancialConnections.Session;
|
|
311
|
+
token?: FinancialConnections.BankAccountToken;
|
|
312
|
+
error?: {
|
|
313
|
+
code: string;
|
|
314
|
+
message: string;
|
|
315
|
+
localizedMessage?: string;
|
|
316
|
+
type?: string;
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
) => {
|
|
320
|
+
ref.current?.injectJavaScript(`
|
|
321
|
+
(function() {
|
|
322
|
+
window.callSetterWithSerializableValue(${JSON.stringify({
|
|
323
|
+
setter: 'setCollectMobileFinancialConnectionsResult',
|
|
324
|
+
value: {
|
|
325
|
+
id: id,
|
|
326
|
+
financialConnectionsSession: result.session
|
|
327
|
+
? {
|
|
328
|
+
accounts: result.session.accounts,
|
|
329
|
+
}
|
|
330
|
+
: null,
|
|
331
|
+
token: result.token ?? null,
|
|
332
|
+
error: result.error ?? null,
|
|
333
|
+
},
|
|
334
|
+
})});
|
|
335
|
+
true;
|
|
336
|
+
})();
|
|
337
|
+
`);
|
|
338
|
+
};
|
|
339
|
+
|
|
259
340
|
const onMessageCallback = useCallback(
|
|
260
341
|
async (event: WebViewMessageEvent) => {
|
|
261
342
|
const message = JSON.parse(event.nativeEvent.data) as {
|
|
@@ -283,7 +364,111 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
283
364
|
} else if (message.type === 'accountSessionClaimed') {
|
|
284
365
|
// message.data is of type {elementTagName: string, merchantId: string}
|
|
285
366
|
} else if (message.type === 'openFinancialConnections') {
|
|
286
|
-
|
|
367
|
+
const messageData = message.data as {
|
|
368
|
+
clientSecret: string;
|
|
369
|
+
id: string;
|
|
370
|
+
connectedAccountId: string;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
const { clientSecret, id, connectedAccountId } = messageData;
|
|
374
|
+
|
|
375
|
+
// Validate client secret
|
|
376
|
+
if (!clientSecret || typeof clientSecret !== 'string') {
|
|
377
|
+
handleFinancialConnectionsResult(id, {
|
|
378
|
+
error: {
|
|
379
|
+
code: 'InvalidClientSecret',
|
|
380
|
+
message: 'Invalid or missing clientSecret parameter',
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Prevent multiple simultaneous flows
|
|
387
|
+
if (pendingFinancialConnectionsPromise.current) {
|
|
388
|
+
handleFinancialConnectionsResult(id, {
|
|
389
|
+
error: {
|
|
390
|
+
code: 'AlreadyInProgress',
|
|
391
|
+
message: 'Financial Connections flow already in progress',
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Setup event listener for debugging
|
|
398
|
+
let eventListener: EventSubscription | null = null;
|
|
399
|
+
if (__DEV__) {
|
|
400
|
+
eventListener = addListener(
|
|
401
|
+
'onFinancialConnectionsEvent',
|
|
402
|
+
(fcEvent: FinancialConnections.FinancialConnectionsEvent) => {
|
|
403
|
+
console.debug(
|
|
404
|
+
`[FinancialConnections ${component}]: ${fcEvent.name}`,
|
|
405
|
+
fcEvent.metadata
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Store cleanup function
|
|
412
|
+
const cleanup = () => {
|
|
413
|
+
eventListener?.remove();
|
|
414
|
+
pendingFinancialConnectionsPromise.current = null;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
pendingFinancialConnectionsPromise.current = {
|
|
418
|
+
id,
|
|
419
|
+
cleanup,
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// Call native Financial Connections
|
|
423
|
+
NativeStripeSdk.collectFinancialConnectionsAccounts(clientSecret, {
|
|
424
|
+
connectedAccountId,
|
|
425
|
+
})
|
|
426
|
+
.then(({ session, error }) => {
|
|
427
|
+
cleanup();
|
|
428
|
+
|
|
429
|
+
if (error) {
|
|
430
|
+
handleFinancialConnectionsResult(id, {
|
|
431
|
+
session: undefined,
|
|
432
|
+
token: undefined,
|
|
433
|
+
error: {
|
|
434
|
+
code: error.code,
|
|
435
|
+
message: error.message,
|
|
436
|
+
localizedMessage: error.localizedMessage,
|
|
437
|
+
type: error.type,
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
} else if (session) {
|
|
441
|
+
// Note: collectFinancialConnectionsAccounts doesn't return a token
|
|
442
|
+
// Only collectBankAccountToken returns both session and token
|
|
443
|
+
handleFinancialConnectionsResult(id, {
|
|
444
|
+
session,
|
|
445
|
+
token: undefined,
|
|
446
|
+
error: undefined,
|
|
447
|
+
});
|
|
448
|
+
} else {
|
|
449
|
+
// Defensive: should never happen
|
|
450
|
+
handleFinancialConnectionsResult(id, {
|
|
451
|
+
error: {
|
|
452
|
+
code: 'UnexpectedError',
|
|
453
|
+
message:
|
|
454
|
+
'No session or error returned from Financial Connections',
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
})
|
|
459
|
+
.catch((unexpectedError) => {
|
|
460
|
+
cleanup();
|
|
461
|
+
handleUnexpectedError(unexpectedError);
|
|
462
|
+
handleFinancialConnectionsResult(id, {
|
|
463
|
+
error: {
|
|
464
|
+
code: 'UnexpectedError',
|
|
465
|
+
message:
|
|
466
|
+
unexpectedError instanceof Error
|
|
467
|
+
? unexpectedError.message
|
|
468
|
+
: 'An unexpected error occurred during Financial Connections',
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
});
|
|
287
472
|
} else if (message.type === 'closeWebView') {
|
|
288
473
|
// message.data is empty
|
|
289
474
|
callbacks?.onCloseWebView?.({});
|
|
@@ -347,6 +532,27 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
347
532
|
]
|
|
348
533
|
);
|
|
349
534
|
|
|
535
|
+
const onShouldStartLoadWithRequest = useCallback(
|
|
536
|
+
(event: ShouldStartLoadRequest) => {
|
|
537
|
+
const { url } = event;
|
|
538
|
+
|
|
539
|
+
// Allow navigation within allowed Stripe domains (matching iOS SDK behavior)
|
|
540
|
+
if (ALLOWED_STRIPE_HOSTS.some((host) => url.includes(host))) {
|
|
541
|
+
return true; // Allow in-WebView navigation
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Validate and open external links in system browser
|
|
545
|
+
if (isValidUrl(url)) {
|
|
546
|
+
Linking.openURL(url).catch((error) => {
|
|
547
|
+
handleUnexpectedError(error);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return false; // Block in-WebView navigation for external links
|
|
552
|
+
},
|
|
553
|
+
[handleUnexpectedError]
|
|
554
|
+
);
|
|
555
|
+
|
|
350
556
|
const backgroundColor = appearance?.variables?.colorBackground || '#FFFFFF';
|
|
351
557
|
|
|
352
558
|
const mergedStyle = useMemo(
|
|
@@ -375,6 +581,11 @@ export function EmbeddedComponent(props: EmbeddedComponentProps) {
|
|
|
375
581
|
// Fixes injectedJavaScriptObject in Android https://github.com/react-native-webview/react-native-webview/issues/3326#issuecomment-3048111789
|
|
376
582
|
injectedJavaScriptBeforeContentLoaded={'(function() {})();'}
|
|
377
583
|
onMessage={onMessageCallback}
|
|
584
|
+
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
|
585
|
+
// Camera/Media Permissions - matches iOS SDK behavior
|
|
586
|
+
mediaCapturePermissionGrantType="grantIfSameHostElsePrompt"
|
|
587
|
+
allowsInlineMediaPlayback={true}
|
|
588
|
+
mediaPlaybackRequiresUserAction={false}
|
|
378
589
|
/>
|
|
379
590
|
);
|
|
380
591
|
}
|
|
@@ -42,7 +42,11 @@ export type EmbeddedErrorType =
|
|
|
42
42
|
/**
|
|
43
43
|
* API errors covering any other type of problem (e.g., a temporary problem with Stripe's servers), and are extremely uncommon.
|
|
44
44
|
*/
|
|
45
|
-
| 'api_error'
|
|
45
|
+
| 'api_error'
|
|
46
|
+
/**
|
|
47
|
+
* Failure to render the component, typically caused by browser extensions or network issues
|
|
48
|
+
*/
|
|
49
|
+
| 'render_error';
|
|
46
50
|
|
|
47
51
|
export type Status =
|
|
48
52
|
| 'blocked'
|
package/src/hooks/useOnramp.tsx
CHANGED
|
@@ -174,8 +174,11 @@ export function useOnramp() {
|
|
|
174
174
|
return NativeOnrampSdk.logout();
|
|
175
175
|
}, []);
|
|
176
176
|
|
|
177
|
-
const _isAuthError = (error
|
|
177
|
+
const _isAuthError = (error?: StripeError<OnrampError>): boolean => {
|
|
178
178
|
const stripeErrorCode = error?.stripeErrorCode;
|
|
179
|
+
if (stripeErrorCode == null) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
179
182
|
const authErrorCodes = [
|
|
180
183
|
'consumer_session_credentials_invalid',
|
|
181
184
|
'consumer_session_expired',
|
|
@@ -294,6 +297,7 @@ export function useOnramp() {
|
|
|
294
297
|
* Performs the checkout flow for a crypto onramp session, handling any required authentication steps.
|
|
295
298
|
*
|
|
296
299
|
* @param onrampSessionId The onramp session identifier
|
|
300
|
+
* @param provideCheckoutClientSecret A callback that asynchronously provides the checkout client secret when requested during the checkout flow. Pass `null` to resolve with an error in the event that a client secret is unavailable.
|
|
297
301
|
* @returns Promise that resolves to an object with an optional error property
|
|
298
302
|
*/
|
|
299
303
|
performCheckout: _performCheckout,
|
|
@@ -195,7 +195,12 @@ export interface EmbeddedPaymentElementConfiguration {
|
|
|
195
195
|
* Note: Card brand filtering is not currently supported in Link.
|
|
196
196
|
*/
|
|
197
197
|
cardBrandAcceptance?: PaymentSheetTypes.CardBrandAcceptance;
|
|
198
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* Configuration for filtering cards by funding type.
|
|
200
|
+
* @note This is a private preview API and will have no effect unless your Stripe account is enrolled in the private preview.
|
|
201
|
+
*/
|
|
202
|
+
cardFundingFiltering?: PaymentSheetTypes.CardFundingFiltering;
|
|
203
|
+
/** The view can display payment methods like "Card" that, when tapped, open a sheet where customers enter their payment method details.
|
|
199
204
|
* The sheet has a button at the bottom. `formSheetAction` controls the action the button performs. Defaults to 'continue'.
|
|
200
205
|
*/
|
|
201
206
|
formSheetAction?: EmbeddedFormSheetAction;
|
|
@@ -7,6 +7,8 @@ export type CollectFinancialConnectionsAccountsParams = {
|
|
|
7
7
|
style?: UserInterfaceStyle;
|
|
8
8
|
/** An optional event listener to receive @type {FinancialConnectionEvent} for specific events during the process of a user connecting their financial accounts. */
|
|
9
9
|
onEvent?: (event: FinancialConnectionsEvent) => void;
|
|
10
|
+
/** Optional connected account ID to use for this Financial Connections session. Used for Stripe Connect embedded components. */
|
|
11
|
+
connectedAccountId?: string;
|
|
10
12
|
};
|
|
11
13
|
|
|
12
14
|
export type SessionResult =
|
|
@@ -85,6 +85,11 @@ export type SetupParamsBase = IntentParams & {
|
|
|
85
85
|
* Note: Card brand filtering is not currently supported in Link.
|
|
86
86
|
*/
|
|
87
87
|
cardBrandAcceptance?: CardBrandAcceptance;
|
|
88
|
+
/**
|
|
89
|
+
* Configuration for filtering cards by funding type.
|
|
90
|
+
* @note This is a private preview API and will have no effect unless your Stripe account is enrolled in the private preview.
|
|
91
|
+
*/
|
|
92
|
+
cardFundingFiltering?: CardFundingFiltering;
|
|
88
93
|
/** Configuration for custom payment methods in PaymentSheet */
|
|
89
94
|
customPaymentMethodConfiguration?: CustomPaymentMethodConfiguration;
|
|
90
95
|
};
|
|
@@ -680,6 +685,33 @@ export enum PaymentMethodLayout {
|
|
|
680
685
|
Automatic = 'Automatic',
|
|
681
686
|
}
|
|
682
687
|
|
|
688
|
+
/**
|
|
689
|
+
* Card funding types that can be filtered.
|
|
690
|
+
* @note This is a private preview API and will have no effect unless your Stripe account is enrolled in the private preview.
|
|
691
|
+
*/
|
|
692
|
+
export enum CardFundingType {
|
|
693
|
+
/** Debit cards */
|
|
694
|
+
Debit = 'debit',
|
|
695
|
+
/** Credit cards */
|
|
696
|
+
Credit = 'credit',
|
|
697
|
+
/** Prepaid cards */
|
|
698
|
+
Prepaid = 'prepaid',
|
|
699
|
+
/**
|
|
700
|
+
* Unknown or undetermined funding type.
|
|
701
|
+
* Include this if you want to accept cards where the funding type cannot be determined from card metadata.
|
|
702
|
+
*/
|
|
703
|
+
Unknown = 'unknown',
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Configuration for filtering cards by funding type.
|
|
708
|
+
* @note This is a private preview API and will have no effect unless your Stripe account is enrolled in the private preview.
|
|
709
|
+
*/
|
|
710
|
+
export type CardFundingFiltering = {
|
|
711
|
+
/** List of allowed card funding types. If not set, all types are accepted. */
|
|
712
|
+
allowedCardFundingTypes?: CardFundingType[];
|
|
713
|
+
};
|
|
714
|
+
|
|
683
715
|
/** Card brand categories that can be allowed or disallowed */
|
|
684
716
|
export enum CardBrandCategory {
|
|
685
717
|
/** Visa branded cards */
|
|
@@ -2,7 +2,7 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
4
|
# Keep stripe_version in sync with https://github.com/stripe/stripe-identity-react-native/blob/main/stripe-identity-react-native.podspec
|
|
5
|
-
stripe_version = '~> 25.0
|
|
5
|
+
stripe_version = '~> 25.6.0'
|
|
6
6
|
|
|
7
7
|
fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
|
|
8
8
|
|