@transfergratis/react-native-sdk 0.1.24 → 0.1.25

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.
Files changed (149) hide show
  1. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +12 -5
  2. package/android/build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +0 -0
  3. package/android/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +0 -0
  4. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  5. package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
  6. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +61 -59
  7. package/android/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-transfergratis-react-native-sdk.jar +0 -0
  8. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +12 -5
  9. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  10. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  11. package/android/build/outputs/aar/transfergratis-react-native-sdk-debug.aar +0 -0
  12. package/android/build/outputs/logs/manifest-merger-debug-report.txt +26 -34
  13. package/android/src/main/AndroidManifest.xml +10 -7
  14. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts +12 -0
  15. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts.map +1 -0
  16. package/build/components/KYCElements/AdditionalDocumentsTemplate.js +283 -0
  17. package/build/components/KYCElements/AdditionalDocumentsTemplate.js.map +1 -0
  18. package/build/components/KYCElements/EmailVerificationTemplate.d.ts +12 -0
  19. package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
  20. package/build/components/KYCElements/EmailVerificationTemplate.js +193 -0
  21. package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
  22. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  23. package/build/components/KYCElements/IDCardCapture.js +180 -7
  24. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  25. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -0
  26. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  27. package/build/components/KYCElements/OrientationVideoCapture.js +2 -2
  28. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  29. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -0
  30. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +2 -2
  32. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  33. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -0
  34. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  35. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +2 -2
  36. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  37. package/build/components/KYCElements/PersonalInformationTemplate.d.ts +12 -0
  38. package/build/components/KYCElements/PersonalInformationTemplate.d.ts.map +1 -0
  39. package/build/components/KYCElements/PersonalInformationTemplate.js +120 -0
  40. package/build/components/KYCElements/PersonalInformationTemplate.js.map +1 -0
  41. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts +12 -0
  42. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -0
  43. package/build/components/KYCElements/PhoneVerificationTemplate.js +185 -0
  44. package/build/components/KYCElements/PhoneVerificationTemplate.js.map +1 -0
  45. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  46. package/build/components/KYCElements/SelfieCaptureTemplate.js +7 -3
  47. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  48. package/build/components/TemplateKYCExample.d.ts +4 -0
  49. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  50. package/build/components/TemplateKYCExample.js +7 -30
  51. package/build/components/TemplateKYCExample.js.map +1 -1
  52. package/build/components/TemplateKYCFlowRefactored.d.ts +4 -0
  53. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  54. package/build/components/TemplateKYCFlowRefactored.js +14 -2
  55. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  56. package/build/config/KYCConfig.d.ts +14 -0
  57. package/build/config/KYCConfig.d.ts.map +1 -0
  58. package/build/config/KYCConfig.js +26 -0
  59. package/build/config/KYCConfig.js.map +1 -0
  60. package/build/config/allowedDomains.d.ts.map +1 -1
  61. package/build/config/allowedDomains.js +4 -19
  62. package/build/config/allowedDomains.js.map +1 -1
  63. package/build/hooks/useOrientationVideo.d.ts +2 -1
  64. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  65. package/build/hooks/useOrientationVideo.js +3 -3
  66. package/build/hooks/useOrientationVideo.js.map +1 -1
  67. package/build/hooks/useTemplateKYCFlow.d.ts +6 -1
  68. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  69. package/build/hooks/useTemplateKYCFlow.js +286 -23
  70. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  71. package/build/i18n/en/index.d.ts +40 -0
  72. package/build/i18n/en/index.d.ts.map +1 -1
  73. package/build/i18n/en/index.js +41 -1
  74. package/build/i18n/en/index.js.map +1 -1
  75. package/build/i18n/fr/index.d.ts +26 -0
  76. package/build/i18n/fr/index.d.ts.map +1 -1
  77. package/build/i18n/fr/index.js +27 -1
  78. package/build/i18n/fr/index.js.map +1 -1
  79. package/build/index.d.ts +1 -0
  80. package/build/index.d.ts.map +1 -1
  81. package/build/index.js +2 -0
  82. package/build/index.js.map +1 -1
  83. package/build/modules/api/CardAuthentification.d.ts +24 -3
  84. package/build/modules/api/CardAuthentification.d.ts.map +1 -1
  85. package/build/modules/api/CardAuthentification.js +68 -10
  86. package/build/modules/api/CardAuthentification.js.map +1 -1
  87. package/build/modules/api/KYCService.d.ts +7 -7
  88. package/build/modules/api/KYCService.d.ts.map +1 -1
  89. package/build/modules/api/KYCService.js +101 -37
  90. package/build/modules/api/KYCService.js.map +1 -1
  91. package/build/modules/api/SelfieVerification.d.ts +3 -1
  92. package/build/modules/api/SelfieVerification.d.ts.map +1 -1
  93. package/build/modules/api/SelfieVerification.js +17 -1
  94. package/build/modules/api/SelfieVerification.js.map +1 -1
  95. package/build/modules/api/TemplateService.d.ts +0 -1
  96. package/build/modules/api/TemplateService.d.ts.map +1 -1
  97. package/build/modules/api/TemplateService.js +3 -3
  98. package/build/modules/api/TemplateService.js.map +1 -1
  99. package/build/types/KYC.types.d.ts +124 -3
  100. package/build/types/KYC.types.d.ts.map +1 -1
  101. package/build/types/KYC.types.js.map +1 -1
  102. package/build/types/env.types.d.ts +13 -0
  103. package/build/types/env.types.d.ts.map +1 -0
  104. package/build/types/env.types.js +2 -0
  105. package/build/types/env.types.js.map +1 -0
  106. package/build/utils/deviceDetection.d.ts +6 -0
  107. package/build/utils/deviceDetection.d.ts.map +1 -0
  108. package/build/utils/deviceDetection.js +12 -0
  109. package/build/utils/deviceDetection.js.map +1 -0
  110. package/build/utils/platformAlert.d.ts.map +1 -1
  111. package/build/utils/platformAlert.js.map +1 -1
  112. package/build/utils/template-transformer.d.ts.map +1 -1
  113. package/build/utils/template-transformer.js +12 -0
  114. package/build/utils/template-transformer.js.map +1 -1
  115. package/build/web/WebKYCEntry.d.ts.map +1 -1
  116. package/build/web/WebKYCEntry.js +82 -38
  117. package/build/web/WebKYCEntry.js.map +1 -1
  118. package/package.json +1 -1
  119. package/plugin/build/withVisionCamera.js +3 -4
  120. package/plugin/src/withVisionCamera.js +3 -4
  121. package/plugin/src/withVisionCamera.ts +3 -4
  122. package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
  123. package/src/components/KYCElements/EmailVerificationTemplate.tsx +264 -0
  124. package/src/components/KYCElements/IDCardCapture.tsx +216 -15
  125. package/src/components/KYCElements/OrientationVideoCapture.tsx +4 -1
  126. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +4 -1
  127. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +4 -1
  128. package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
  129. package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
  130. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +6 -3
  131. package/src/components/TemplateKYCExample.tsx +31 -46
  132. package/src/components/TemplateKYCFlowRefactored.tsx +27 -1
  133. package/src/config/KYCConfig.ts +34 -0
  134. package/src/config/allowedDomains.ts +7 -26
  135. package/src/hooks/useOrientationVideo.ts +5 -4
  136. package/src/hooks/useTemplateKYCFlow.tsx +314 -21
  137. package/src/i18n/en/index.ts +43 -2
  138. package/src/i18n/fr/index.ts +28 -1
  139. package/src/index.ts +3 -0
  140. package/src/modules/api/CardAuthentification.ts +75 -10
  141. package/src/modules/api/KYCService.ts +117 -37
  142. package/src/modules/api/SelfieVerification.ts +25 -3
  143. package/src/modules/api/TemplateService.ts +4 -4
  144. package/src/types/KYC.types.ts +146 -3
  145. package/src/types/env.types.ts +13 -0
  146. package/src/utils/deviceDetection.ts +11 -0
  147. package/src/utils/platformAlert.ts +1 -0
  148. package/src/utils/template-transformer.ts +20 -8
  149. package/src/web/WebKYCEntry.tsx +112 -61
@@ -0,0 +1,253 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Text, StyleSheet, TextInput, TouchableOpacity, Alert } from 'react-native';
3
+ import { TemplateComponent, LocalizedText } from '../../types/KYC.types';
4
+ import { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';
5
+ import { useI18n } from '../../hooks/useI18n';
6
+ import { Button } from '../ui/Button';
7
+
8
+ interface PhoneVerificationTemplateProps {
9
+ component: TemplateComponent;
10
+ value?: any;
11
+ onValueChange: (data: any) => void;
12
+ error?: string;
13
+ language?: string;
14
+ }
15
+
16
+ type VerificationStep = 'phone' | 'otp';
17
+
18
+ export const PhoneVerificationTemplate: React.FC<PhoneVerificationTemplateProps> = ({
19
+ component,
20
+ value,
21
+ onValueChange,
22
+ error: propError,
23
+ }) => {
24
+ const { actions, getLocalizedText } = useTemplateKYCFlowContext();
25
+ const { t } = useI18n();
26
+ // const config = component.config as PhoneVerificationConfig;
27
+
28
+ // State
29
+ const [step, setStep] = useState<VerificationStep>('phone');
30
+ const [phone, setPhone] = useState('');
31
+ const [otp, setOtp] = useState('');
32
+ const [localError, setLocalError] = useState<string | null>(null);
33
+ const [isSimulating, setIsSimulating] = useState(false);
34
+
35
+ const title = getLocalizedText(component.labels as LocalizedText);
36
+ const instructions = getLocalizedText(component.instructions as LocalizedText);
37
+
38
+ // Determine button text based on step
39
+ const verifyButtonText = getLocalizedText((component.ui as any).buttonText) || t('common.verify') || 'Verify';
40
+ const sendButtonText = t('common.sendCode') || 'Send Verification Code';
41
+ const buttonText = step === 'phone' ? sendButtonText : verifyButtonText;
42
+
43
+ const handleSendCode = () => {
44
+ if (!phone || phone.length < 5) {
45
+ setLocalError(t('errors.invalidPhone') || 'Please enter a valid phone number');
46
+ return;
47
+ }
48
+
49
+ setLocalError(null);
50
+ setIsSimulating(true);
51
+
52
+ // Simulate API call to send code
53
+ setTimeout(() => {
54
+ setIsSimulating(false);
55
+ setStep('otp');
56
+ }, 1500);
57
+ };
58
+
59
+ const handleVerifyCode = () => {
60
+ if (!otp || otp.length < 4) {
61
+ setLocalError(t('errors.invalidCode') || 'Please enter the 6-digit code');
62
+ return;
63
+ }
64
+
65
+ setLocalError(null);
66
+ setIsSimulating(true);
67
+
68
+ // Simulate verification API
69
+ setTimeout(() => {
70
+ setIsSimulating(false);
71
+
72
+ // Mock validation logic
73
+ if (otp === '123456') {
74
+ onValueChange({ phone, otp, verified: true });
75
+ actions.nextComponent();
76
+ } else {
77
+ setLocalError(t('errors.wrongCode') || 'Invalid verification code. Try 123456');
78
+ }
79
+ }, 1500);
80
+ };
81
+
82
+ const onChangePhone = (text: string) => {
83
+ setPhone(text);
84
+ if (localError) setLocalError(null);
85
+ };
86
+
87
+ const onChangeOtp = (text: string) => {
88
+ setOtp(text);
89
+ if (localError) setLocalError(null);
90
+ };
91
+
92
+ const handleBackToPhone = () => {
93
+ setStep('phone');
94
+ setOtp('');
95
+ setLocalError(null);
96
+ };
97
+
98
+ return (
99
+ <View style={styles.container}>
100
+ <Text style={styles.title}>{title}</Text>
101
+ <Text style={styles.instructions}>
102
+ {step === 'phone' ? instructions : (t('kyc.enterCodeSent') || `Please enter the code sent to ${phone}`)}
103
+ </Text>
104
+
105
+ <View style={styles.contentContainer}>
106
+ {step === 'phone' ? (
107
+ <View style={styles.inputContainer}>
108
+ <Text style={styles.label}>{t('common.phone') || 'Phone Number'}</Text>
109
+ <TextInput
110
+ style={styles.input}
111
+ placeholder="+1234567890"
112
+ value={phone}
113
+ onChangeText={onChangePhone}
114
+ keyboardType="phone-pad"
115
+ autoComplete="tel"
116
+ editable={!isSimulating}
117
+ />
118
+ </View>
119
+ ) : (
120
+ <View style={styles.inputContainer}>
121
+ <Text style={styles.label}>{t('common.verificationCode') || 'Verification Code'}</Text>
122
+ <TextInput
123
+ style={styles.input}
124
+ placeholder="123456"
125
+ value={otp}
126
+ onChangeText={onChangeOtp}
127
+ keyboardType="number-pad"
128
+ maxLength={6}
129
+ editable={!isSimulating}
130
+ />
131
+ <TouchableOpacity onPress={handleBackToPhone} style={styles.changeLink}>
132
+ <Text style={styles.changeText}>{t('common.back') || 'Change number'}</Text>
133
+ </TouchableOpacity>
134
+ </View>
135
+ )}
136
+
137
+ {(localError || propError) && (
138
+ <Text style={styles.errorText}>{localError || propError}</Text>
139
+ )}
140
+
141
+ <Button
142
+ title={isSimulating ? (t('common.processing') || 'Processing...') : buttonText}
143
+ onPress={step === 'phone' ? handleSendCode : handleVerifyCode}
144
+ style={styles.button}
145
+ disabled={
146
+ isSimulating ||
147
+ (step === 'phone' ? !phone : !otp)
148
+ }
149
+ />
150
+
151
+ {step === 'otp' && (
152
+ <TouchableOpacity
153
+ onPress={() => {
154
+ // Resend logic
155
+ Alert.alert(
156
+ t('common.codeResent') || 'Code Resent',
157
+ t('common.codeResentMessage', { email: phone }) || 'Code resent to ' + phone
158
+ );
159
+ }}
160
+ style={styles.resendButton}
161
+ disabled={isSimulating}
162
+ >
163
+ <Text style={styles.resendText}>{t('common.resendCode') || 'Resend Code'}</Text>
164
+ </TouchableOpacity>
165
+ )}
166
+ </View>
167
+ </View>
168
+ );
169
+ };
170
+
171
+ const styles = StyleSheet.create({
172
+ container: {
173
+ padding: 24,
174
+ backgroundColor: 'white',
175
+ borderRadius: 16,
176
+ margin: 16,
177
+ shadowColor: '#000',
178
+ shadowOffset: { width: 0, height: 4 },
179
+ shadowOpacity: 0.1,
180
+ shadowRadius: 12,
181
+ elevation: 5,
182
+ width: '95%',
183
+ },
184
+ title: {
185
+ fontSize: 24,
186
+ fontWeight: '700',
187
+ marginBottom: 8,
188
+ color: '#1a1a1a',
189
+ textAlign: 'center',
190
+ },
191
+ instructions: {
192
+ fontSize: 16,
193
+ color: '#666',
194
+ marginBottom: 32,
195
+ lineHeight: 24,
196
+ textAlign: 'center',
197
+ },
198
+ contentContainer: {
199
+ // width: '100%',
200
+ },
201
+ inputContainer: {
202
+ marginBottom: 24,
203
+ },
204
+ label: {
205
+ fontSize: 14,
206
+ fontWeight: '600',
207
+ color: '#333',
208
+ marginBottom: 8,
209
+ marginLeft: 4,
210
+ },
211
+ input: {
212
+ borderWidth: 1,
213
+ borderColor: '#e0e0e0',
214
+ padding: 16,
215
+ borderRadius: 12,
216
+ fontSize: 16,
217
+ backgroundColor: '#f8f9fa',
218
+ color: '#333',
219
+ },
220
+ errorText: {
221
+ color: '#dc2626',
222
+ marginBottom: 16,
223
+ fontSize: 14,
224
+ textAlign: 'center',
225
+ backgroundColor: '#fee2e2',
226
+ padding: 8,
227
+ borderRadius: 8,
228
+ overflow: 'hidden',
229
+ },
230
+ button: {
231
+ height: 50,
232
+ borderRadius: 12,
233
+ width: "100%"
234
+ },
235
+ changeLink: {
236
+ alignSelf: 'flex-end',
237
+ marginTop: 8,
238
+ },
239
+ changeText: {
240
+ color: '#2DBD60',
241
+ fontSize: 14,
242
+ fontWeight: '500',
243
+ },
244
+ resendButton: {
245
+ marginTop: 16,
246
+ alignItems: 'center',
247
+ },
248
+ resendText: {
249
+ color: '#666',
250
+ fontSize: 14,
251
+ textDecorationLine: 'underline',
252
+ },
253
+ });
@@ -33,7 +33,7 @@ export const SelfieCaptureTemplate: React.FC<SelfieCaptureTemplateProps> = ({
33
33
  const { t } = useI18n();
34
34
  // const config = component.config as SelfieConfig;
35
35
  const orientations: OrientationType[] = (['center','left','right']) as OrientationType[];
36
- const { actions, state, } = useTemplateKYCFlowContext();
36
+ const { actions, state, env } = useTemplateKYCFlowContext();
37
37
 
38
38
  const [silentCaptureResult, setSilentCaptureResult] = useState<ISilentCaptureResult>({ success: false, isAnalyzing: false });
39
39
 
@@ -152,10 +152,13 @@ export const SelfieCaptureTemplate: React.FC<SelfieCaptureTemplateProps> = ({
152
152
  }
153
153
  if (result.success && result.path) {
154
154
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));
155
- selfieVerification(result.path).then((response) => {
155
+ selfieVerification(result.path, env).then((response) => {
156
156
  if (response.length > 0) {
157
157
  const res = response[0];
158
- if (res?.orientation_direction === getOrientationOpposite(currentOrientation) && res?.capture) {
158
+ // In SANDBOX mode, always accept the result regardless of orientation
159
+ if (env === 'SANDBOX' && res?.capture) {
160
+ setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: true, error: '', path: result.path }));
161
+ } else if (res?.orientation_direction === getOrientationOpposite(currentOrientation) && res?.capture) {
159
162
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: true, error: '', path: result.path }));
160
163
  } else {
161
164
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: 'Le selfie n\'est pas correct' }));
@@ -2,8 +2,11 @@ import React from 'react';
2
2
  import { View, SafeAreaView } from 'react-native';
3
3
  import { TemplateKYCFlow } from './TemplateKYCFlowRefactored';
4
4
  import { KYCTemplate, VerificationState } from '../types/KYC.types';
5
+ import { KycEnvironment } from '../types/env.types';
6
+
7
+
8
+
5
9
 
6
- // Template JSON basé sur votre exemple
7
10
  const advancedVerificationTemplate: KYCTemplate = {
8
11
  id: 1,
9
12
  name: {
@@ -103,7 +106,7 @@ const advancedVerificationTemplate: KYCTemplate = {
103
106
  allowed_formats: ["jpg", "png"],
104
107
  max_size_mb: 5,
105
108
  document_types: ["drivers_licence", "passport", "drivers_licence", "national_id"],
106
-
109
+
107
110
  } as const
108
111
  },
109
112
  {
@@ -130,42 +133,21 @@ const advancedVerificationTemplate: KYCTemplate = {
130
133
  orientations: ["center", "left", "right"]
131
134
  } as const
132
135
  },
133
- // {
134
- // id: 4,
135
- // type: "file_upload" as const,
136
- // order: 6,
137
- // labels: {
138
- // en: "Upload proof of address",
139
- // fr: "Téléversez un justificatif de domicile"
140
- // },
141
- // instructions: {
142
- // en: "Upload a recent utility bill or bank statement (PDF, JPG, PNG).",
143
- // fr: "Téléversez une facture récente ou un relevé bancaire (PDF, JPG, PNG)."
144
- // },
145
- // ui: {
146
- // icon: "file-upload-icon.png",
147
- // themeColor: "#2DBD60",
148
- // buttonText: { en: "Upload", fr: "Téléverser" }
149
- // },
150
- // config: {
151
- // allowed_formats: ["pdf", "jpg", "png"],
152
- // max_size_mb: 10,
153
- // required: true
154
- // } as const
155
- // },
156
-
157
136
  ]
158
137
  };
159
138
 
160
- export const TemplateKYCExample: React.FC<{
161
- onComplete: (data: VerificationState) => void;
162
- onCancel: () => void;
163
- onError: (error: string) => void;
164
- language: string;
139
+ export const TemplateKYCExample: React.FC<{
140
+ onComplete: (data: VerificationState) => void;
141
+ onCancel: () => void;
142
+ onError: (error: string) => void;
143
+ language: string;
165
144
  API_KEY?: string;
166
145
  templateId?: string;
167
146
  template?: KYCTemplate;
168
- }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template }) => {
147
+ env?: KycEnvironment;
148
+ existingSessionId?: string;
149
+ initialStep?: number;
150
+ }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template, env = 'PRODUCTION', existingSessionId, initialStep }) => {
169
151
  const handleComplete = (data: VerificationState) => {
170
152
  console.log('KYC Template completed with data:', data);
171
153
  onComplete(data);
@@ -182,24 +164,27 @@ export const TemplateKYCExample: React.FC<{
182
164
  onError(error);
183
165
  };
184
166
 
167
+ // Transform backend template to SDK format
185
168
  // Determine which template to use: prefer templateId for dynamic loading, then template prop, then fallback to hardcoded
186
169
  const templateToUse = templateId ? undefined : (template || advancedVerificationTemplate);
187
170
 
188
171
  return (
189
- <SafeAreaView style={{ flex: 1 , paddingVertical:25}}>
190
- <View style={{ flex: 1 }}>
191
- <TemplateKYCFlow
192
- template={templateToUse}
193
- templateId={templateId}
194
- onComplete={handleComplete}
195
- onError={handleError}
196
- onCancel={handleCancel}
197
- language={language} // ou "en" pour l'anglais
198
- API_KEY={API_KEY}
199
- />
200
- </View>
201
- </SafeAreaView>
172
+ <SafeAreaView style={{ flex: 1, paddingVertical: 25 }}>
173
+ <View style={{ flex: 1 }}>
174
+ <TemplateKYCFlow
175
+ template={templateToUse}
176
+ templateId={templateId}
177
+ onComplete={handleComplete}
178
+ onError={handleError}
179
+ onCancel={handleCancel}
180
+ language={language} // ou "en" pour l'anglais
181
+ API_KEY={API_KEY}
182
+ env={env}
183
+ existingSessionId={existingSessionId}
184
+ initialStep={initialStep}
185
+ />
186
+ </View>
187
+ </SafeAreaView>
202
188
  );
203
189
  };
204
190
 
205
-
@@ -14,6 +14,11 @@ import { ReviewSubmitTemplate } from './KYCElements/ReviewSubmitTemplate';
14
14
  import { VerificationProgressTemplate } from './KYCElements/VerificationProgressTemplate';
15
15
  import { useTemplateLoader } from '../hooks/useTemplateLoader';
16
16
  import { WelcomeTemplate } from './KYCElements/WelcomeTemplate';
17
+ import { EmailVerificationTemplate } from './KYCElements/EmailVerificationTemplate';
18
+ import { PhoneVerificationTemplate } from './KYCElements/PhoneVerificationTemplate';
19
+ import { PersonalInformationTemplate } from './KYCElements/PersonalInformationTemplate';
20
+ import { AdditionalDocumentsTemplate } from './KYCElements/AdditionalDocumentsTemplate';
21
+ import { KycEnvironment } from '../types/env.types';
17
22
 
18
23
  interface TemplateKYCFlowProps {
19
24
  template?: KYCTemplate; // Format SDK direct (existing, now optional)
@@ -23,6 +28,9 @@ interface TemplateKYCFlowProps {
23
28
  language?: string;
24
29
  onCancel?: () => void;
25
30
  API_KEY?: string; // Required if templateId is used
31
+ env?: KycEnvironment; // Environment mode: PRODUCTION or SANDBOX
32
+ existingSessionId?: string;
33
+ initialStep?: number; // Initial step index to resume verification
26
34
  }
27
35
 
28
36
  export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
@@ -33,6 +41,9 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
33
41
  language = 'fr',
34
42
  onCancel,
35
43
  API_KEY,
44
+ env = 'PRODUCTION',
45
+ existingSessionId,
46
+ initialStep,
36
47
  }) => {
37
48
  const { t } = useI18n();
38
49
  const { template: loadedTemplate, isLoading, error, loadTemplate } = useTemplateLoader();
@@ -123,6 +134,9 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
123
134
  onCancel={OnCancel}
124
135
  initialLanguage={language}
125
136
  apiKey={API_KEY}
137
+ env={env}
138
+ existingSessionId={existingSessionId}
139
+ initialStep={initialStep}
126
140
  >
127
141
  <TemplateKYCFlowContent onCancel={OnCancel} />
128
142
  </TemplateKYCFlowProvider>
@@ -187,6 +201,18 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
187
201
  case 'review_submit':
188
202
  return <ReviewSubmitTemplate {...commonProps} />;
189
203
 
204
+ case 'email_verification':
205
+ return <EmailVerificationTemplate {...commonProps} />;
206
+
207
+ case 'phone_verification':
208
+ return <PhoneVerificationTemplate {...commonProps} />;
209
+
210
+ case 'personal_information':
211
+ return <PersonalInformationTemplate {...commonProps} />;
212
+
213
+ case 'additional_documents':
214
+ return <AdditionalDocumentsTemplate {...commonProps} />;
215
+
190
216
  case 'verification_progress':
191
217
  return <VerificationProgressTemplate {...commonProps} />;
192
218
 
@@ -238,7 +264,7 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
238
264
  ) : null}
239
265
 
240
266
  {/* Contenu principal */}
241
- <ScrollView
267
+ <ScrollView
242
268
  style={styles.scrollView}
243
269
  contentContainerStyle={styles.content}
244
270
  showsVerticalScrollIndicator={Platform.OS === 'web'}
@@ -0,0 +1,34 @@
1
+ import { BackendEnvironment } from '../types/env.types';
2
+
3
+ class KYCConfig {
4
+ private static instance: KYCConfig;
5
+ private backendEnvironment: BackendEnvironment = 'PRODUCTION';
6
+
7
+ private backendUrls: Record<BackendEnvironment, string> = {
8
+ PRODUCTION: 'https://service.sanctumkey.com/api/v1',
9
+ TEST: 'https://test-service.sanctumkey.com/api/v1', // Placeholder URL
10
+ };
11
+
12
+ private constructor() { }
13
+
14
+ public static getInstance(): KYCConfig {
15
+ if (!KYCConfig.instance) {
16
+ KYCConfig.instance = new KYCConfig();
17
+ }
18
+ return KYCConfig.instance;
19
+ }
20
+
21
+ public setBackendEnvironment(env: BackendEnvironment) {
22
+ this.backendEnvironment = env;
23
+ }
24
+
25
+ public getBackendUrl(): string {
26
+ return this.backendUrls[this.backendEnvironment];
27
+ }
28
+
29
+ public getBackendEnvironment(): BackendEnvironment {
30
+ return this.backendEnvironment;
31
+ }
32
+ }
33
+
34
+ export default KYCConfig.getInstance();
@@ -16,6 +16,7 @@ const DEFAULT_CONFIG: AllowedDomainConfig = {
16
16
  'www.transfergratis.com',
17
17
  'admin.transfergratis.com',
18
18
  'dashboard.transfergratis.com',
19
+ 'preweb.transfergratis.net',
19
20
  // Add other trusted domains here
20
21
  ],
21
22
  enforceHttps: true,
@@ -45,7 +46,7 @@ export const getAllowedDomainsConfig = (): AllowedDomainConfig => {
45
46
  */
46
47
  export const isDomainAllowed = (domain: string): boolean => {
47
48
  const config = getAllowedDomainsConfig();
48
-
49
+
49
50
  // Allow localhost in development
50
51
  if (config.allowLocalhost && (domain === 'localhost' || domain.startsWith('127.0.0.1'))) {
51
52
  return true;
@@ -57,12 +58,12 @@ export const isDomainAllowed = (domain: string): boolean => {
57
58
  if (domain === allowedDomain) {
58
59
  return true;
59
60
  }
60
-
61
+
61
62
  // Subdomain match (e.g., app.transfergratis.com matches transfergratis.com)
62
63
  if (domain.endsWith('.' + allowedDomain)) {
63
64
  return true;
64
65
  }
65
-
66
+
66
67
  return false;
67
68
  });
68
69
  };
@@ -71,30 +72,10 @@ export const isDomainAllowed = (domain: string): boolean => {
71
72
  * Validate if a URL is allowed for callback
72
73
  */
73
74
  export const isCallbackUrlAllowed = (url: string): { allowed: boolean; reason?: string } => {
74
- const config = getAllowedDomainsConfig();
75
-
76
75
  try {
77
- const urlObj = new URL(url);
78
-
79
- // Check protocol
80
- if (config.enforceHttps && urlObj.protocol !== 'https:') {
81
- // Allow http for localhost in development
82
- if (!(config.allowLocalhost && (urlObj.hostname === 'localhost' || urlObj.hostname.startsWith('127.0.0.1')))) {
83
- return {
84
- allowed: false,
85
- reason: 'HTTPS required for callback URLs',
86
- };
87
- }
88
- }
89
-
90
- // Check domain
91
- if (!isDomainAllowed(urlObj.hostname)) {
92
- return {
93
- allowed: false,
94
- reason: `Domain '${urlObj.hostname}' is not in the allowed list`,
95
- };
96
- }
97
-
76
+ // Check if valid URL
77
+ new URL(url);
78
+ // Allow all URLs for redirection as requested
98
79
  return { allowed: true };
99
80
  } catch (error) {
100
81
  return {
@@ -6,6 +6,7 @@ import {
6
6
  OrientationVideoResult,
7
7
  OrientationType
8
8
  } from '../types/KYC.types';
9
+ import { KycEnvironment } from '../types/env.types';
9
10
  import kycService from '../modules/api/KYCService';
10
11
 
11
12
  export interface UseOrientationVideoReturn {
@@ -15,8 +16,8 @@ export interface UseOrientationVideoReturn {
15
16
  }
16
17
 
17
18
  export const useOrientationVideo = (
18
-
19
- config?: Partial<OrientationVideoConfig>
19
+ config?: Partial<OrientationVideoConfig>,
20
+ env: KycEnvironment = 'PRODUCTION'
20
21
  ): UseOrientationVideoReturn => {
21
22
  const defaultConfig: OrientationVideoConfig = {
22
23
  duration: 10,
@@ -66,7 +67,7 @@ export const useOrientationVideo = (
66
67
  setState(prev => ({ ...prev, isProcessing: true, error: null }));
67
68
 
68
69
  try {
69
- const result = await kycService.processOrientationVideo(state.recordedVideo);
70
+ const result = await kycService.processOrientationVideo(state.recordedVideo, env);
70
71
 
71
72
  if (result.success && result.data) {
72
73
  setState(prev => ({
@@ -93,7 +94,7 @@ export const useOrientationVideo = (
93
94
  }));
94
95
  throw error;
95
96
  }
96
- }, [state.recordedVideo, state.isProcessing, kycService]);
97
+ }, [state.recordedVideo, state.isProcessing, env]);
97
98
 
98
99
  const retake = useCallback(() => {
99
100
  if (state.retakeCount >= finalConfig.maxRetakes) {