@transfergratis/react-native-sdk 0.1.5 → 0.1.7
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/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/CountrySelectionTemplate.js +7 -1
- package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.d.ts +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.js +32 -3
- package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
- package/build/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/VerificationProgressTemplate.js +106 -5
- package/build/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
- package/build/components/TemplateKYCExample.d.ts +4 -1
- package/build/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/components/TemplateKYCExample.js +4 -4
- package/build/components/TemplateKYCExample.js.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.d.ts +3 -2
- package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.js +2 -2
- package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
- package/build/hooks/useTemplateKYCFlow.d.ts +5 -3
- package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
- package/build/hooks/useTemplateKYCFlow.js +89 -74
- package/build/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/modules/api/KYCService.d.ts +2 -1
- package/build/modules/api/KYCService.d.ts.map +1 -1
- package/build/modules/api/KYCService.js +17 -61
- package/build/modules/api/KYCService.js.map +1 -1
- package/build/modules/api/types.d.ts +25 -0
- package/build/modules/api/types.d.ts.map +1 -1
- package/build/modules/api/types.js.map +1 -1
- package/build/types/KYC.types.d.ts +2 -5
- package/build/types/KYC.types.d.ts.map +1 -1
- package/build/types/KYC.types.js.map +1 -1
- package/build/utils/cropByObb.js +4 -4
- package/build/utils/cropByObb.js.map +1 -1
- package/build/web/WebKYCEntry.d.ts +9 -0
- package/build/web/WebKYCEntry.d.ts.map +1 -0
- package/build/web/WebKYCEntry.js +156 -0
- package/build/web/WebKYCEntry.js.map +1 -0
- package/build/web/index.d.ts +2 -0
- package/build/web/index.d.ts.map +1 -0
- package/build/web/index.js +2 -0
- package/build/web/index.js.map +1 -0
- package/package.json +4 -4
- package/src/components/KYCElements/CountrySelectionTemplate.tsx +8 -1
- package/src/components/KYCElements/SelfieCaptureTemplate.tsx +37 -7
- package/src/components/KYCElements/VerificationProgressTemplate.tsx +129 -6
- package/src/components/TemplateKYCExample.tsx +6 -5
- package/src/components/TemplateKYCFlowRefactored.tsx +6 -2
- package/src/hooks/useTemplateKYCFlow.tsx +105 -77
- package/src/index.ts +3 -0
- package/src/modules/api/KYCService.ts +21 -74
- package/src/modules/api/types.ts +30 -3
- package/src/types/KYC.types.ts +4 -5
- package/src/utils/cropByObb.ts +5 -5
- package/src/web/WebKYCEntry.tsx +215 -0
- package/src/web/index.ts +1 -0
package/src/modules/api/types.ts
CHANGED
|
@@ -12,13 +12,40 @@ export interface SessionResponse {
|
|
|
12
12
|
|
|
13
13
|
export interface VerificationSessionRequest {
|
|
14
14
|
step: number;
|
|
15
|
-
data:VerificationSessionData;
|
|
15
|
+
data: VerificationSessionData;
|
|
16
16
|
templateId: string | null;
|
|
17
17
|
session_id: string;
|
|
18
18
|
token: string;
|
|
19
|
-
action:string
|
|
19
|
+
action: string
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
// dynamic type
|
|
24
|
-
export type VerificationSessionData = Record<string, any>;
|
|
24
|
+
export type VerificationSessionData = Record<string, any>;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export interface VerificationResult {
|
|
28
|
+
[key: string]: {
|
|
29
|
+
data: {
|
|
30
|
+
verification_id: string;
|
|
31
|
+
verification_status: string;
|
|
32
|
+
completion_timestamp: string;
|
|
33
|
+
user_data: {
|
|
34
|
+
personal_information: {
|
|
35
|
+
full_name: string;
|
|
36
|
+
first_name: string | null;
|
|
37
|
+
last_name: string | null;
|
|
38
|
+
date_of_birth: string | null;
|
|
39
|
+
nationality: string | null;
|
|
40
|
+
gender: string | null;
|
|
41
|
+
place_of_birth: string | null;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
selfie_info: {
|
|
45
|
+
is_match: boolean;
|
|
46
|
+
similarity: number;
|
|
47
|
+
image: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}
|
package/src/types/KYC.types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { VerificationResult } from "../modules/api/types";
|
|
2
|
+
|
|
1
3
|
// Types pour les documents
|
|
2
4
|
export interface Document {
|
|
3
5
|
id: string;
|
|
@@ -428,11 +430,7 @@ export interface SessionState {
|
|
|
428
430
|
|
|
429
431
|
export type VerificationStatus = 'idle' | 'in_progress' | 'success' | 'failed';
|
|
430
432
|
|
|
431
|
-
|
|
432
|
-
referenceId?: string;
|
|
433
|
-
message?: string;
|
|
434
|
-
issues?: string[];
|
|
435
|
-
}
|
|
433
|
+
|
|
436
434
|
|
|
437
435
|
export interface VerificationState {
|
|
438
436
|
status: VerificationStatus;
|
|
@@ -452,6 +450,7 @@ export interface TemplateActions {
|
|
|
452
450
|
setLanguage: (language: string) => void;
|
|
453
451
|
showCustomStepper: (show: boolean) => void;
|
|
454
452
|
setVerificationState: (state: VerificationState) => void;
|
|
453
|
+
submitVerification: () => Promise<void>;
|
|
455
454
|
}
|
|
456
455
|
|
|
457
456
|
// Hook pour le template KYC
|
package/src/utils/cropByObb.ts
CHANGED
|
@@ -79,12 +79,12 @@ export async function cropImageWithBBox(uri: string, bbox: any) {
|
|
|
79
79
|
// const scaleX = originalWidth / displayedSize.width;
|
|
80
80
|
// const scaleY = originalHeight / displayedSize.height;
|
|
81
81
|
|
|
82
|
-
// 3️⃣ Convertir le bbox à la taille réelle
|
|
82
|
+
// 3️⃣ Convertir le bbox à la taille réelle scale 0.10 = 10%
|
|
83
83
|
const crop = {
|
|
84
|
-
originX: bbox.minX,
|
|
85
|
-
originY: bbox.minY,
|
|
86
|
-
width: bbox.width,
|
|
87
|
-
height: bbox.height,
|
|
84
|
+
originX: bbox.minX ,
|
|
85
|
+
originY: bbox.minY - 80,
|
|
86
|
+
width: bbox.width + 100,
|
|
87
|
+
height: bbox.height + 150,
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
// 4️⃣ Appliquer le crop
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
+
import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
|
|
3
|
+
// import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';
|
|
4
|
+
// import { KYCTemplate } from '../types/KYC.types';
|
|
5
|
+
import { useI18n } from '../hooks/useI18n';
|
|
6
|
+
import { TemplateKYCExample } from '../components/TemplateKYCExample';
|
|
7
|
+
|
|
8
|
+
interface WebKYCEntryProps {
|
|
9
|
+
onComplete?: (data: any) => void;
|
|
10
|
+
onError?: (error: string) => void;
|
|
11
|
+
onCancel?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface URLParams {
|
|
15
|
+
token?: string;
|
|
16
|
+
return_url?: string;
|
|
17
|
+
lang?: string;
|
|
18
|
+
theme?: string;
|
|
19
|
+
kyc_id?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
|
|
23
|
+
onComplete,
|
|
24
|
+
onError,
|
|
25
|
+
onCancel,
|
|
26
|
+
}) => {
|
|
27
|
+
const { setLocale } = useI18n();
|
|
28
|
+
const [urlParams, setUrlParams] = useState<URLParams>({});
|
|
29
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
30
|
+
const [error, setError] = useState<string | null>(null);
|
|
31
|
+
|
|
32
|
+
// Parse URL parameters
|
|
33
|
+
const parseUrlParams = useCallback((): URLParams => {
|
|
34
|
+
if (typeof window === 'undefined') return {};
|
|
35
|
+
|
|
36
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
37
|
+
return {
|
|
38
|
+
token: urlParams.get('token') || undefined,
|
|
39
|
+
return_url: urlParams.get('return_url') || undefined,
|
|
40
|
+
lang: urlParams.get('lang') || 'en',
|
|
41
|
+
theme: urlParams.get('theme') || 'light',
|
|
42
|
+
kyc_id: urlParams.get('kyc_id') || undefined,
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
// Safe redirect function with validation
|
|
47
|
+
const redirectToReturnUrl = useCallback((params: {
|
|
48
|
+
status: 'completed' | 'cancelled' | 'error';
|
|
49
|
+
kyc_id?: string;
|
|
50
|
+
message?: string;
|
|
51
|
+
sig?: string;
|
|
52
|
+
}) => {
|
|
53
|
+
const { return_url } = urlParams;
|
|
54
|
+
|
|
55
|
+
if (!return_url) {
|
|
56
|
+
console.warn('No return_url provided');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Basic URL validation - ensure it's a valid URL
|
|
61
|
+
try {
|
|
62
|
+
const returnUrl = new URL(return_url);
|
|
63
|
+
|
|
64
|
+
// Optional: Add domain allowlist validation here
|
|
65
|
+
// const allowedDomains = ['example.com', 'trusted-site.com'];
|
|
66
|
+
// if (!allowedDomains.some(domain => returnUrl.hostname.endsWith(domain))) {
|
|
67
|
+
// console.error('Return URL not in allowlist');
|
|
68
|
+
// return;
|
|
69
|
+
// }
|
|
70
|
+
|
|
71
|
+
// Build redirect URL with parameters
|
|
72
|
+
const redirectUrl = new URL(returnUrl);
|
|
73
|
+
redirectUrl.searchParams.set('status', params.status);
|
|
74
|
+
|
|
75
|
+
if (params.kyc_id) {
|
|
76
|
+
redirectUrl.searchParams.set('kyc_id', params.kyc_id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (params.message) {
|
|
80
|
+
redirectUrl.searchParams.set('message', params.message);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (params.sig) {
|
|
84
|
+
redirectUrl.searchParams.set('sig', params.sig);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Optional: Send postMessage to parent if in iframe
|
|
88
|
+
if (window.parent !== window) {
|
|
89
|
+
window.parent.postMessage({
|
|
90
|
+
type: 'kyc_result',
|
|
91
|
+
status: params.status,
|
|
92
|
+
kyc_id: params.kyc_id,
|
|
93
|
+
message: params.message,
|
|
94
|
+
}, '*');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Redirect to return URL
|
|
98
|
+
window.location.href = redirectUrl.toString();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('Invalid return URL:', error);
|
|
101
|
+
setError('Invalid return URL provided');
|
|
102
|
+
}
|
|
103
|
+
}, [urlParams]);
|
|
104
|
+
|
|
105
|
+
// Handle KYC completion
|
|
106
|
+
const handleComplete = useCallback((data: any) => {
|
|
107
|
+
console.log('KYC completed:', data);
|
|
108
|
+
redirectToReturnUrl({
|
|
109
|
+
status: 'completed',
|
|
110
|
+
kyc_id: data.session_id || urlParams.kyc_id,
|
|
111
|
+
message: 'KYC process completed successfully',
|
|
112
|
+
});
|
|
113
|
+
onComplete?.(data);
|
|
114
|
+
}, [redirectToReturnUrl, urlParams.kyc_id, onComplete]);
|
|
115
|
+
|
|
116
|
+
// Handle KYC error
|
|
117
|
+
const handleError = useCallback((error: string) => {
|
|
118
|
+
console.error('KYC error:', error);
|
|
119
|
+
redirectToReturnUrl({
|
|
120
|
+
status: 'error',
|
|
121
|
+
kyc_id: urlParams.kyc_id,
|
|
122
|
+
message: error,
|
|
123
|
+
});
|
|
124
|
+
onError?.(error);
|
|
125
|
+
}, [redirectToReturnUrl, urlParams.kyc_id, onError]);
|
|
126
|
+
|
|
127
|
+
// Handle KYC cancellation
|
|
128
|
+
const handleCancel = useCallback(() => {
|
|
129
|
+
console.log('KYC cancelled');
|
|
130
|
+
redirectToReturnUrl({
|
|
131
|
+
status: 'cancelled',
|
|
132
|
+
kyc_id: urlParams.kyc_id,
|
|
133
|
+
message: 'KYC process was cancelled',
|
|
134
|
+
});
|
|
135
|
+
onCancel?.();
|
|
136
|
+
}, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
|
|
137
|
+
|
|
138
|
+
// Initialize component
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
try {
|
|
141
|
+
const params = parseUrlParams();
|
|
142
|
+
setUrlParams(params);
|
|
143
|
+
|
|
144
|
+
// Set language if provided
|
|
145
|
+
if (params.lang) {
|
|
146
|
+
setLocale(params.lang);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
setIsLoading(false);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error('Error parsing URL parameters:', error);
|
|
152
|
+
setError('Error parsing URL parameters');
|
|
153
|
+
setIsLoading(false);
|
|
154
|
+
}
|
|
155
|
+
}, [parseUrlParams, setLocale]);
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
if (isLoading) {
|
|
159
|
+
return (
|
|
160
|
+
<View style={styles.container}>
|
|
161
|
+
<Text style={styles.loadingText}>Loading KYC process...</Text>
|
|
162
|
+
</View>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (error) {
|
|
167
|
+
return (
|
|
168
|
+
<View style={styles.container}>
|
|
169
|
+
<Text style={styles.errorText}>Error: {error}</Text>
|
|
170
|
+
</View>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!urlParams.token) {
|
|
175
|
+
return (
|
|
176
|
+
<View style={styles.container}>
|
|
177
|
+
<Text style={styles.errorText}>No token provided in URL parameters</Text>
|
|
178
|
+
</View>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<SafeAreaView style={styles.container}>
|
|
184
|
+
<TemplateKYCExample
|
|
185
|
+
onComplete={handleComplete}
|
|
186
|
+
onCancel={handleCancel}
|
|
187
|
+
onError={handleError}
|
|
188
|
+
language={urlParams.lang || 'en'}
|
|
189
|
+
API_KEY={urlParams.token}
|
|
190
|
+
/>
|
|
191
|
+
</SafeAreaView>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const styles = StyleSheet.create({
|
|
196
|
+
container: {
|
|
197
|
+
flex: 1,
|
|
198
|
+
backgroundColor: '#f5f5f5',
|
|
199
|
+
},
|
|
200
|
+
loadingText: {
|
|
201
|
+
fontSize: 18,
|
|
202
|
+
textAlign: 'center',
|
|
203
|
+
marginTop: 50,
|
|
204
|
+
color: '#666',
|
|
205
|
+
},
|
|
206
|
+
errorText: {
|
|
207
|
+
fontSize: 16,
|
|
208
|
+
textAlign: 'center',
|
|
209
|
+
marginTop: 50,
|
|
210
|
+
color: '#dc2626',
|
|
211
|
+
paddingHorizontal: 20,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
export default WebKYCEntry;
|
package/src/web/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as WebKYCEntry } from './WebKYCEntry';
|