@transfergratis/react-native-sdk 0.1.30 → 0.1.32

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.
@@ -149,7 +149,8 @@ export const TemplateKYCExample: React.FC<{
149
149
  existingSessionId?: string;
150
150
  initialComponentIndex?: number;
151
151
  initialCountryResume?: { code: string; documentType: string; region?: string };
152
- }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template, env = 'PRODUCTION', serverEnv, existingSessionId, initialComponentIndex, initialCountryResume }) => {
152
+ onSessionSave?: (sessionId: string) => void;
153
+ }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template, env = 'PRODUCTION', serverEnv, existingSessionId, initialComponentIndex, initialCountryResume, onSessionSave }) => {
153
154
  const handleComplete = (data: VerificationState) => {
154
155
  console.log('KYC Template completed with data:', data);
155
156
  onComplete(data);
@@ -186,6 +187,7 @@ export const TemplateKYCExample: React.FC<{
186
187
  existingSessionId={existingSessionId}
187
188
  initialComponentIndex={initialComponentIndex}
188
189
  initialCountryResume={initialCountryResume}
190
+ onSessionSave={onSessionSave}
189
191
  />
190
192
  </View>
191
193
  </SafeAreaView>
@@ -36,6 +36,7 @@ interface TemplateKYCFlowProps {
36
36
  initialComponentIndex?: number;
37
37
  /** Pays / type de document depuis l'URL de reprise (reprise multi-appareil) */
38
38
  initialCountryResume?: { code: string; documentType: string; region?: string };
39
+ onSessionSave?: (sessionId: string) => void;
39
40
  }
40
41
 
41
42
  export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
@@ -51,6 +52,7 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
51
52
  existingSessionId,
52
53
  initialComponentIndex,
53
54
  initialCountryResume,
55
+ onSessionSave,
54
56
  }) => {
55
57
  const { t } = useI18n();
56
58
  const { template: loadedTemplate, isLoading, error, loadTemplate } = useTemplateLoader();
@@ -152,6 +154,7 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
152
154
  existingSessionId={existingSessionId}
153
155
  initialComponentIndex={initialComponentIndex}
154
156
  initialCountryResume={initialCountryResume}
157
+ onSessionSave={onSessionSave}
155
158
  >
156
159
  <TemplateKYCFlowContent onCancel={OnCancel} />
157
160
  </TemplateKYCFlowProvider>
@@ -73,7 +73,7 @@
73
73
  "identity_card": {
74
74
  "root": [
75
75
  {
76
- "py_file": "cameroon_id_back_1_1.py",
76
+ "py_file": "cameroon_id_back_1_1_new.py",
77
77
  "back": "MRZ",
78
78
  "mrz_type": "TD1"
79
79
  },
@@ -96,11 +96,7 @@
96
96
  "mrz_type": "TD1"
97
97
  },
98
98
  {
99
- "py_file": "cameroon_id_front_1_1.py",
100
- "keys_found": null
101
- },
102
- {
103
- "py_file": "cameroon_id_front_2_1.py",
99
+ "py_file": "cameroon_id_front_1_1_new.py",
104
100
  "keys_found": null
105
101
  },
106
102
  {
@@ -599,30 +595,26 @@
599
595
  "identity_card": {
600
596
  "root": [
601
597
  {
602
- "py_file": "back_1.py",
598
+ "py_file": "back_2.py",
603
599
  "back": "MRZ",
604
600
  "mrz_type": "TD1"
605
601
  },
606
602
  {
607
- "py_file": "back_2.py",
608
- "back": "MRZ",
609
- "mrz_type": "TD1"
603
+ "py_file": "front_3.py",
604
+ "keys_found": null
610
605
  },
611
606
  {
612
- "py_file": "back_3.py",
607
+ "py_file": "kenya_back_1.py",
613
608
  "back": "MRZ",
614
609
  "mrz_type": "TD1"
615
610
  },
616
611
  {
617
- "py_file": "front_1.py",
618
- "keys_found": null
619
- },
620
- {
621
- "py_file": "front_2.py",
622
- "keys_found": null
612
+ "py_file": "kenya_back_3.py",
613
+ "back": "MRZ",
614
+ "mrz_type": "TD1"
623
615
  },
624
616
  {
625
- "py_file": "front_3.py",
617
+ "py_file": "kenya_front_2.py",
626
618
  "keys_found": null
627
619
  }
628
620
  ]
@@ -75,7 +75,7 @@ export const countryMapping: Record<string, Record<string, Record<string, ICount
75
75
  "identity_card": {
76
76
  "root": [
77
77
  {
78
- "py_file": "cameroon_id_back_1_1.py",
78
+ "py_file": "cameroon_id_back_1_1_new.py",
79
79
  "back": "MRZ",
80
80
  "mrz_type": "TD1"
81
81
  },
@@ -98,11 +98,7 @@ export const countryMapping: Record<string, Record<string, Record<string, ICount
98
98
  "mrz_type": "TD1"
99
99
  },
100
100
  {
101
- "py_file": "cameroon_id_front_1_1.py",
102
- "keys_found": null
103
- },
104
- {
105
- "py_file": "cameroon_id_front_2_1.py",
101
+ "py_file": "cameroon_id_front_1_1_new.py",
106
102
  "keys_found": null
107
103
  },
108
104
  {
@@ -601,30 +597,26 @@ export const countryMapping: Record<string, Record<string, Record<string, ICount
601
597
  "identity_card": {
602
598
  "root": [
603
599
  {
604
- "py_file": "back_1.py",
600
+ "py_file": "back_2.py",
605
601
  "back": "MRZ",
606
602
  "mrz_type": "TD1"
607
603
  },
608
604
  {
609
- "py_file": "back_2.py",
610
- "back": "MRZ",
611
- "mrz_type": "TD1"
605
+ "py_file": "front_3.py",
606
+ "keys_found": null
612
607
  },
613
608
  {
614
- "py_file": "back_3.py",
609
+ "py_file": "kenya_back_1.py",
615
610
  "back": "MRZ",
616
611
  "mrz_type": "TD1"
617
612
  },
618
613
  {
619
- "py_file": "front_1.py",
620
- "keys_found": null
621
- },
622
- {
623
- "py_file": "front_2.py",
624
- "keys_found": null
614
+ "py_file": "kenya_back_3.py",
615
+ "back": "MRZ",
616
+ "mrz_type": "TD1"
625
617
  },
626
618
  {
627
- "py_file": "front_3.py",
619
+ "py_file": "kenya_front_2.py",
628
620
  "keys_found": null
629
621
  }
630
622
  ]
@@ -1,4 +1,4 @@
1
- import React, { useState, useCallback, useMemo, createContext, useContext, ReactNode, useEffect } from 'react';
1
+ import React, { useState, useCallback, useMemo, createContext, useContext, ReactNode, useEffect, useRef } from 'react';
2
2
  import { KYCTemplate, TemplateState, TemplateActions, UseTemplateReturn, TemplateComponent, GovernmentDocumentType, VerificationState } from '../types/KYC.types';
3
3
  import { KycEnvironment } from '../types/env.types';
4
4
  import kycService, { authentification, truncateFields } from '../modules/api/KYCService';
@@ -39,6 +39,7 @@ interface TemplateKYCFlowProviderProps {
39
39
  initialComponentIndex?: number;
40
40
  /** Pays / type de document depuis l'URL de reprise — évite de dépendre du backend pour afficher les pays. */
41
41
  initialCountryResume?: { code: string; documentType: string; region?: string };
42
+ onSessionSave?: (sessionId: string) => void;
42
43
  }
43
44
 
44
45
  export const TemplateKYCFlowProvider: React.FC<TemplateKYCFlowProviderProps> = ({
@@ -53,8 +54,9 @@ export const TemplateKYCFlowProvider: React.FC<TemplateKYCFlowProviderProps> = (
53
54
  existingSessionId,
54
55
  initialComponentIndex,
55
56
  initialCountryResume,
57
+ onSessionSave,
56
58
  }) => {
57
- const hookResult = useTemplateKYCFlow(template, onComplete, onError, onCancel, initialLanguage, apiKey, env, existingSessionId, initialComponentIndex, initialCountryResume);
59
+ const hookResult = useTemplateKYCFlow(template, onComplete, onError, onCancel, initialLanguage, apiKey, env, existingSessionId, initialComponentIndex, initialCountryResume, onSessionSave);
58
60
 
59
61
  return (
60
62
  <TemplateKYCFlowContext.Provider value={hookResult}>
@@ -83,6 +85,7 @@ export const useTemplateKYCFlow = (
83
85
  existingSessionId?: string,
84
86
  initialComponentIndex?: number,
85
87
  initialCountryResume?: { code: string; documentType: string; region?: string },
88
+ onSessionSave?: (sessionId: string) => void,
86
89
  ): UseTemplateReturn => {
87
90
 
88
91
  const { setLocale } = useI18n();
@@ -253,6 +256,7 @@ export const useTemplateKYCFlow = (
253
256
 
254
257
  // État du flux
255
258
  const [state, setState] = useState<TemplateState>(() => buildInitialState());
259
+ const hasSavedSessionRef = useRef(false);
256
260
 
257
261
  // Fonction utilitaire pour convertir base64 en data URI pour l'affichage
258
262
  const base64ToDataUri = useCallback((base64: string, mimeType: string = 'image/jpeg'): string => {
@@ -723,6 +727,15 @@ export const useTemplateKYCFlow = (
723
727
  initializeSession();
724
728
  }, [existingSessionId, state.session.session_id, state.session.isInitialized, initializeSession]);
725
729
 
730
+ // Emit session id once when session becomes available.
731
+ useEffect(() => {
732
+ if (!onSessionSave || hasSavedSessionRef.current) return;
733
+ if (!state.session.isInitialized || !state.session.session_id) return;
734
+
735
+ hasSavedSessionRef.current = true;
736
+ onSessionSave(state.session.session_id);
737
+ }, [onSessionSave, state.session.isInitialized, state.session.session_id]);
738
+
726
739
  // Validation d'un composant (dataOverride permet de valider sans attendre la mise à jour du state)
727
740
  const validateComponent = useCallback((componentId: number, dataOverride?: any): boolean => {
728
741
  const component = state.template.components.find(c => c.id === componentId);
@@ -12,12 +12,14 @@ interface WebKYCEntryProps {
12
12
  onComplete?: (data: any) => void;
13
13
  onError?: (error: string) => void;
14
14
  onCancel?: () => void;
15
+ onSessionSave?: (sessionId: string) => void;
15
16
  }
16
17
 
17
18
  interface URLParams {
18
19
  token?: string;
19
20
  return_url?: string;
20
21
  push_url?: string;
22
+ save_session_url?: string;
21
23
  lang?: string;
22
24
  theme?: string;
23
25
  kyc_id?: string;
@@ -42,6 +44,7 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
42
44
  onComplete,
43
45
  onError,
44
46
  onCancel,
47
+ onSessionSave,
45
48
  }) => {
46
49
  const { setLocale } = useI18n();
47
50
  const [urlParams, setUrlParams] = useState<URLParams>({});
@@ -66,6 +69,7 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
66
69
  token: urlParams.get('token') || undefined,
67
70
  return_url: urlParams.get('return_url') || undefined,
68
71
  push_url: urlParams.get('push_url') || undefined,
72
+ save_session_url: urlParams.get('save_session_url') || undefined,
69
73
  lang: urlParams.get('lang') || 'en',
70
74
  theme: urlParams.get('theme') || 'light',
71
75
  kyc_id: urlParams.get('kyc_id') || undefined,
@@ -234,6 +238,42 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
234
238
  onCancel?.();
235
239
  }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
236
240
 
241
+ const handleSessionSave = useCallback(async (sessionId: string) => {
242
+ console.log('KYC session created:', sessionId);
243
+
244
+ if (urlParams.save_session_url) {
245
+ try {
246
+ const payload = {
247
+ status: 'session_created',
248
+ result: {
249
+ session_id: sessionId,
250
+ kyc_id: sessionId,
251
+ },
252
+ };
253
+
254
+ const controller = new AbortController();
255
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
256
+
257
+ await fetch(urlParams.save_session_url, {
258
+ method: 'POST',
259
+ headers: {
260
+ 'Content-Type': 'application/json',
261
+ },
262
+ body: JSON.stringify(payload),
263
+ signal: controller.signal,
264
+ });
265
+
266
+ clearTimeout(timeoutId);
267
+ console.log('Successfully pushed session data to save_session_url');
268
+ } catch (err) {
269
+ // Fail open - do not block the KYC flow if save_session webhook fails
270
+ console.warn('Failed to push session data to save_session_url:', err);
271
+ }
272
+ }
273
+
274
+ onSessionSave?.(sessionId);
275
+ }, [urlParams.save_session_url, onSessionSave]);
276
+
237
277
  // Initialize component
238
278
  useEffect(() => {
239
279
  try {
@@ -311,6 +351,7 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
311
351
  return Number.isNaN(index) ? undefined : index;
312
352
  })()}
313
353
  initialCountryResume={urlParams.country && urlParams.document_type ? { code: urlParams.country, documentType: urlParams.document_type, region: urlParams.region || undefined } : undefined}
354
+ onSessionSave={handleSessionSave}
314
355
  />
315
356
  </SafeAreaView>
316
357
  );