@transfergratis/react-native-sdk 0.1.16 → 0.1.18
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 -1
- package/build/components/KYCElements/IDCardCapture.js +4 -4
- package/build/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/components/KYCElements/VerificationProgressTemplate.js +3 -3
- package/build/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
- package/build/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/components/TemplateKYCExample.js +5 -8
- package/build/components/TemplateKYCExample.js.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.js +7 -2
- package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
- package/build/i18n/en/index.d.ts +1 -0
- package/build/i18n/en/index.d.ts.map +1 -1
- package/build/i18n/en/index.js +2 -1
- package/build/i18n/en/index.js.map +1 -1
- package/build/i18n/fr/index.d.ts +1 -0
- package/build/i18n/fr/index.d.ts.map +1 -1
- package/build/i18n/fr/index.js +2 -1
- package/build/i18n/fr/index.js.map +1 -1
- package/build/modules/api/KYCService.d.ts.map +1 -1
- package/build/modules/api/KYCService.js +12 -6
- package/build/modules/api/KYCService.js.map +1 -1
- package/build/utils/cropByObb.js +3 -3
- package/build/utils/cropByObb.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KYCElements/IDCardCapture.tsx +9 -9
- package/src/components/KYCElements/VerificationProgressTemplate.tsx +10 -10
- package/src/components/TemplateKYCExample.tsx +6 -8
- package/src/components/TemplateKYCFlowRefactored.tsx +10 -3
- package/src/i18n/en/index.ts +2 -1
- package/src/i18n/fr/index.ts +2 -1
- package/src/modules/api/KYCService.ts +12 -7
- package/src/utils/cropByObb.ts +3 -3
|
@@ -139,7 +139,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
139
139
|
setShowCamera(true);
|
|
140
140
|
actions.showCustomStepper(false);
|
|
141
141
|
setCapturedImages({ ...capturedImages, [currentSide]: { dir: '', file: '', mrz: '' } });
|
|
142
|
-
setSilentCaptureResult((prev) => ({ path: '', success: false, isAnalyzing: false, error: '' }));
|
|
142
|
+
setSilentCaptureResult((prev) => ({ ...prev, path: '', success: false, isAnalyzing: false, error: '' }));
|
|
143
143
|
setCropImageUri('');
|
|
144
144
|
onValueChange({ ...value, [currentSide]: { dir: '', file: '', mrz: '' } });
|
|
145
145
|
};
|
|
@@ -212,7 +212,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
212
212
|
|
|
213
213
|
const regionMappings = getCurrentSideVerification(currentSide)
|
|
214
214
|
// logger.log("regionMappings", JSON.stringify(truncateFields({regionMappings, templatePath}), null, 2));
|
|
215
|
-
if (
|
|
215
|
+
if (templatePath.length === 0) {
|
|
216
216
|
try {
|
|
217
217
|
const templateType = await checkTemplateType({ path: result.path || '', docType: selectedDocumentType?.type as GovernmentDocumentType, docRegion: countryData?.code || "", postfix: currentSide });
|
|
218
218
|
|
|
@@ -224,9 +224,9 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
224
224
|
if (templateType.card_obb) {
|
|
225
225
|
let bbox: IBbox | undefined;
|
|
226
226
|
try {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
227
|
+
const crop = await cropByObb(result?.path || '', (templateType as any).card_obb);
|
|
228
|
+
bbox = crop.bbox;
|
|
229
|
+
templateBbox = bbox;
|
|
230
230
|
} catch { }
|
|
231
231
|
}
|
|
232
232
|
} catch (e: any) {
|
|
@@ -250,7 +250,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
250
250
|
logger.log("front verification result", truncateFields(mrz));
|
|
251
251
|
const bbox = (mrz as any)?.bbox || templateBbox;
|
|
252
252
|
setSilentCaptureResult((prev) => ({
|
|
253
|
-
...prev,
|
|
253
|
+
...prev,
|
|
254
254
|
path: result.path,
|
|
255
255
|
templatePath: templatePath,
|
|
256
256
|
bbox: bbox, success: true,
|
|
@@ -286,7 +286,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
286
286
|
success: true, mrz: JSON.stringify(mrz), isAnalyzing: false,
|
|
287
287
|
country: countryData?.code,
|
|
288
288
|
documentType: selectedDocumentType?.type,
|
|
289
|
-
|
|
289
|
+
|
|
290
290
|
}));
|
|
291
291
|
// Stocker le bbox pour ce côté
|
|
292
292
|
if (bbox && typeof bbox === 'object') {
|
|
@@ -345,7 +345,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
345
345
|
const handleDocumentTypeSelection = (docType: GovernmentDocumentType) => {
|
|
346
346
|
setSelectedDocumentType({ type: docType, region: hasRegions(docType) ? '' : 'root' });
|
|
347
347
|
setSilentCaptureResult((prev) => ({ ...prev, templatePath: '', bbox: undefined, success: false, isAnalyzing: false, error: '', path: '', mrz: '', country: '', documentType: '' }));
|
|
348
|
-
setCapturedImages((prev) => ({
|
|
348
|
+
setCapturedImages((prev) => ({ front: { dir: '', file: '', mrz: '', templatePath: '' }, back: { dir: '', file: '', mrz: '', templatePath: '' } }));
|
|
349
349
|
};
|
|
350
350
|
const handleRegionSelection = (region: string) => {
|
|
351
351
|
setSelectedDocumentType((prev) => ({ ...prev, region: region }));
|
|
@@ -522,7 +522,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
522
522
|
<ScrollView style={styles.previewItemContainer} showsVerticalScrollIndicator={false}>
|
|
523
523
|
<View key={currentSide} style={styles.sideContainer}>
|
|
524
524
|
<Text style={styles.sideTitle}>
|
|
525
|
-
{currentSide === 'front' ? 'Recto' : '
|
|
525
|
+
{t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
|
|
526
526
|
</Text>
|
|
527
527
|
<Text style={{ fontSize: 14, color: '#666', textAlign: 'center', marginBottom: 16, lineHeight: 22 }}>
|
|
528
528
|
{getLocalizedText(component.instructions)}
|
|
@@ -3,7 +3,7 @@ import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
|
|
3
3
|
import { TemplateComponent } from '../../types/KYC.types';
|
|
4
4
|
import { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';
|
|
5
5
|
import { useI18n } from '../../hooks/useI18n';
|
|
6
|
-
import kycService from '../../modules/api/KYCService';
|
|
6
|
+
import kycService, { errorMessage } from '../../modules/api/KYCService';
|
|
7
7
|
import { logger } from '../../utils/logger';
|
|
8
8
|
|
|
9
9
|
interface VerificationProgressTemplateProps {
|
|
@@ -30,7 +30,7 @@ export const VerificationProgressTemplate: React.FC<VerificationProgressTemplate
|
|
|
30
30
|
const getVerificationResult = async (currentRetryCount = 0, maxRetries = 40) => {
|
|
31
31
|
try {
|
|
32
32
|
logger.log(`Starting verification check (attempt ${currentRetryCount + 1}/${maxRetries + 1})`);
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
const result = await kycService.getVerificationResult(state.session.session_id);
|
|
35
35
|
const verificationResult = result[state.session.session_id].data;
|
|
36
36
|
|
|
@@ -42,7 +42,7 @@ export const VerificationProgressTemplate: React.FC<VerificationProgressTemplate
|
|
|
42
42
|
const nextRetryCount = currentRetryCount + 1;
|
|
43
43
|
setRetryCount(nextRetryCount);
|
|
44
44
|
setIsRetrying(true);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
logger.log(`Verification still processing, retrying in 10s... (${nextRetryCount}/${maxRetries})`);
|
|
47
47
|
|
|
48
48
|
// Nettoyer le timeout précédent s'il existe
|
|
@@ -54,7 +54,7 @@ export const VerificationProgressTemplate: React.FC<VerificationProgressTemplate
|
|
|
54
54
|
const newTimeoutId = setTimeout(() => {
|
|
55
55
|
getVerificationResult(nextRetryCount, maxRetries);
|
|
56
56
|
}, 10000);
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
setTimeoutId(newTimeoutId);
|
|
59
59
|
return; // Sortir de la fonction pour éviter de traiter le résultat
|
|
60
60
|
} else {
|
|
@@ -87,25 +87,25 @@ export const VerificationProgressTemplate: React.FC<VerificationProgressTemplate
|
|
|
87
87
|
setIsRetrying(false);
|
|
88
88
|
|
|
89
89
|
} catch (error) {
|
|
90
|
-
logger.error('getVerificationResult error', error);
|
|
90
|
+
logger.error('getVerificationResult error', JSON.stringify(errorMessage(error), null, 2));
|
|
91
91
|
|
|
92
92
|
// En cas d'erreur, on peut aussi retry
|
|
93
93
|
if (currentRetryCount < maxRetries) {
|
|
94
94
|
const nextRetryCount = currentRetryCount + 1;
|
|
95
95
|
setRetryCount(nextRetryCount);
|
|
96
96
|
setIsRetrying(true);
|
|
97
|
-
|
|
98
|
-
logger.log(`Error occurred, retrying in 10s... (${nextRetryCount}/${maxRetries})`);
|
|
99
|
-
|
|
97
|
+
|
|
98
|
+
logger.log(`getVerificationResult Error occurred, retrying in 10s... (${nextRetryCount}/${maxRetries})`);
|
|
99
|
+
|
|
100
100
|
// Nettoyer le timeout précédent s'il existe
|
|
101
101
|
if (timeoutId) {
|
|
102
102
|
clearTimeout(timeoutId);
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
const newTimeoutId = setTimeout(() => {
|
|
106
106
|
getVerificationResult(nextRetryCount, maxRetries);
|
|
107
107
|
}, 10000);
|
|
108
|
-
|
|
108
|
+
|
|
109
109
|
setTimeoutId(newTimeoutId);
|
|
110
110
|
} else {
|
|
111
111
|
setIsRetrying(false);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { View,
|
|
2
|
+
import { View, SafeAreaView } from 'react-native';
|
|
3
3
|
import { TemplateKYCFlow } from './TemplateKYCFlowRefactored';
|
|
4
4
|
import { KYCTemplate, VerificationState } from '../types/KYC.types';
|
|
5
5
|
|
|
@@ -56,7 +56,7 @@ const advancedVerificationTemplate: KYCTemplate = {
|
|
|
56
56
|
buttonText: { en: "Confirm", fr: "Confirmer" }
|
|
57
57
|
},
|
|
58
58
|
config: {
|
|
59
|
-
allowed_countries: ["CM", "NG", "CI", "KE","GH"],
|
|
59
|
+
allowed_countries: ["CM", "NG", "CI", "KE", "GH"],
|
|
60
60
|
default_country: "CM",
|
|
61
61
|
required: true
|
|
62
62
|
} as const
|
|
@@ -242,7 +242,8 @@ export const TemplateKYCExample: React.FC<{ onComplete: (data: VerificationState
|
|
|
242
242
|
};
|
|
243
243
|
|
|
244
244
|
return (
|
|
245
|
-
<
|
|
245
|
+
<SafeAreaView style={{ flex: 1 , paddingVertical:25}}>
|
|
246
|
+
<View style={{ flex: 1 }}>
|
|
246
247
|
<TemplateKYCFlow
|
|
247
248
|
template={advancedVerificationTemplate}
|
|
248
249
|
onComplete={handleComplete}
|
|
@@ -252,11 +253,8 @@ export const TemplateKYCExample: React.FC<{ onComplete: (data: VerificationState
|
|
|
252
253
|
API_KEY={API_KEY}
|
|
253
254
|
/>
|
|
254
255
|
</View>
|
|
256
|
+
</SafeAreaView>
|
|
255
257
|
);
|
|
256
258
|
};
|
|
257
259
|
|
|
258
|
-
|
|
259
|
-
container: {
|
|
260
|
-
flex: 1,
|
|
261
|
-
},
|
|
262
|
-
});
|
|
260
|
+
|
|
@@ -30,7 +30,7 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
|
|
|
30
30
|
API_KEY,
|
|
31
31
|
}) => {
|
|
32
32
|
const { t } = useI18n();
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
const OnCancel = () => {
|
|
35
35
|
Alert.alert(
|
|
36
36
|
t('kyc.cancelConfirmation.title'),
|
|
@@ -130,7 +130,7 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
|
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
return (
|
|
133
|
-
<View style={{ flex: 1 }}>
|
|
133
|
+
<View style={{ flex: 1, position: 'relative' }}>
|
|
134
134
|
{state.isProcessing && (
|
|
135
135
|
<View style={styles.processingContainer}>
|
|
136
136
|
<Text style={styles.processingText}>{t('common.loading')}</Text>
|
|
@@ -169,6 +169,13 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
|
|
|
169
169
|
<View style={styles.content}>
|
|
170
170
|
{renderCurrentComponent()}
|
|
171
171
|
</View>
|
|
172
|
+
|
|
173
|
+
{state.isProcessing && (
|
|
174
|
+
<View style={styles.processingContainer}>
|
|
175
|
+
<Text style={styles.processingText}>{t('common.loading')}</Text>
|
|
176
|
+
<ActivityIndicator size="large" color="#fff" />
|
|
177
|
+
</View>
|
|
178
|
+
)}
|
|
172
179
|
</SafeAreaView>
|
|
173
180
|
</View>
|
|
174
181
|
|
|
@@ -300,7 +307,7 @@ const styles = StyleSheet.create({
|
|
|
300
307
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
301
308
|
justifyContent: 'center',
|
|
302
309
|
alignItems: 'center',
|
|
303
|
-
zIndex:
|
|
310
|
+
zIndex: 10000000,
|
|
304
311
|
},
|
|
305
312
|
processingText: {
|
|
306
313
|
fontSize: 16,
|
package/src/i18n/en/index.ts
CHANGED
|
@@ -86,7 +86,8 @@ export const en = {
|
|
|
86
86
|
usePhotoButton: 'Use This Photo',
|
|
87
87
|
processing: 'Processing image...',
|
|
88
88
|
success: 'ID captured successfully',
|
|
89
|
-
error: 'Failed to capture ID. Please try again.'
|
|
89
|
+
error: 'Failed to capture ID. Please try again.',
|
|
90
|
+
captureTitle: '%{side} side of your government document',
|
|
90
91
|
},
|
|
91
92
|
|
|
92
93
|
// Selfie Capture
|
package/src/i18n/fr/index.ts
CHANGED
|
@@ -86,7 +86,8 @@ export const fr = {
|
|
|
86
86
|
usePhotoButton: 'Utiliser Cette Photo',
|
|
87
87
|
processing: 'Traitement de l\'image...',
|
|
88
88
|
success: 'Document d\'identité capturé avec succès',
|
|
89
|
-
error: 'Échec de la capture du document. Veuillez réessayer.'
|
|
89
|
+
error: 'Échec de la capture du document. Veuillez réessayer.',
|
|
90
|
+
captureTitle: '%{side} de votre document d\'identité',
|
|
90
91
|
},
|
|
91
92
|
|
|
92
93
|
// Selfie Capture
|
|
@@ -226,9 +226,9 @@ export class KYCService {
|
|
|
226
226
|
const rnFile: any = { uri: fileUri, type: 'image/jpeg', name: 'id_card_front.jpg' };
|
|
227
227
|
formData.append('file', rnFile);
|
|
228
228
|
const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType];
|
|
229
|
-
logger.log('checkTemplateType params', this.mrzServiceURL, JSON.stringify({ fileUri, docTypeShorted, docRegion, token, postfix }, null, 2));
|
|
230
229
|
const url = `${this.mrzServiceURL}/get_template_version/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${postfix}`;
|
|
231
230
|
|
|
231
|
+
logger.log('checkTemplateType params', this.mrzServiceURL, JSON.stringify({ fileUri, docTypeShorted, docRegion, token, postfix, url }, null, 2));
|
|
232
232
|
try {
|
|
233
233
|
const res = await axios.post<CheckTemplateTypeResponse>(url, formData, {
|
|
234
234
|
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },
|
|
@@ -436,12 +436,17 @@ export class KYCService {
|
|
|
436
436
|
}
|
|
437
437
|
// reultat de la verification
|
|
438
438
|
async getVerificationResult(session_id: string): Promise<VerificationResult> {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
439
|
+
try {
|
|
440
|
+
const token = await authentification();
|
|
441
|
+
const url = `${this.backendServiceURL}/verification/api/kyc/result/?session_id=${session_id}`;
|
|
442
|
+
const res = await axios.get<VerificationResult>(url,
|
|
443
|
+
{ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } });
|
|
444
|
+
logger.log('getVerificationResult res', JSON.stringify(truncateFields(res.data), null, 2));
|
|
445
|
+
return res.data;
|
|
446
|
+
} catch (error) {
|
|
447
|
+
logger.error('Error getting verification result:', JSON.stringify(errorMessage(error), null, 2));
|
|
448
|
+
throw error;
|
|
449
|
+
}
|
|
445
450
|
}
|
|
446
451
|
}
|
|
447
452
|
|
package/src/utils/cropByObb.ts
CHANGED
|
@@ -82,9 +82,9 @@ export async function cropImageWithBBox(uri: string, bbox: any) {
|
|
|
82
82
|
// 3️⃣ Convertir le bbox à la taille réelle scale 0.10 = 10%
|
|
83
83
|
const crop = {
|
|
84
84
|
originX: bbox.minX ,
|
|
85
|
-
originY: bbox.minY
|
|
86
|
-
width: bbox.width
|
|
87
|
-
height: bbox.height
|
|
85
|
+
originY: bbox.minY ,
|
|
86
|
+
width: bbox.width ,
|
|
87
|
+
height: bbox.height,
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
// 4️⃣ Appliquer le crop
|