@transfergratis/react-native-sdk 0.1.24 → 0.1.26

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 (182) 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 +22 -7
  14. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  15. package/build/components/EnhancedCameraView.web.js +76 -21
  16. package/build/components/EnhancedCameraView.web.js.map +1 -1
  17. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts +12 -0
  18. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts.map +1 -0
  19. package/build/components/KYCElements/AdditionalDocumentsTemplate.js +283 -0
  20. package/build/components/KYCElements/AdditionalDocumentsTemplate.js.map +1 -0
  21. package/build/components/KYCElements/EmailVerificationTemplate.d.ts +12 -0
  22. package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
  23. package/build/components/KYCElements/EmailVerificationTemplate.js +212 -0
  24. package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
  25. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  26. package/build/components/KYCElements/IDCardCapture.js +216 -14
  27. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  28. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -0
  29. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  30. package/build/components/KYCElements/OrientationVideoCapture.js +2 -2
  31. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  32. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -0
  33. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  34. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +2 -2
  35. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  36. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -0
  37. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  38. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +2 -2
  39. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  40. package/build/components/KYCElements/PersonalInformationTemplate.d.ts +12 -0
  41. package/build/components/KYCElements/PersonalInformationTemplate.d.ts.map +1 -0
  42. package/build/components/KYCElements/PersonalInformationTemplate.js +120 -0
  43. package/build/components/KYCElements/PersonalInformationTemplate.js.map +1 -0
  44. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts +12 -0
  45. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -0
  46. package/build/components/KYCElements/PhoneVerificationTemplate.js +185 -0
  47. package/build/components/KYCElements/PhoneVerificationTemplate.js.map +1 -0
  48. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  49. package/build/components/KYCElements/SelfieCaptureTemplate.js +7 -3
  50. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  51. package/build/components/KYCElements/WelcomeTemplate.js +2 -1
  52. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -1
  53. package/build/components/OverLay/type.d.ts +2 -0
  54. package/build/components/OverLay/type.d.ts.map +1 -1
  55. package/build/components/OverLay/type.js.map +1 -1
  56. package/build/components/TemplateKYCExample.d.ts +10 -0
  57. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  58. package/build/components/TemplateKYCExample.js +7 -30
  59. package/build/components/TemplateKYCExample.js.map +1 -1
  60. package/build/components/TemplateKYCFlowRefactored.d.ts +12 -0
  61. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  62. package/build/components/TemplateKYCFlowRefactored.js +25 -3
  63. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  64. package/build/config/KYCConfig.d.ts +14 -0
  65. package/build/config/KYCConfig.d.ts.map +1 -0
  66. package/build/config/KYCConfig.js +26 -0
  67. package/build/config/KYCConfig.js.map +1 -0
  68. package/build/config/allowedDomains.d.ts.map +1 -1
  69. package/build/config/allowedDomains.js +4 -19
  70. package/build/config/allowedDomains.js.map +1 -1
  71. package/build/hooks/useOrientationVideo.d.ts +2 -1
  72. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  73. package/build/hooks/useOrientationVideo.js +3 -3
  74. package/build/hooks/useOrientationVideo.js.map +1 -1
  75. package/build/hooks/useTemplateKYCFlow.d.ts +18 -1
  76. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  77. package/build/hooks/useTemplateKYCFlow.js +410 -56
  78. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  79. package/build/i18n/en/index.d.ts +42 -0
  80. package/build/i18n/en/index.d.ts.map +1 -1
  81. package/build/i18n/en/index.js +44 -2
  82. package/build/i18n/en/index.js.map +1 -1
  83. package/build/i18n/fr/index.d.ts +28 -0
  84. package/build/i18n/fr/index.d.ts.map +1 -1
  85. package/build/i18n/fr/index.js +30 -2
  86. package/build/i18n/fr/index.js.map +1 -1
  87. package/build/i18n/types.d.ts +2 -0
  88. package/build/i18n/types.d.ts.map +1 -1
  89. package/build/i18n/types.js.map +1 -1
  90. package/build/index.d.ts +1 -0
  91. package/build/index.d.ts.map +1 -1
  92. package/build/index.js +2 -0
  93. package/build/index.js.map +1 -1
  94. package/build/modules/api/CardAuthentification.d.ts +24 -3
  95. package/build/modules/api/CardAuthentification.d.ts.map +1 -1
  96. package/build/modules/api/CardAuthentification.js +90 -12
  97. package/build/modules/api/CardAuthentification.js.map +1 -1
  98. package/build/modules/api/KYCService.d.ts +17 -7
  99. package/build/modules/api/KYCService.d.ts.map +1 -1
  100. package/build/modules/api/KYCService.js +125 -37
  101. package/build/modules/api/KYCService.js.map +1 -1
  102. package/build/modules/api/SelfieVerification.d.ts +3 -1
  103. package/build/modules/api/SelfieVerification.d.ts.map +1 -1
  104. package/build/modules/api/SelfieVerification.js +17 -1
  105. package/build/modules/api/SelfieVerification.js.map +1 -1
  106. package/build/modules/api/TemplateService.d.ts +0 -1
  107. package/build/modules/api/TemplateService.d.ts.map +1 -1
  108. package/build/modules/api/TemplateService.js +3 -3
  109. package/build/modules/api/TemplateService.js.map +1 -1
  110. package/build/modules/camera/VisionCameraModule.web.d.ts.map +1 -1
  111. package/build/modules/camera/VisionCameraModule.web.js +27 -8
  112. package/build/modules/camera/VisionCameraModule.web.js.map +1 -1
  113. package/build/types/KYC.types.d.ts +130 -5
  114. package/build/types/KYC.types.d.ts.map +1 -1
  115. package/build/types/KYC.types.js.map +1 -1
  116. package/build/types/env.types.d.ts +13 -0
  117. package/build/types/env.types.d.ts.map +1 -0
  118. package/build/types/env.types.js +2 -0
  119. package/build/types/env.types.js.map +1 -0
  120. package/build/utils/cropByObb.d.ts +7 -0
  121. package/build/utils/cropByObb.d.ts.map +1 -1
  122. package/build/utils/cropByObb.js +20 -1
  123. package/build/utils/cropByObb.js.map +1 -1
  124. package/build/utils/deviceDetection.d.ts +6 -0
  125. package/build/utils/deviceDetection.d.ts.map +1 -0
  126. package/build/utils/deviceDetection.js +12 -0
  127. package/build/utils/deviceDetection.js.map +1 -0
  128. package/build/utils/platformAlert.d.ts.map +1 -1
  129. package/build/utils/platformAlert.js.map +1 -1
  130. package/build/utils/template-transformer.d.ts.map +1 -1
  131. package/build/utils/template-transformer.js +12 -0
  132. package/build/utils/template-transformer.js.map +1 -1
  133. package/build/web/WebKYCEntry.d.ts.map +1 -1
  134. package/build/web/WebKYCEntry.js +88 -38
  135. package/build/web/WebKYCEntry.js.map +1 -1
  136. package/package.json +1 -1
  137. package/plugin/build/index.d.ts +1 -0
  138. package/plugin/build/index.js +3 -1
  139. package/plugin/build/withRemovePermissions.d.ts +3 -0
  140. package/plugin/build/withRemovePermissions.js +67 -0
  141. package/plugin/build/withVisionCamera.js +3 -4
  142. package/plugin/src/index.ts +2 -1
  143. package/plugin/src/withRemovePermissions.js +85 -0
  144. package/plugin/src/withRemovePermissions.ts +83 -0
  145. package/plugin/src/withVisionCamera.js +3 -4
  146. package/plugin/src/withVisionCamera.ts +3 -4
  147. package/plugin/tsconfig.tsbuildinfo +1 -1
  148. package/plugin.js +6 -1
  149. package/src/components/EnhancedCameraView.web.tsx +76 -21
  150. package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
  151. package/src/components/KYCElements/EmailVerificationTemplate.tsx +278 -0
  152. package/src/components/KYCElements/IDCardCapture.tsx +253 -21
  153. package/src/components/KYCElements/OrientationVideoCapture.tsx +4 -1
  154. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +4 -1
  155. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +4 -1
  156. package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
  157. package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
  158. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +6 -3
  159. package/src/components/KYCElements/WelcomeTemplate.tsx +2 -1
  160. package/src/components/OverLay/type.ts +2 -0
  161. package/src/components/TemplateKYCExample.tsx +35 -46
  162. package/src/components/TemplateKYCFlowRefactored.tsx +46 -2
  163. package/src/config/KYCConfig.ts +34 -0
  164. package/src/config/allowedDomains.ts +7 -26
  165. package/src/hooks/useOrientationVideo.ts +5 -4
  166. package/src/hooks/useTemplateKYCFlow.tsx +443 -56
  167. package/src/i18n/en/index.ts +46 -3
  168. package/src/i18n/fr/index.ts +31 -2
  169. package/src/i18n/types.ts +2 -0
  170. package/src/index.ts +3 -0
  171. package/src/modules/api/CardAuthentification.ts +98 -12
  172. package/src/modules/api/KYCService.ts +158 -37
  173. package/src/modules/api/SelfieVerification.ts +25 -3
  174. package/src/modules/api/TemplateService.ts +4 -4
  175. package/src/modules/camera/VisionCameraModule.web.ts +30 -12
  176. package/src/types/KYC.types.ts +153 -6
  177. package/src/types/env.types.ts +13 -0
  178. package/src/utils/cropByObb.ts +20 -1
  179. package/src/utils/deviceDetection.ts +11 -0
  180. package/src/utils/platformAlert.ts +1 -0
  181. package/src/utils/template-transformer.ts +20 -8
  182. package/src/web/WebKYCEntry.tsx +123 -61
@@ -1,5 +1,6 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { KYCTemplate, TemplateState, TemplateActions, UseTemplateReturn, VerificationState } from '../types/KYC.types';
3
+ import { KycEnvironment } from '../types/env.types';
3
4
  interface TemplateKYCFlowContextType {
4
5
  state: TemplateState;
5
6
  actions: TemplateActions;
@@ -14,6 +15,8 @@ interface TemplateKYCFlowContextType {
14
15
  [key: string]: string;
15
16
  }) => string;
16
17
  initializeSession: () => Promise<void>;
18
+ env: KycEnvironment;
19
+ apiKey?: string;
17
20
  }
18
21
  interface TemplateKYCFlowProviderProps {
19
22
  children: ReactNode;
@@ -23,9 +26,23 @@ interface TemplateKYCFlowProviderProps {
23
26
  onCancel?: () => void;
24
27
  initialLanguage?: string;
25
28
  apiKey?: string;
29
+ env?: KycEnvironment;
30
+ existingSessionId?: string;
31
+ /** Index in template.components where to resume (0-based). Simple to store in template table. */
32
+ initialComponentIndex?: number;
33
+ /** Pays / type de document depuis l'URL de reprise — évite de dépendre du backend pour afficher les pays. */
34
+ initialCountryResume?: {
35
+ code: string;
36
+ documentType: string;
37
+ region?: string;
38
+ };
26
39
  }
27
40
  export declare const TemplateKYCFlowProvider: React.FC<TemplateKYCFlowProviderProps>;
28
41
  export declare const useTemplateKYCFlowContext: () => TemplateKYCFlowContextType;
29
- export declare const useTemplateKYCFlow: (template: KYCTemplate, onComplete?: (data: VerificationState) => void, onError?: (error: string) => void, onCancel?: () => void, initialLanguage?: string, apiKey?: string) => UseTemplateReturn;
42
+ export declare const useTemplateKYCFlow: (template: KYCTemplate, onComplete?: (data: VerificationState) => void, onError?: (error: string) => void, onCancel?: () => void, initialLanguage?: string, apiKey?: string, env?: KycEnvironment, existingSessionId?: string, initialComponentIndex?: number, initialCountryResume?: {
43
+ code: string;
44
+ documentType: string;
45
+ region?: string;
46
+ }) => UseTemplateReturn;
30
47
  export {};
31
48
  //# sourceMappingURL=useTemplateKYCFlow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTemplateKYCFlow.d.ts","sourceRoot":"","sources":["../../src/hooks/useTemplateKYCFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA6D,SAAS,EAAa,MAAM,OAAO,CAAC;AAC/G,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAA6C,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAMlK,UAAU,0BAA0B;IAClC,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,gBAAgB,EAAE,GAAG,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAA,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IACrF,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAKD,UAAU,4BAA4B;IACpC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAgB1E,CAAC;AAGF,eAAO,MAAM,yBAAyB,QAAO,0BAM5C,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,aAAa,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,EAC9C,UAAU,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,WAAW,MAAM,IAAI,EACrB,kBAAiB,MAAa,EAC9B,SAAS,MAAM,KACd,iBAqlBF,CAAC"}
1
+ {"version":3,"file":"useTemplateKYCFlow.d.ts","sourceRoot":"","sources":["../../src/hooks/useTemplateKYCFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA6D,SAAS,EAAa,MAAM,OAAO,CAAC;AAC/G,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAA6C,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAClK,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQpD,UAAU,0BAA0B;IAClC,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,gBAAgB,EAAE,GAAG,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAA,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IACrF,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD,UAAU,4BAA4B;IACpC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iGAAiG;IACjG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6GAA6G;IAC7G,oBAAoB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChF;AAED,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAoB1E,CAAC;AAGF,eAAO,MAAM,yBAAyB,QAAO,0BAM5C,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,EACrB,aAAa,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,EAC9C,UAAU,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,WAAW,MAAM,IAAI,EACrB,kBAAiB,MAAa,EAC9B,SAAS,MAAM,EACf,MAAK,cAA6B,EAClC,oBAAoB,MAAM,EAC1B,wBAAwB,MAAM,EAC9B,uBAAuB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAC7E,iBAq8BF,CAAC"}
@@ -2,9 +2,11 @@ import React, { useState, useCallback, useMemo, createContext, useContext, useEf
2
2
  import kycService, { authentification, truncateFields } from '../modules/api/KYCService';
3
3
  import useI18n from './useI18n';
4
4
  import { logger } from '../utils/logger';
5
+ import { countryMapping } from '../config/region_mapping';
6
+ import { countryData } from '../config/countriesData';
5
7
  const TemplateKYCFlowContext = createContext(undefined);
6
- export const TemplateKYCFlowProvider = ({ children, template, onComplete, onError, onCancel, initialLanguage = 'en', apiKey, }) => {
7
- const hookResult = useTemplateKYCFlow(template, onComplete, onError, onCancel, initialLanguage, apiKey);
8
+ export const TemplateKYCFlowProvider = ({ children, template, onComplete, onError, onCancel, initialLanguage = 'en', apiKey, env = 'PRODUCTION', existingSessionId, initialComponentIndex, initialCountryResume, }) => {
9
+ const hookResult = useTemplateKYCFlow(template, onComplete, onError, onCancel, initialLanguage, apiKey, env, existingSessionId, initialComponentIndex, initialCountryResume);
8
10
  return (<TemplateKYCFlowContext.Provider value={hookResult}>
9
11
  {children}
10
12
  </TemplateKYCFlowContext.Provider>);
@@ -17,7 +19,7 @@ export const useTemplateKYCFlowContext = () => {
17
19
  }
18
20
  return context;
19
21
  };
20
- export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, initialLanguage = 'en', apiKey) => {
22
+ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, initialLanguage = 'en', apiKey, env = 'PRODUCTION', existingSessionId, initialComponentIndex, initialCountryResume) => {
21
23
  const { setLocale } = useI18n();
22
24
  useEffect(() => {
23
25
  setLocale(initialLanguage);
@@ -70,29 +72,336 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
70
72
  }, [apiKey]);
71
73
  const templateWithReview = useMemo(() => ensureReviewSubmitStep(template), [template, ensureReviewSubmitStep, apiKey]);
72
74
  const templateWithReviewAndVerification = useMemo(() => ensureVerificationProgressStep(templateWithReview), [templateWithReview, ensureVerificationProgressStep, apiKey]);
73
- // État initial du flux
74
- const buildInitialState = () => ({
75
- template: templateWithReviewAndVerification,
76
- currentComponentIndex: 0,
77
- completedComponents: [],
78
- componentData: {},
79
- errors: {},
80
- isProcessing: false,
81
- currentLanguage: initialLanguage,
82
- showCustomStepper: true,
83
- session: {
84
- session_id: '',
85
- token: '',
86
- isInitialized: false,
75
+ // État initial du flux (initialComponentIndex = index dans template.components pour reprendre au bon composant)
76
+ const buildInitialState = () => {
77
+ let resumeAtIndex = 0;
78
+ let completedComponents = [];
79
+ let initialComponentData = {};
80
+ logger.log('buildInitialState called', { initialComponentIndex, existingSessionId, initialCountryResume });
81
+ if (initialComponentIndex !== undefined && initialComponentIndex >= 0) {
82
+ const maxIndex = templateWithReviewAndVerification.components.length - 1;
83
+ const requestedIndex = Math.min(initialComponentIndex, maxIndex);
84
+ const requestedComponent = templateWithReviewAndVerification.components[requestedIndex];
85
+ logger.log('Processing initialComponentIndex (component in template)', {
86
+ initialComponentIndex,
87
+ requestedIndex,
88
+ maxIndex,
89
+ componentType: requestedComponent?.type,
90
+ componentId: requestedComponent?.id,
91
+ });
92
+ // Reprendre au composant en cours (id_card, selfie, etc.)
93
+ if (requestedComponent?.type === 'id_card') {
94
+ if (existingSessionId) {
95
+ logger.log('id_card with existing session - staying at id_card');
96
+ resumeAtIndex = requestedIndex;
97
+ if (resumeAtIndex > 0) {
98
+ completedComponents = templateWithReviewAndVerification.components
99
+ .slice(0, resumeAtIndex)
100
+ .map(component => component.id);
101
+ }
102
+ }
103
+ else {
104
+ const countrySelectionIndex = templateWithReviewAndVerification.components.findIndex(c => c.type === 'country_selection');
105
+ logger.log('id_card without session - going back to country_selection', { countrySelectionIndex });
106
+ if (countrySelectionIndex >= 0) {
107
+ resumeAtIndex = countrySelectionIndex;
108
+ if (countrySelectionIndex > 0) {
109
+ completedComponents = templateWithReviewAndVerification.components
110
+ .slice(0, countrySelectionIndex)
111
+ .map(component => component.id);
112
+ }
113
+ }
114
+ else {
115
+ resumeAtIndex = 0;
116
+ }
117
+ }
118
+ }
119
+ else if (requestedComponent?.type === 'review_submit') {
120
+ resumeAtIndex = requestedIndex;
121
+ completedComponents = [];
122
+ }
123
+ else {
124
+ resumeAtIndex = requestedIndex;
125
+ if (resumeAtIndex > 0) {
126
+ completedComponents = templateWithReviewAndVerification.components
127
+ .slice(0, resumeAtIndex)
128
+ .map(component => component.id);
129
+ }
130
+ }
131
+ logger.log('Final initial state (resume at component index)', {
132
+ resumeAtIndex,
133
+ completedComponentsCount: completedComponents.length,
134
+ componentAtResume: templateWithReviewAndVerification.components[resumeAtIndex]?.type,
135
+ });
136
+ }
137
+ if (initialCountryResume?.code && initialCountryResume?.documentType) {
138
+ const countrySel = templateWithReviewAndVerification.components.find(c => c.type === 'country_selection');
139
+ if (countrySel && countryData[initialCountryResume.code]) {
140
+ initialComponentData[countrySel.id] = {
141
+ code: initialCountryResume.code,
142
+ documentType: initialCountryResume.documentType,
143
+ region: initialCountryResume.region || 'root',
144
+ ...countryData[initialCountryResume.code],
145
+ };
146
+ logger.log('Prefilled country_selection from URL', { code: initialCountryResume.code, documentType: initialCountryResume.documentType });
147
+ }
148
+ }
149
+ return {
150
+ template: templateWithReviewAndVerification,
151
+ currentComponentIndex: resumeAtIndex,
152
+ completedComponents: completedComponents,
153
+ componentData: initialComponentData,
154
+ errors: {},
87
155
  isProcessing: false,
88
- error: null,
89
- },
90
- verification: {
91
- status: 'idle',
92
- },
93
- });
156
+ currentLanguage: initialLanguage,
157
+ showCustomStepper: true,
158
+ session: {
159
+ session_id: existingSessionId || '',
160
+ token: '',
161
+ isInitialized: false,
162
+ isProcessing: false,
163
+ error: null,
164
+ sessionDataRestored: !existingSessionId || Boolean(initialCountryResume?.code && initialCountryResume?.documentType),
165
+ },
166
+ verification: {
167
+ status: 'idle',
168
+ },
169
+ };
170
+ };
94
171
  // État du flux
95
172
  const [state, setState] = useState(() => buildInitialState());
173
+ // Fonction utilitaire pour convertir base64 en data URI pour l'affichage
174
+ const base64ToDataUri = useCallback((base64, mimeType = 'image/jpeg') => {
175
+ // Si c'est déjà une data URI, retourner tel quel
176
+ if (base64.startsWith('data:')) {
177
+ return base64;
178
+ }
179
+ // Sinon, créer une data URI
180
+ return `data:${mimeType};base64,${base64}`;
181
+ }, []);
182
+ // Charger les données de session si on reprend une session existante
183
+ useEffect(() => {
184
+ const loadSessionData = async () => {
185
+ // Ne charger que si on a une session existante
186
+ if (!existingSessionId) {
187
+ logger.log('No existingSessionId, skipping data load');
188
+ return;
189
+ }
190
+ // Si initialComponentIndex n'est pas défini ou est 0, on ne charge pas (début de session)
191
+ if (initialComponentIndex === undefined || initialComponentIndex === 0) {
192
+ logger.log('initialComponentIndex is 0 or undefined, skipping data load');
193
+ return;
194
+ }
195
+ // Attendre que la session soit initialisée
196
+ if (!state.session.isInitialized || !state.session.session_id) {
197
+ logger.log('Session not initialized yet, waiting...', {
198
+ isInitialized: state.session.isInitialized,
199
+ sessionId: state.session.session_id
200
+ });
201
+ return;
202
+ }
203
+ try {
204
+ logger.log('Loading session data for resume:', { sessionId: existingSessionId, componentIndex: initialComponentIndex });
205
+ const result = await kycService.getVerificationResult(state.session.session_id);
206
+ const sessionData = result[state.session.session_id]?.data;
207
+ if (sessionData) {
208
+ // Restaurer les données des composants depuis la session
209
+ // Utiliser 'as any' car VerificationResult peut avoir des propriétés dynamiques
210
+ const data = sessionData;
211
+ const restoredComponentData = {};
212
+ // Parcourir les composants jusqu'au composant de reprise (inclu) pour restaurer leurs données
213
+ templateWithReviewAndVerification.components
214
+ .slice(0, initialComponentIndex + 1)
215
+ .forEach((component) => {
216
+ // Essayer de restaurer les données selon le type de composant
217
+ if (component.type === 'id_card' || component.type === 'file_upload') {
218
+ // Les documents peuvent être dans différentes structures
219
+ let documents = null;
220
+ // Chercher dans différentes structures possibles
221
+ if (data.documents) {
222
+ documents = data.documents;
223
+ }
224
+ else if (data.user_data?.documents) {
225
+ documents = data.user_data.documents;
226
+ }
227
+ else if (data.document_images) {
228
+ documents = data.document_images;
229
+ }
230
+ if (documents) {
231
+ // Convertir les images base64 en format utilisable
232
+ const restoredDocuments = {};
233
+ Object.keys(documents).forEach((key) => {
234
+ const doc = documents[key];
235
+ if (typeof doc === 'object' && doc !== null) {
236
+ // Si on a un fichier base64, créer une structure avec dir et file
237
+ if (doc.file || doc.base64) {
238
+ const base64Data = doc.file || doc.base64;
239
+ restoredDocuments[key] = {
240
+ dir: base64ToDataUri(base64Data), // Utiliser data URI pour l'affichage
241
+ file: base64Data, // Garder le base64 pour l'envoi
242
+ mrz: doc.mrz || '',
243
+ templatePath: doc.templatePath || '',
244
+ };
245
+ }
246
+ else {
247
+ // Sinon, garder la structure originale
248
+ restoredDocuments[key] = doc;
249
+ }
250
+ }
251
+ else if (typeof doc === 'string') {
252
+ // Si c'est directement une string base64
253
+ restoredDocuments[key] = {
254
+ dir: base64ToDataUri(doc),
255
+ file: doc,
256
+ mrz: '',
257
+ templatePath: '',
258
+ };
259
+ }
260
+ });
261
+ if (Object.keys(restoredDocuments).length > 0) {
262
+ restoredComponentData[component.id] = restoredDocuments;
263
+ }
264
+ }
265
+ }
266
+ else if (component.type === 'selfie') {
267
+ // Les selfies peuvent être dans sessionData.selfie_info
268
+ if (data.selfie_info) {
269
+ const selfieData = {};
270
+ const selfieInfo = data.selfie_info;
271
+ // Si selfie_info contient une image
272
+ if (selfieInfo.image) {
273
+ const base64Image = selfieInfo.image;
274
+ selfieData['front'] = {
275
+ dir: base64ToDataUri(base64Image),
276
+ file: base64Image,
277
+ };
278
+ }
279
+ // Si on a plusieurs orientations
280
+ if (selfieInfo.orientations) {
281
+ Object.keys(selfieInfo.orientations).forEach((orientation) => {
282
+ const img = selfieInfo.orientations[orientation];
283
+ if (img) {
284
+ selfieData[orientation] = {
285
+ dir: base64ToDataUri(img),
286
+ file: img,
287
+ };
288
+ }
289
+ });
290
+ }
291
+ if (Object.keys(selfieData).length > 0) {
292
+ restoredComponentData[component.id] = selfieData;
293
+ }
294
+ }
295
+ }
296
+ else if (component.type === 'country_selection') {
297
+ // Reconstruire country_selection au format attendu par IDCardCapture / CountrySelectionTemplate (code, documentType, region, regionMapping)
298
+ const meta = data.metadata || data.user_data || data;
299
+ const code = meta.country || meta.country_code || meta.code;
300
+ const documentType = meta.document_type || meta.documentType;
301
+ const region = meta.region;
302
+ if (code && documentType != null) {
303
+ const country = countryData[code];
304
+ const mapping = countryMapping[code];
305
+ if (country) {
306
+ restoredComponentData[component.id] = {
307
+ code,
308
+ ...country,
309
+ documentType,
310
+ region: region || undefined,
311
+ regionMapping: mapping || undefined,
312
+ };
313
+ logger.log('Restored country_selection for resume', { code, documentType, region });
314
+ }
315
+ else {
316
+ restoredComponentData[component.id] = { code, documentType, region: region || undefined, regionMapping: mapping || undefined };
317
+ }
318
+ }
319
+ else if (data.metadata || data.user_data) {
320
+ restoredComponentData[component.id] = {
321
+ ...(data.metadata || {}),
322
+ ...(data.user_data || {}),
323
+ };
324
+ }
325
+ }
326
+ else if (component.type === 'location') {
327
+ // Les données de localisation peuvent être dans metadata
328
+ if (data.metadata?.location || data.user_data?.location) {
329
+ restoredComponentData[component.id] = {
330
+ ...(data.metadata?.location || {}),
331
+ ...(data.user_data?.location || {}),
332
+ };
333
+ }
334
+ }
335
+ });
336
+ // Fallback: si pas de country_selection restauré mais on a des documents avec templatePath, déduire code/documentType (ex. "templates/national_id_CM_front.jpg")
337
+ const countrySelectionComponent = templateWithReviewAndVerification.components.find(c => c.type === 'country_selection');
338
+ if (countrySelectionComponent && !restoredComponentData[countrySelectionComponent.id] && data.documents) {
339
+ const docs = data.documents;
340
+ const firstDoc = Object.values(docs).find(d => d?.templatePath);
341
+ const path = firstDoc?.templatePath || '';
342
+ const match = path.match(/([a-z_]+)_([A-Z]{2})(?:_|$)/i) || path.match(/([A-Z]{2})/);
343
+ const code = match ? (match[2] || match[1]).toUpperCase().slice(0, 2) : null;
344
+ const docTypeFromPath = path.match(/(national_id|identity_card|passport|passport_card)/i)?.[1]?.toLowerCase().replace('identity_card', 'national_id') || null;
345
+ if (code && countryData[code]) {
346
+ const documentType = docTypeFromPath || 'national_id';
347
+ const mapping = countryMapping[code];
348
+ const country = countryData[code];
349
+ restoredComponentData[countrySelectionComponent.id] = {
350
+ code,
351
+ ...country,
352
+ documentType,
353
+ region: undefined,
354
+ regionMapping: mapping || undefined,
355
+ };
356
+ logger.log('Restored country_selection from document templatePath', { code, documentType, path });
357
+ }
358
+ }
359
+ // Mettre à jour l'état avec les données restaurées
360
+ if (Object.keys(restoredComponentData).length > 0) {
361
+ logger.log('Session data restored - components:', Object.keys(restoredComponentData));
362
+ logger.log('Session data restored - sample data:', truncateFields(restoredComponentData));
363
+ setState(prev => ({
364
+ ...prev,
365
+ componentData: {
366
+ ...prev.componentData,
367
+ ...restoredComponentData,
368
+ },
369
+ session: { ...prev.session, sessionDataRestored: true },
370
+ }));
371
+ logger.log('Component data updated in state');
372
+ }
373
+ else {
374
+ logger.log('No component data to restore from session');
375
+ setState(prev => ({ ...prev, session: { ...prev.session, sessionDataRestored: true } }));
376
+ }
377
+ }
378
+ else {
379
+ setState(prev => ({ ...prev, session: { ...prev.session, sessionDataRestored: true } }));
380
+ }
381
+ }
382
+ catch (error) {
383
+ logger.error('Error loading session data:', truncateFields(error));
384
+ setState(prev => ({ ...prev, session: { ...prev.session, sessionDataRestored: true } }));
385
+ }
386
+ };
387
+ loadSessionData();
388
+ }, [existingSessionId, initialComponentIndex, state.session.isInitialized, state.session.session_id, templateWithReviewAndVerification.components, base64ToDataUri]);
389
+ // Si l'index pointe vers Review alors que des étapes ne sont pas complétées, ramener à la première étape incomplète
390
+ useEffect(() => {
391
+ const comp = state.template.components[state.currentComponentIndex];
392
+ if (!comp || comp.type !== 'review_submit')
393
+ return;
394
+ const nonReview = state.template.components.filter(c => c.type !== 'review_submit' && c.type !== 'verification_progress');
395
+ if (nonReview.every(c => state.completedComponents.includes(c.id)))
396
+ return;
397
+ const firstIncomplete = nonReview.find(c => !state.completedComponents.includes(c.id));
398
+ if (!firstIncomplete)
399
+ return;
400
+ const targetIndex = state.template.components.findIndex(c => c.id === firstIncomplete.id);
401
+ if (targetIndex >= 0 && targetIndex !== state.currentComponentIndex) {
402
+ setState(prev => ({ ...prev, currentComponentIndex: targetIndex }));
403
+ }
404
+ }, [state.currentComponentIndex, state.completedComponents, state.template.components]);
96
405
  const mapComponentTypeToAction = useCallback((type) => {
97
406
  switch (type) {
98
407
  case 'id_card':
@@ -144,7 +453,7 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
144
453
  if (!action) {
145
454
  return base;
146
455
  }
147
- // Document upload expects an array of documents with base64 and metadata
456
+ // Document upload expects documents; include country_selection in metadata so resume can restore it
148
457
  if (action === 'document_upload') {
149
458
  const documents = {};
150
459
  if (rawData && typeof rawData === 'object') {
@@ -152,9 +461,19 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
152
461
  documents[key] = rawData[key];
153
462
  });
154
463
  }
464
+ const countryComp = state.template.components.find(c => c.type === 'country_selection');
465
+ const countryDataForPayload = countryComp ? state.componentData[countryComp.id] : null;
466
+ const metadata = {};
467
+ if (countryDataForPayload?.code) {
468
+ metadata.country = countryDataForPayload.code;
469
+ metadata.document_type = countryDataForPayload.documentType;
470
+ if (countryDataForPayload.region != null)
471
+ metadata.region = countryDataForPayload.region;
472
+ }
155
473
  return {
156
474
  ...base,
157
475
  documents,
476
+ ...(Object.keys(metadata).length > 0 ? { metadata } : {}),
158
477
  };
159
478
  }
160
479
  if (action === 'selfie_capture') {
@@ -182,16 +501,28 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
182
501
  }, [state.componentData, apiKey]);
183
502
  // Ensure the template contains a final review step
184
503
  // console.log('apiKey in useTemplateKYCFlow', apiKey);
185
- // Composant actuel
504
+ // Composant actuel (peut être redirigé si on pointe vers Review alors que le flux n'est pas terminé)
186
505
  const currentComponent = useMemo(() => {
187
- return state.template.components[state.currentComponentIndex] || null;
188
- }, [state.template.components, state.currentComponentIndex, apiKey]);
189
- // Progression du flux
506
+ const comp = state.template.components[state.currentComponentIndex] || null;
507
+ if (!comp || comp.type !== 'review_submit')
508
+ return comp;
509
+ const nonReview = state.template.components.filter(c => c.type !== 'review_submit' && c.type !== 'verification_progress');
510
+ const allDone = nonReview.every(c => state.completedComponents.includes(c.id));
511
+ if (allDone)
512
+ return comp;
513
+ const firstIncomplete = nonReview.find(c => !state.completedComponents.includes(c.id));
514
+ return firstIncomplete || comp;
515
+ }, [state.template.components, state.currentComponentIndex, state.completedComponents, apiKey]);
516
+ // Progression du flux (basée sur le composant effectivement affiché)
190
517
  const progress = useMemo(() => {
518
+ const idx = currentComponent
519
+ ? state.template.components.findIndex(c => c.id === currentComponent.id)
520
+ : state.currentComponentIndex;
521
+ const i = idx >= 0 ? idx : state.currentComponentIndex;
191
522
  return state.template.components.length > 0
192
- ? ((state.currentComponentIndex + 1) / state.template.components.length) * 100
523
+ ? ((i + 1) / state.template.components.length) * 100
193
524
  : 0;
194
- }, [state.currentComponentIndex, state.template.components.length, apiKey]);
525
+ }, [currentComponent, state.template.components, state.currentComponentIndex, apiKey]);
195
526
  // Vérifications de navigation
196
527
  const canGoNext = useMemo(() => {
197
528
  return state.currentComponentIndex < state.template.components.length - 1;
@@ -223,7 +554,17 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
223
554
  logger.log('Initializing session');
224
555
  const token = apiKey ? undefined : await authentification();
225
556
  console.log('token in initializeSession', { token, apiKey });
226
- const session = await kycService.newSession({ token, apiKey });
557
+ // Check if we already have a session ID from URL params (passed via state or prop)
558
+ let session;
559
+ const existingSessionId = state.session.session_id; // This might be set from initial props if we add logic for it
560
+ if (existingSessionId && existingSessionId.length > 0) {
561
+ logger.log('Resuming existing session:', existingSessionId);
562
+ // Verify existence/validity if needed, for now trust the ID and just fetch/use it
563
+ session = { session_id: existingSessionId };
564
+ }
565
+ else {
566
+ session = await kycService.newSession({ token, apiKey });
567
+ }
227
568
  // Align backend flow from step 0 with initialize_session
228
569
  try {
229
570
  const templateId = chooseTemplateId(templateWithReviewAndVerification);
@@ -266,12 +607,21 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
266
607
  }));
267
608
  }
268
609
  }, [apiKey]);
269
- // Validation d'un composant
270
- const validateComponent = useCallback((componentId) => {
610
+ // When user switches device: resume with existingSessionId + initialStep — ensure session is initialized so loadSessionData runs
611
+ useEffect(() => {
612
+ if (!existingSessionId || state.session.isInitialized)
613
+ return;
614
+ if (state.session.session_id !== existingSessionId)
615
+ return;
616
+ logger.log('Resuming on new device: initializing session so data can load', { existingSessionId, initialComponentIndex });
617
+ initializeSession();
618
+ }, [existingSessionId, state.session.session_id, state.session.isInitialized, initializeSession]);
619
+ // Validation d'un composant (dataOverride permet de valider sans attendre la mise à jour du state)
620
+ const validateComponent = useCallback((componentId, dataOverride) => {
271
621
  const component = state.template.components.find(c => c.id === componentId);
272
622
  if (!component)
273
623
  return false;
274
- const componentData = state.componentData[componentId];
624
+ const componentData = dataOverride !== undefined ? dataOverride : state.componentData[componentId];
275
625
  switch (component.type) {
276
626
  case 'id_card':
277
627
  // Vérifier si au moins un côté a été capturé
@@ -294,6 +644,16 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
294
644
  case 'welcome':
295
645
  // Welcome is valid once user has given consent (componentData is set when they click Get Started)
296
646
  return componentData && componentData.consentGiven !== false;
647
+ case 'email_verification':
648
+ return componentData && componentData.verified === true;
649
+ case 'phone_verification':
650
+ return componentData && componentData.verified === true;
651
+ case 'personal_information':
652
+ return componentData && Object.keys(componentData).length > 0;
653
+ case 'additional_documents':
654
+ // Optional by default in template config, but if required we should check based on config
655
+ // For now, return true or check length if present
656
+ return true;
297
657
  case 'review_submit':
298
658
  return true;
299
659
  default:
@@ -317,8 +677,8 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
317
677
  verification: { status: 'idle', result: undefined },
318
678
  }));
319
679
  }, [ensureReviewSubmitStep, ensureVerificationProgressStep, apiKey]),
320
- // Passer au composant suivant
321
- nextComponent: useCallback(async () => {
680
+ // Passer au composant suivant (overrideData = données du step courant si déjà connues, évite un double clic)
681
+ nextComponent: useCallback(async (overrideData) => {
322
682
  if (!canGoNext)
323
683
  return;
324
684
  const currentComp = state.template.components[state.currentComponentIndex];
@@ -334,8 +694,8 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
334
694
  isProcessing: true,
335
695
  };
336
696
  });
337
- // Valider le composant actuel
338
- if (!validateComponent(currentComp.id)) {
697
+ // Valider avec override ou state
698
+ if (!validateComponent(currentComp.id, overrideData)) {
339
699
  setState(prev => ({
340
700
  ...prev,
341
701
  isProcessing: false,
@@ -356,17 +716,14 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
356
716
  return;
357
717
  }
358
718
  if (component.type === 'review_submit') {
359
- // Move to verification screen and mark verification in progress
360
719
  setState(prev => ({
361
720
  ...prev,
362
721
  currentComponentIndex: prev.currentComponentIndex + 1,
363
722
  completedComponents: [...prev.completedComponents, currentComp.id],
723
+ componentData: overrideData !== undefined ? { ...prev.componentData, [currentComp.id]: overrideData } : prev.componentData,
364
724
  isProcessing: false,
365
725
  verification: { status: 'in_progress' },
366
- errors: {
367
- ...prev.errors,
368
- [currentComp.id]: ''
369
- }
726
+ errors: { ...prev.errors, [currentComp.id]: '' }
370
727
  }));
371
728
  return;
372
729
  }
@@ -396,17 +753,15 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
396
753
  ...prev,
397
754
  currentComponentIndex: prev.currentComponentIndex + 1,
398
755
  completedComponents: [...prev.completedComponents, currentComp.id],
756
+ componentData: overrideData !== undefined ? { ...prev.componentData, [currentComp.id]: overrideData } : prev.componentData,
399
757
  isProcessing: false,
400
- errors: {
401
- ...prev.errors,
402
- [currentComp.id]: ''
403
- }
758
+ errors: { ...prev.errors, [currentComp.id]: '' }
404
759
  }));
405
760
  return;
406
761
  }
407
762
  const step = serverStep === 0 && action !== 'initialize_session' ? 1 : serverStep;
408
- // Build payload data per action
409
- const payloadData = buildPayloadForComponent(action, component, state.componentData[currentComp.id], templateId, step);
763
+ const currentStepData = overrideData !== undefined ? overrideData : state.componentData[currentComp.id];
764
+ const payloadData = buildPayloadForComponent(action, component, currentStepData, templateId, step);
410
765
  console.log('payloadData', action, apiKey);
411
766
  await kycService.verificationSession({
412
767
  session_id: state.session.session_id,
@@ -418,17 +773,14 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
418
773
  apiKey: apiKey ?? "-",
419
774
  });
420
775
  logger.log("currentComp state", truncateFields(state));
421
- // Marquer comme complété et passer au suivant
422
776
  setState(prev => ({
423
777
  ...prev,
424
778
  currentComponentIndex: prev.currentComponentIndex + 1,
425
779
  completedComponents: [...prev.completedComponents, currentComp.id],
780
+ componentData: overrideData !== undefined ? { ...prev.componentData, [currentComp.id]: overrideData } : prev.componentData,
426
781
  isProcessing: false,
427
782
  ...(action === "location_permission" ? { permissionGranted: true } : {}),
428
- errors: {
429
- ...prev.errors,
430
- [currentComp.id]: ''
431
- }
783
+ errors: { ...prev.errors, [currentComp.id]: '' }
432
784
  }));
433
785
  }
434
786
  catch (error) {
@@ -478,8 +830,8 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
478
830
  }));
479
831
  }, [apiKey]),
480
832
  // Valider un composant
481
- validateComponent: useCallback((componentId) => {
482
- return validateComponent(componentId);
833
+ validateComponent: useCallback((componentId, dataOverride) => {
834
+ return validateComponent(componentId, dataOverride);
483
835
  }, [validateComponent, apiKey]),
484
836
  // complet verification
485
837
  submitVerification: useCallback(async () => {
@@ -551,6 +903,8 @@ export const useTemplateKYCFlow = (template, onComplete, onError, onCancel, init
551
903
  isComplete,
552
904
  getLocalizedText,
553
905
  initializeSession,
906
+ env,
907
+ apiKey,
554
908
  };
555
909
  };
556
910
  //# sourceMappingURL=useTemplateKYCFlow.js.map