@stripe/stripe-react-native 0.58.0 → 0.59.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 +2 -0
- package/android/src/main/AndroidManifest.xml +27 -1
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +2 -0
- package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +147 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementView.kt +164 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +65 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +1 -1
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +55 -26
- package/android/src/main/java/com/reactnativestripesdk/StripeConnectDeepLinkInterceptorActivity.kt +77 -0
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +325 -22
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
- package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +3 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +8 -0
- package/android/src/main/res/xml/file_paths.xml +4 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerDelegate.java +36 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerInterface.java +18 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +20 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentElementConfigTest.kt +37 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt +543 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentSheetManagerTest.kt +70 -0
- package/ios/CustomerSheet/CustomerSheetUtils.swift +4 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.m +13 -1
- package/ios/PaymentMethodMessagingElementConfig.swift +116 -0
- package/ios/PaymentMethodMessagingElementHandler.m +9 -0
- package/ios/PaymentMethodMessagingElementView.swift +139 -0
- package/ios/StripeSdk.mm +40 -0
- package/ios/StripeSdkEmitter.swift +2 -0
- package/ios/StripeSdkImpl+CustomerSheet.swift +1 -0
- package/ios/StripeSdkImpl+Embedded.swift +4 -0
- package/ios/StripeSdkImpl+PaymentSheet.swift +16 -0
- package/ios/StripeSdkImpl.swift +132 -0
- package/jest/mock.js +20 -0
- 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 +5 -5
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/connect/analytics/AnalyticsClient.js +2 -0
- package/lib/commonjs/connect/analytics/AnalyticsClient.js.map +1 -0
- package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js +2 -0
- package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
- package/lib/commonjs/connect/analytics/events.js +2 -0
- package/lib/commonjs/connect/analytics/events.js.map +1 -0
- package/lib/commonjs/connect/testUtils.js +2 -0
- package/lib/commonjs/connect/testUtils.js.map +1 -0
- 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/hooks/useStripe.js +1 -1
- package/lib/commonjs/hooks/useStripe.js.map +1 -1
- package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +2 -0
- package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js.map +1 -0
- package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/Errors.js +1 -1
- package/lib/commonjs/types/Errors.js.map +1 -1
- package/lib/commonjs/types/PaymentSheet.js.map +1 -1
- package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js +2 -0
- package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
- package/lib/commonjs/types/index.js.map +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 +5 -5
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/connect/analytics/AnalyticsClient.js +2 -0
- package/lib/module/connect/analytics/AnalyticsClient.js.map +1 -0
- package/lib/module/connect/analytics/ComponentAnalyticsClient.js +2 -0
- package/lib/module/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
- package/lib/module/connect/analytics/events.js +2 -0
- package/lib/module/connect/analytics/events.js.map +1 -0
- package/lib/module/connect/testUtils.js +2 -0
- package/lib/module/connect/testUtils.js.map +1 -0
- 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/hooks/useStripe.js +1 -1
- package/lib/module/hooks/useStripe.js.map +1 -1
- package/lib/module/specs/NativePaymentMethodMessagingElement.js +2 -0
- package/lib/module/specs/NativePaymentMethodMessagingElement.js.map +1 -0
- package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/Errors.js +1 -1
- package/lib/module/types/Errors.js.map +1 -1
- package/lib/module/types/PaymentSheet.js.map +1 -1
- package/lib/module/types/components/PaymentMethodMessagingElementComponent.js +2 -0
- package/lib/module/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
- package/lib/module/types/index.js.map +1 -1
- package/lib/typescript/src/connect/Components.d.ts +91 -0
- package/lib/typescript/src/connect/Components.d.ts.map +1 -1
- package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts +61 -0
- package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts.map +1 -1
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
- package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts +32 -0
- package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts.map +1 -0
- package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts +94 -0
- package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts.map +1 -0
- package/lib/typescript/src/connect/analytics/events.d.ts +215 -0
- package/lib/typescript/src/connect/analytics/events.d.ts.map +1 -0
- package/lib/typescript/src/connect/testUtils.d.ts +45 -0
- package/lib/typescript/src/connect/testUtils.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +2 -0
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/functions.d.ts +13 -1
- package/lib/typescript/src/functions.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useStripe.d.ts +2 -1
- package/lib/typescript/src/hooks/useStripe.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts +16 -0
- package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +16 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/CustomerSheet.d.ts +5 -0
- package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +5 -0
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/Errors.d.ts +4 -0
- package/lib/typescript/src/types/Errors.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +5 -0
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts +69 -0
- package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +8 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/connect/Components.tsx +91 -0
- package/src/connect/ConnectComponentsProvider.tsx +69 -2
- package/src/connect/EmbeddedComponent.tsx +254 -30
- package/src/connect/analytics/AnalyticsClient.ts +75 -0
- package/src/connect/analytics/ComponentAnalyticsClient.ts +315 -0
- package/src/connect/analytics/events.ts +253 -0
- package/src/connect/testUtils.ts +37 -0
- package/src/events.ts +2 -0
- package/src/functions.ts +10 -0
- package/src/hooks/useStripe.tsx +8 -0
- package/src/specs/NativePaymentMethodMessagingElement.ts +25 -0
- package/src/specs/NativeStripeSdkModule.ts +21 -1
- package/src/types/CustomerSheet.ts +5 -0
- package/src/types/EmbeddedPaymentElement.tsx +5 -0
- package/src/types/Errors.ts +5 -0
- package/src/types/PaymentSheet.ts +6 -1
- package/src/types/components/PaymentMethodMessagingElementComponent.tsx +74 -0
- package/src/types/index.ts +11 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Analytics Client for tracking Connect component events
|
|
3
|
+
* Matches the Swift iOS SDK's ComponentAnalyticsClient implementation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AnalyticsClient } from './AnalyticsClient';
|
|
7
|
+
import {
|
|
8
|
+
EVENT_NAMES,
|
|
9
|
+
type AnalyticsPayload,
|
|
10
|
+
type CommonAnalyticsFields,
|
|
11
|
+
type ConnectAnalyticsEvent,
|
|
12
|
+
} from './events';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for ComponentAnalyticsClient
|
|
16
|
+
*/
|
|
17
|
+
export interface ComponentAnalyticsConfig {
|
|
18
|
+
publishableKey?: string;
|
|
19
|
+
platformId?: string;
|
|
20
|
+
merchantId?: string;
|
|
21
|
+
livemode?: boolean;
|
|
22
|
+
component: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generates a UUID v4
|
|
27
|
+
*/
|
|
28
|
+
function generateUUID(): string {
|
|
29
|
+
/* eslint-disable no-bitwise */
|
|
30
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
31
|
+
const r = (Math.random() * 16) | 0;
|
|
32
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
33
|
+
return v.toString(16);
|
|
34
|
+
});
|
|
35
|
+
/* eslint-enable no-bitwise */
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Component Analytics Client for tracking lifecycle, web view, and error events
|
|
40
|
+
*/
|
|
41
|
+
export class ComponentAnalyticsClient {
|
|
42
|
+
private analyticsClient: AnalyticsClient;
|
|
43
|
+
private config: ComponentAnalyticsConfig;
|
|
44
|
+
private componentInstance: string;
|
|
45
|
+
private pageViewId?: string;
|
|
46
|
+
private loadStart: number;
|
|
47
|
+
private componentFirstViewedTime?: number;
|
|
48
|
+
private loggedPageLoaded: boolean = false;
|
|
49
|
+
private loggedComponentLoaded: boolean = false;
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
analyticsClient: AnalyticsClient,
|
|
53
|
+
config: ComponentAnalyticsConfig
|
|
54
|
+
) {
|
|
55
|
+
this.analyticsClient = analyticsClient;
|
|
56
|
+
this.config = config;
|
|
57
|
+
this.componentInstance = generateUUID();
|
|
58
|
+
this.loadStart = Date.now();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Build common fields for all events
|
|
63
|
+
*/
|
|
64
|
+
private buildCommonFields(): CommonAnalyticsFields {
|
|
65
|
+
return {
|
|
66
|
+
event_id: generateUUID(),
|
|
67
|
+
created: Date.now(),
|
|
68
|
+
client_id: 'mobile_connect_sdk',
|
|
69
|
+
origin: 'stripe-connect-react-native',
|
|
70
|
+
sdk_platform: 'ios' as 'ios' | 'android',
|
|
71
|
+
sdk_version: '',
|
|
72
|
+
os_version: '',
|
|
73
|
+
device_type: '',
|
|
74
|
+
app_name: '',
|
|
75
|
+
app_version: '',
|
|
76
|
+
publishable_key: this.config.publishableKey,
|
|
77
|
+
platform_id: this.config.platformId,
|
|
78
|
+
merchant_id: this.config.merchantId,
|
|
79
|
+
livemode: this.config.livemode,
|
|
80
|
+
component: this.config.component,
|
|
81
|
+
component_instance: this.componentInstance,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Send an analytics event
|
|
87
|
+
*/
|
|
88
|
+
private async log(event: ConnectAnalyticsEvent): Promise<void> {
|
|
89
|
+
const payload: AnalyticsPayload = {
|
|
90
|
+
...this.buildCommonFields(),
|
|
91
|
+
...event,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
await this.analyticsClient.sendEvent(payload);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Log component created event
|
|
99
|
+
*/
|
|
100
|
+
logComponentCreated(): void {
|
|
101
|
+
this.log({
|
|
102
|
+
event_name: EVENT_NAMES.COMPONENT_CREATED,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Log component viewed event (first time component becomes visible)
|
|
108
|
+
*/
|
|
109
|
+
logComponentViewed(): void {
|
|
110
|
+
if (this.componentFirstViewedTime) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.componentFirstViewedTime = Date.now();
|
|
115
|
+
this.log({
|
|
116
|
+
event_name: EVENT_NAMES.COMPONENT_VIEWED,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Log web page loaded event
|
|
122
|
+
*/
|
|
123
|
+
logComponentWebPageLoaded(pageViewId?: string): void {
|
|
124
|
+
if (this.loggedPageLoaded) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
this.loggedPageLoaded = true;
|
|
129
|
+
if (pageViewId) {
|
|
130
|
+
this.pageViewId = pageViewId;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const timeToLoad = (Date.now() - this.loadStart) / 1000;
|
|
134
|
+
|
|
135
|
+
this.log({
|
|
136
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_PAGE_LOADED,
|
|
137
|
+
event_metadata: {
|
|
138
|
+
time_to_load: timeToLoad,
|
|
139
|
+
},
|
|
140
|
+
time_to_load: timeToLoad,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Log component loaded event (Connect JS fully initialized)
|
|
146
|
+
*/
|
|
147
|
+
logComponentLoaded(): void {
|
|
148
|
+
if (this.loggedComponentLoaded) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.loggedComponentLoaded = true;
|
|
153
|
+
|
|
154
|
+
const timeToLoad = (Date.now() - this.loadStart) / 1000;
|
|
155
|
+
const perceivedTimeToLoad = this.componentFirstViewedTime
|
|
156
|
+
? (Date.now() - this.componentFirstViewedTime) / 1000
|
|
157
|
+
: undefined;
|
|
158
|
+
|
|
159
|
+
this.log({
|
|
160
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_COMPONENT_LOADED,
|
|
161
|
+
event_metadata: {
|
|
162
|
+
page_view_id: this.pageViewId,
|
|
163
|
+
time_to_load: timeToLoad,
|
|
164
|
+
perceived_time_to_load: perceivedTimeToLoad,
|
|
165
|
+
},
|
|
166
|
+
page_view_id: this.pageViewId,
|
|
167
|
+
time_to_load: timeToLoad,
|
|
168
|
+
perceived_time_to_load: perceivedTimeToLoad,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Log page load error
|
|
174
|
+
*/
|
|
175
|
+
logPageLoadError(error: Error, url?: string): void {
|
|
176
|
+
this.log({
|
|
177
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_ERROR_PAGE_LOAD,
|
|
178
|
+
event_metadata: {
|
|
179
|
+
error_message: error.message,
|
|
180
|
+
error_domain: error.name,
|
|
181
|
+
url,
|
|
182
|
+
},
|
|
183
|
+
error_message: error.message,
|
|
184
|
+
error_domain: error.name,
|
|
185
|
+
url,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Log unexpected navigation error
|
|
191
|
+
*/
|
|
192
|
+
logUnexpectedNavigation(url?: string): void {
|
|
193
|
+
this.log({
|
|
194
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_ERROR_UNEXPECTED_NAVIGATION,
|
|
195
|
+
event_metadata: {
|
|
196
|
+
url,
|
|
197
|
+
},
|
|
198
|
+
url,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Log unexpected load error type
|
|
204
|
+
*/
|
|
205
|
+
logUnexpectedLoadErrorType(errorType: string): void {
|
|
206
|
+
this.log({
|
|
207
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_ERROR_UNEXPECTED_LOAD_ERROR_TYPE,
|
|
208
|
+
event_metadata: {
|
|
209
|
+
error_type: errorType,
|
|
210
|
+
},
|
|
211
|
+
error_type: errorType,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Log unrecognized setter function warning
|
|
217
|
+
*/
|
|
218
|
+
logUnrecognizedSetter(setterName: string): void {
|
|
219
|
+
this.log({
|
|
220
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_WARN_UNRECOGNIZED_SETTER,
|
|
221
|
+
event_metadata: {
|
|
222
|
+
setter_name: setterName,
|
|
223
|
+
},
|
|
224
|
+
setter_name: setterName,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Log message deserialization error
|
|
230
|
+
*/
|
|
231
|
+
logDeserializeMessageError(messageName: string, error: Error): void {
|
|
232
|
+
this.log({
|
|
233
|
+
event_name: EVENT_NAMES.COMPONENT_WEB_ERROR_DESERIALIZE_MESSAGE,
|
|
234
|
+
event_metadata: {
|
|
235
|
+
message_name: messageName,
|
|
236
|
+
error_message: error.message,
|
|
237
|
+
},
|
|
238
|
+
message_name: messageName,
|
|
239
|
+
error_message: error.message,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Log authenticated web view opened
|
|
245
|
+
*/
|
|
246
|
+
logAuthenticatedWebViewOpened(id: string): void {
|
|
247
|
+
this.log({
|
|
248
|
+
event_name: EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_OPENED,
|
|
249
|
+
event_metadata: {
|
|
250
|
+
id,
|
|
251
|
+
},
|
|
252
|
+
id,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Log authenticated web view canceled
|
|
258
|
+
*/
|
|
259
|
+
logAuthenticatedWebViewCanceled(id: string): void {
|
|
260
|
+
this.log({
|
|
261
|
+
event_name: EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_CANCELED,
|
|
262
|
+
event_metadata: {
|
|
263
|
+
id,
|
|
264
|
+
},
|
|
265
|
+
id,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Log authenticated web view redirected
|
|
271
|
+
*/
|
|
272
|
+
logAuthenticatedWebViewRedirected(id: string): void {
|
|
273
|
+
this.log({
|
|
274
|
+
event_name: EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_REDIRECTED,
|
|
275
|
+
event_metadata: {
|
|
276
|
+
id,
|
|
277
|
+
},
|
|
278
|
+
id,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Log authenticated web view error
|
|
284
|
+
*/
|
|
285
|
+
logAuthenticatedWebViewError(id: string, error: Error): void {
|
|
286
|
+
this.log({
|
|
287
|
+
event_name: EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_ERROR,
|
|
288
|
+
event_metadata: {
|
|
289
|
+
id,
|
|
290
|
+
error_message: error.message,
|
|
291
|
+
},
|
|
292
|
+
id,
|
|
293
|
+
error_message: error.message,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Log client error (catch-all for mobile client errors)
|
|
299
|
+
*/
|
|
300
|
+
logClientError(error: Error, file?: string, line?: number): void {
|
|
301
|
+
this.log({
|
|
302
|
+
event_name: EVENT_NAMES.CLIENT_ERROR,
|
|
303
|
+
event_metadata: {
|
|
304
|
+
error_message: error.message,
|
|
305
|
+
error_domain: error.name,
|
|
306
|
+
file,
|
|
307
|
+
line,
|
|
308
|
+
},
|
|
309
|
+
error_message: error.message,
|
|
310
|
+
error_domain: error.name,
|
|
311
|
+
file,
|
|
312
|
+
line,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics event types for Connect components
|
|
3
|
+
* Matches the Swift iOS SDK implementation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Event names matching Swift SDK
|
|
8
|
+
*/
|
|
9
|
+
export const EVENT_NAMES = {
|
|
10
|
+
COMPONENT_CREATED: 'component.created',
|
|
11
|
+
COMPONENT_VIEWED: 'component.viewed',
|
|
12
|
+
COMPONENT_WEB_PAGE_LOADED: 'component.web.page_loaded',
|
|
13
|
+
COMPONENT_WEB_COMPONENT_LOADED: 'component.web.component_loaded',
|
|
14
|
+
COMPONENT_WEB_ERROR_PAGE_LOAD: 'component.web.error.page_load',
|
|
15
|
+
COMPONENT_WEB_ERROR_UNEXPECTED_NAVIGATION:
|
|
16
|
+
'component.web.error.unexpected_navigation',
|
|
17
|
+
COMPONENT_WEB_ERROR_UNEXPECTED_LOAD_ERROR_TYPE:
|
|
18
|
+
'component.web.error.unexpected_load_error_type',
|
|
19
|
+
COMPONENT_WEB_WARN_UNRECOGNIZED_SETTER:
|
|
20
|
+
'component.web.warn.unrecognized_setter_function',
|
|
21
|
+
COMPONENT_WEB_ERROR_DESERIALIZE_MESSAGE:
|
|
22
|
+
'component.web.error.deserialize_message',
|
|
23
|
+
COMPONENT_AUTHENTICATED_WEB_OPENED: 'component.authenticated_web.opened',
|
|
24
|
+
COMPONENT_AUTHENTICATED_WEB_CANCELED: 'component.authenticated_web.canceled',
|
|
25
|
+
COMPONENT_AUTHENTICATED_WEB_REDIRECTED:
|
|
26
|
+
'component.authenticated_web.redirected',
|
|
27
|
+
COMPONENT_AUTHENTICATED_WEB_ERROR: 'component.authenticated_web.error',
|
|
28
|
+
CLIENT_ERROR: 'client_error',
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Common fields included in all analytics events
|
|
33
|
+
*/
|
|
34
|
+
export interface CommonAnalyticsFields {
|
|
35
|
+
event_id: string;
|
|
36
|
+
created: number;
|
|
37
|
+
client_id: string;
|
|
38
|
+
origin: string;
|
|
39
|
+
sdk_platform: 'ios' | 'android';
|
|
40
|
+
sdk_version: string;
|
|
41
|
+
os_version: string;
|
|
42
|
+
device_type: string;
|
|
43
|
+
app_name: string;
|
|
44
|
+
app_version: string;
|
|
45
|
+
publishable_key?: string;
|
|
46
|
+
platform_id?: string;
|
|
47
|
+
merchant_id?: string;
|
|
48
|
+
livemode?: boolean;
|
|
49
|
+
component: string;
|
|
50
|
+
component_instance: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Base analytics event structure
|
|
55
|
+
*/
|
|
56
|
+
export interface AnalyticsEvent {
|
|
57
|
+
event_name: string;
|
|
58
|
+
event_metadata?: Record<string, any>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Component created event
|
|
63
|
+
*/
|
|
64
|
+
export interface ComponentCreatedEvent extends AnalyticsEvent {
|
|
65
|
+
event_name: typeof EVENT_NAMES.COMPONENT_CREATED;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Component viewed event (first time component becomes visible)
|
|
70
|
+
*/
|
|
71
|
+
export interface ComponentViewedEvent extends AnalyticsEvent {
|
|
72
|
+
event_name: typeof EVENT_NAMES.COMPONENT_VIEWED;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Web page loaded event (HTML page finished loading)
|
|
77
|
+
*/
|
|
78
|
+
export interface ComponentWebPageLoadedEvent extends AnalyticsEvent {
|
|
79
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_PAGE_LOADED;
|
|
80
|
+
event_metadata: {
|
|
81
|
+
time_to_load: number;
|
|
82
|
+
};
|
|
83
|
+
time_to_load: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Component loaded event (Connect JS fully initialized)
|
|
88
|
+
*/
|
|
89
|
+
export interface ComponentWebComponentLoadedEvent extends AnalyticsEvent {
|
|
90
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_COMPONENT_LOADED;
|
|
91
|
+
event_metadata: {
|
|
92
|
+
page_view_id?: string;
|
|
93
|
+
time_to_load: number;
|
|
94
|
+
perceived_time_to_load?: number;
|
|
95
|
+
};
|
|
96
|
+
page_view_id?: string;
|
|
97
|
+
time_to_load: number;
|
|
98
|
+
perceived_time_to_load?: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Page load error event
|
|
103
|
+
*/
|
|
104
|
+
export interface PageLoadErrorEvent extends AnalyticsEvent {
|
|
105
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_ERROR_PAGE_LOAD;
|
|
106
|
+
event_metadata: {
|
|
107
|
+
error_message: string;
|
|
108
|
+
error_domain?: string;
|
|
109
|
+
error_code?: string;
|
|
110
|
+
url?: string;
|
|
111
|
+
};
|
|
112
|
+
error_message: string;
|
|
113
|
+
error_domain?: string;
|
|
114
|
+
error_code?: string;
|
|
115
|
+
url?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Unexpected navigation error event
|
|
120
|
+
*/
|
|
121
|
+
export interface UnexpectedNavigationEvent extends AnalyticsEvent {
|
|
122
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_ERROR_UNEXPECTED_NAVIGATION;
|
|
123
|
+
event_metadata: {
|
|
124
|
+
url?: string;
|
|
125
|
+
};
|
|
126
|
+
url?: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Unexpected load error type event
|
|
131
|
+
*/
|
|
132
|
+
export interface UnexpectedLoadErrorTypeEvent extends AnalyticsEvent {
|
|
133
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_ERROR_UNEXPECTED_LOAD_ERROR_TYPE;
|
|
134
|
+
event_metadata: {
|
|
135
|
+
error_type: string;
|
|
136
|
+
};
|
|
137
|
+
error_type: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Unrecognized setter function warning event
|
|
142
|
+
*/
|
|
143
|
+
export interface UnrecognizedSetterEvent extends AnalyticsEvent {
|
|
144
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_WARN_UNRECOGNIZED_SETTER;
|
|
145
|
+
event_metadata: {
|
|
146
|
+
setter_name: string;
|
|
147
|
+
};
|
|
148
|
+
setter_name: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Message deserialization error event
|
|
153
|
+
*/
|
|
154
|
+
export interface DeserializeMessageErrorEvent extends AnalyticsEvent {
|
|
155
|
+
event_name: typeof EVENT_NAMES.COMPONENT_WEB_ERROR_DESERIALIZE_MESSAGE;
|
|
156
|
+
event_metadata: {
|
|
157
|
+
message_name: string;
|
|
158
|
+
error_message: string;
|
|
159
|
+
};
|
|
160
|
+
message_name: string;
|
|
161
|
+
error_message: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Authenticated web view opened event
|
|
166
|
+
*/
|
|
167
|
+
export interface AuthenticatedWebViewOpenedEvent extends AnalyticsEvent {
|
|
168
|
+
event_name: typeof EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_OPENED;
|
|
169
|
+
event_metadata: {
|
|
170
|
+
id: string;
|
|
171
|
+
};
|
|
172
|
+
id: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Authenticated web view canceled event
|
|
177
|
+
*/
|
|
178
|
+
export interface AuthenticatedWebViewCanceledEvent extends AnalyticsEvent {
|
|
179
|
+
event_name: typeof EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_CANCELED;
|
|
180
|
+
event_metadata: {
|
|
181
|
+
id: string;
|
|
182
|
+
};
|
|
183
|
+
id: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Authenticated web view redirected event
|
|
188
|
+
*/
|
|
189
|
+
export interface AuthenticatedWebViewRedirectedEvent extends AnalyticsEvent {
|
|
190
|
+
event_name: typeof EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_REDIRECTED;
|
|
191
|
+
event_metadata: {
|
|
192
|
+
id: string;
|
|
193
|
+
};
|
|
194
|
+
id: string;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Authenticated web view error event
|
|
199
|
+
*/
|
|
200
|
+
export interface AuthenticatedWebViewErrorEvent extends AnalyticsEvent {
|
|
201
|
+
event_name: typeof EVENT_NAMES.COMPONENT_AUTHENTICATED_WEB_ERROR;
|
|
202
|
+
event_metadata: {
|
|
203
|
+
id: string;
|
|
204
|
+
error_message: string;
|
|
205
|
+
};
|
|
206
|
+
id: string;
|
|
207
|
+
error_message: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Client error event (catch-all for mobile client errors)
|
|
212
|
+
*/
|
|
213
|
+
export interface ClientErrorEvent extends AnalyticsEvent {
|
|
214
|
+
event_name: typeof EVENT_NAMES.CLIENT_ERROR;
|
|
215
|
+
event_metadata: {
|
|
216
|
+
error_message: string;
|
|
217
|
+
error_domain?: string;
|
|
218
|
+
error_code?: string;
|
|
219
|
+
file?: string;
|
|
220
|
+
line?: number;
|
|
221
|
+
};
|
|
222
|
+
error_message: string;
|
|
223
|
+
error_domain?: string;
|
|
224
|
+
error_code?: string;
|
|
225
|
+
file?: string;
|
|
226
|
+
line?: number;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Union type of all possible analytics events
|
|
231
|
+
*/
|
|
232
|
+
export type ConnectAnalyticsEvent =
|
|
233
|
+
| ComponentCreatedEvent
|
|
234
|
+
| ComponentViewedEvent
|
|
235
|
+
| ComponentWebPageLoadedEvent
|
|
236
|
+
| ComponentWebComponentLoadedEvent
|
|
237
|
+
| PageLoadErrorEvent
|
|
238
|
+
| UnexpectedNavigationEvent
|
|
239
|
+
| UnexpectedLoadErrorTypeEvent
|
|
240
|
+
| UnrecognizedSetterEvent
|
|
241
|
+
| DeserializeMessageErrorEvent
|
|
242
|
+
| AuthenticatedWebViewOpenedEvent
|
|
243
|
+
| AuthenticatedWebViewCanceledEvent
|
|
244
|
+
| AuthenticatedWebViewRedirectedEvent
|
|
245
|
+
| AuthenticatedWebViewErrorEvent
|
|
246
|
+
| ClientErrorEvent;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Full analytics payload sent to backend
|
|
250
|
+
*/
|
|
251
|
+
export interface AnalyticsPayload
|
|
252
|
+
extends CommonAnalyticsFields,
|
|
253
|
+
AnalyticsEvent {}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test utilities for Connect component tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Mock constants returned by NativeStripeSdkModule.getConstants()
|
|
7
|
+
* Used to mock the native module in tests
|
|
8
|
+
*/
|
|
9
|
+
export const mockNativeConstants = {
|
|
10
|
+
API_VERSIONS: {
|
|
11
|
+
CORE: '2024-12-15',
|
|
12
|
+
ISSUING: '2024-12-15',
|
|
13
|
+
},
|
|
14
|
+
SYSTEM_INFO: {
|
|
15
|
+
sdkVersion: '1.0.0',
|
|
16
|
+
osVersion: '18.0',
|
|
17
|
+
deviceType: 'iPhone14,5',
|
|
18
|
+
appName: 'TestApp',
|
|
19
|
+
appVersion: '1.0.0',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a mock for NativeStripeSdkModule with standard test constants
|
|
25
|
+
* NOTE: Prefixed with 'mock' to be allowed in jest.mock() factory functions
|
|
26
|
+
* @param additionalMethods - Optional additional methods to include in the mock
|
|
27
|
+
* @returns Mock module configuration
|
|
28
|
+
*/
|
|
29
|
+
export const mockCreateNativeStripeSdkMock = (
|
|
30
|
+
additionalMethods: Record<string, any> = {}
|
|
31
|
+
) => ({
|
|
32
|
+
__esModule: true,
|
|
33
|
+
default: {
|
|
34
|
+
getConstants: jest.fn(() => mockNativeConstants),
|
|
35
|
+
...additionalMethods,
|
|
36
|
+
},
|
|
37
|
+
});
|
package/src/events.ts
CHANGED
|
@@ -64,6 +64,8 @@ type Events = {
|
|
|
64
64
|
embeddedPaymentElementLoadingFailed: EventEmitter<UnsafeObject<any>>;
|
|
65
65
|
embeddedPaymentElementUpdateComplete: EventEmitter<UnsafeObject<any>>;
|
|
66
66
|
onCustomPaymentMethodConfirmHandlerCallback: EventEmitter<UnsafeObject<any>>;
|
|
67
|
+
paymentMethodMessagingElementDidUpdateHeight: EventEmitter<UnsafeObject<any>>;
|
|
68
|
+
paymentMethodMessagingElementConfigureResult: EventEmitter<UnsafeObject<any>>;
|
|
67
69
|
};
|
|
68
70
|
|
|
69
71
|
export function addListener<EventT extends keyof Events>(
|
package/src/functions.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type {
|
|
|
31
31
|
CanAddCardToWalletResult,
|
|
32
32
|
FinancialConnections,
|
|
33
33
|
PlatformPay,
|
|
34
|
+
CreateRadarSessionResult,
|
|
34
35
|
} from './types';
|
|
35
36
|
import { Platform, EventSubscription } from 'react-native';
|
|
36
37
|
import type { CollectFinancialConnectionsAccountsParams } from './types/FinancialConnections';
|
|
@@ -910,6 +911,15 @@ export const openPlatformPaySetup = async (): Promise<void> => {
|
|
|
910
911
|
}
|
|
911
912
|
};
|
|
912
913
|
|
|
914
|
+
/**
|
|
915
|
+
* Creates a [Radar session](https://docs.stripe.com/radar/radar-session).
|
|
916
|
+
* @returns A promise that resolves to a Radar session id, or an error.
|
|
917
|
+
*/
|
|
918
|
+
export const createRadarSession =
|
|
919
|
+
async (): Promise<CreateRadarSessionResult> => {
|
|
920
|
+
return await NativeStripeSdk.createRadarSession();
|
|
921
|
+
};
|
|
922
|
+
|
|
913
923
|
export const setFinancialConnectionsForceNativeFlow = async (
|
|
914
924
|
enabled: boolean
|
|
915
925
|
): Promise<void> => {
|
package/src/hooks/useStripe.tsx
CHANGED
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
FinancialConnections,
|
|
28
28
|
PlatformPay,
|
|
29
29
|
PlatformPayError,
|
|
30
|
+
CreateRadarSessionResult,
|
|
30
31
|
} from '../types';
|
|
31
32
|
import { useCallback } from 'react';
|
|
32
33
|
import {
|
|
@@ -59,6 +60,7 @@ import {
|
|
|
59
60
|
createPlatformPayToken,
|
|
60
61
|
updatePlatformPaySheet,
|
|
61
62
|
openPlatformPaySetup,
|
|
63
|
+
createRadarSession,
|
|
62
64
|
} from '../functions';
|
|
63
65
|
import type { CollectBankAccountTokenParams } from '../types/PaymentMethod';
|
|
64
66
|
import type { CollectFinancialConnectionsAccountsParams } from '../types/FinancialConnections';
|
|
@@ -320,6 +322,11 @@ export function useStripe() {
|
|
|
320
322
|
return openPlatformPaySetup();
|
|
321
323
|
}, []);
|
|
322
324
|
|
|
325
|
+
const _createRadarSession =
|
|
326
|
+
useCallback(async (): Promise<CreateRadarSessionResult> => {
|
|
327
|
+
return createRadarSession();
|
|
328
|
+
}, []);
|
|
329
|
+
|
|
323
330
|
return {
|
|
324
331
|
retrievePaymentIntent: _retrievePaymentIntent,
|
|
325
332
|
retrieveSetupIntent: _retrieveSetupIntent,
|
|
@@ -355,5 +362,6 @@ export function useStripe() {
|
|
|
355
362
|
createPlatformPayToken: _createPlatformPayToken,
|
|
356
363
|
updatePlatformPaySheet: _updatePlatformPaySheet,
|
|
357
364
|
openPlatformPaySetup: _openPlatformPaySetup,
|
|
365
|
+
createRadarSession: _createRadarSession,
|
|
358
366
|
};
|
|
359
367
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
|
2
|
+
import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
|
|
3
|
+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
4
|
+
import {
|
|
5
|
+
PaymentMethodMessagingElementAppearance,
|
|
6
|
+
PaymentMethodMessagingElementConfiguration,
|
|
7
|
+
PaymentMethodMessagingElementState,
|
|
8
|
+
} from '../types/components/PaymentMethodMessagingElementComponent';
|
|
9
|
+
import { UnsafeMixed } from './utils';
|
|
10
|
+
|
|
11
|
+
interface StateChangeEvent {
|
|
12
|
+
result: UnsafeMixed<PaymentMethodMessagingElementState>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface NativeProps extends ViewProps {
|
|
16
|
+
appearance?: UnsafeMixed<PaymentMethodMessagingElementAppearance>;
|
|
17
|
+
configuration: UnsafeMixed<PaymentMethodMessagingElementConfiguration>;
|
|
18
|
+
onStateChange: DirectEventHandler<StateChangeEvent>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ComponentType = HostComponent<NativeProps>;
|
|
22
|
+
|
|
23
|
+
export default codegenNativeComponent<NativeProps>(
|
|
24
|
+
'PaymentMethodMessagingElementView'
|
|
25
|
+
) as ComponentType;
|