@transfergratis/react-native-sdk 0.1.23 → 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 (207) 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 +13 -5
  14. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  15. package/build/components/EnhancedCameraView.js +26 -3
  16. package/build/components/EnhancedCameraView.js.map +1 -1
  17. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  18. package/build/components/EnhancedCameraView.web.js +21 -0
  19. package/build/components/EnhancedCameraView.web.js.map +1 -1
  20. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts +12 -0
  21. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts.map +1 -0
  22. package/build/components/KYCElements/AdditionalDocumentsTemplate.js +283 -0
  23. package/build/components/KYCElements/AdditionalDocumentsTemplate.js.map +1 -0
  24. package/build/components/KYCElements/CameraCapture.d.ts.map +1 -1
  25. package/build/components/KYCElements/CameraCapture.js +4 -3
  26. package/build/components/KYCElements/CameraCapture.js.map +1 -1
  27. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +5 -2
  28. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  29. package/build/components/KYCElements/CountrySelectionTemplate.js +360 -101
  30. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  31. package/build/components/KYCElements/EmailVerificationTemplate.d.ts +12 -0
  32. package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
  33. package/build/components/KYCElements/EmailVerificationTemplate.js +193 -0
  34. package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
  35. package/build/components/KYCElements/FileUpload.d.ts.map +1 -1
  36. package/build/components/KYCElements/FileUpload.js +5 -4
  37. package/build/components/KYCElements/FileUpload.js.map +1 -1
  38. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  39. package/build/components/KYCElements/FileUploadTemplate.js +5 -4
  40. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  41. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  42. package/build/components/KYCElements/IDCardCapture.js +356 -227
  43. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  44. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  45. package/build/components/KYCElements/LocationCaptureTemplate.js +78 -37
  46. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  47. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -0
  48. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  49. package/build/components/KYCElements/OrientationVideoCapture.js +5 -4
  50. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  51. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -0
  52. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  53. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +5 -4
  54. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  55. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -0
  56. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  57. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +5 -4
  58. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  59. package/build/components/KYCElements/PersonalInformationTemplate.d.ts +12 -0
  60. package/build/components/KYCElements/PersonalInformationTemplate.d.ts.map +1 -0
  61. package/build/components/KYCElements/PersonalInformationTemplate.js +120 -0
  62. package/build/components/KYCElements/PersonalInformationTemplate.js.map +1 -0
  63. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts +12 -0
  64. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -0
  65. package/build/components/KYCElements/PhoneVerificationTemplate.js +185 -0
  66. package/build/components/KYCElements/PhoneVerificationTemplate.js.map +1 -0
  67. package/build/components/KYCElements/SelfieCapture.d.ts.map +1 -1
  68. package/build/components/KYCElements/SelfieCapture.js +4 -3
  69. package/build/components/KYCElements/SelfieCapture.js.map +1 -1
  70. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  71. package/build/components/KYCElements/SelfieCaptureTemplate.js +189 -42
  72. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  73. package/build/components/KYCElements/WelcomeTemplate.d.ts +12 -0
  74. package/build/components/KYCElements/WelcomeTemplate.d.ts.map +1 -0
  75. package/build/components/KYCElements/WelcomeTemplate.js +243 -0
  76. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -0
  77. package/build/components/TemplateKYCExample.d.ts +8 -2
  78. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  79. package/build/components/TemplateKYCExample.js +10 -97
  80. package/build/components/TemplateKYCExample.js.map +1 -1
  81. package/build/components/TemplateKYCFlowRefactored.d.ts +6 -1
  82. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  83. package/build/components/TemplateKYCFlowRefactored.js +108 -11
  84. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  85. package/build/components/example/DynamicTemplateExample.d.ts +10 -0
  86. package/build/components/example/DynamicTemplateExample.d.ts.map +1 -0
  87. package/build/components/example/DynamicTemplateExample.js +241 -0
  88. package/build/components/example/DynamicTemplateExample.js.map +1 -0
  89. package/build/config/KYCConfig.d.ts +14 -0
  90. package/build/config/KYCConfig.d.ts.map +1 -0
  91. package/build/config/KYCConfig.js +26 -0
  92. package/build/config/KYCConfig.js.map +1 -0
  93. package/build/config/allowedDomains.d.ts +30 -0
  94. package/build/config/allowedDomains.d.ts.map +1 -0
  95. package/build/config/allowedDomains.js +112 -0
  96. package/build/config/allowedDomains.js.map +1 -0
  97. package/build/hooks/useOrientationVideo.d.ts +2 -1
  98. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  99. package/build/hooks/useOrientationVideo.js +3 -3
  100. package/build/hooks/useOrientationVideo.js.map +1 -1
  101. package/build/hooks/useTemplateKYCFlow.d.ts +6 -1
  102. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  103. package/build/hooks/useTemplateKYCFlow.js +317 -34
  104. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  105. package/build/hooks/useTemplateLoader.d.ts +14 -0
  106. package/build/hooks/useTemplateLoader.d.ts.map +1 -0
  107. package/build/hooks/useTemplateLoader.js +85 -0
  108. package/build/hooks/useTemplateLoader.js.map +1 -0
  109. package/build/i18n/en/index.d.ts +49 -0
  110. package/build/i18n/en/index.d.ts.map +1 -1
  111. package/build/i18n/en/index.js +50 -1
  112. package/build/i18n/en/index.js.map +1 -1
  113. package/build/i18n/fr/index.d.ts +35 -0
  114. package/build/i18n/fr/index.d.ts.map +1 -1
  115. package/build/i18n/fr/index.js +36 -1
  116. package/build/i18n/fr/index.js.map +1 -1
  117. package/build/index.d.ts +6 -0
  118. package/build/index.d.ts.map +1 -1
  119. package/build/index.js +10 -0
  120. package/build/index.js.map +1 -1
  121. package/build/modules/api/CardAuthentification.d.ts +24 -3
  122. package/build/modules/api/CardAuthentification.d.ts.map +1 -1
  123. package/build/modules/api/CardAuthentification.js +69 -10
  124. package/build/modules/api/CardAuthentification.js.map +1 -1
  125. package/build/modules/api/KYCService.d.ts +7 -7
  126. package/build/modules/api/KYCService.d.ts.map +1 -1
  127. package/build/modules/api/KYCService.js +108 -39
  128. package/build/modules/api/KYCService.js.map +1 -1
  129. package/build/modules/api/SelfieVerification.d.ts +3 -1
  130. package/build/modules/api/SelfieVerification.d.ts.map +1 -1
  131. package/build/modules/api/SelfieVerification.js +17 -1
  132. package/build/modules/api/SelfieVerification.js.map +1 -1
  133. package/build/modules/api/TemplateService.d.ts +44 -0
  134. package/build/modules/api/TemplateService.d.ts.map +1 -0
  135. package/build/modules/api/TemplateService.js +145 -0
  136. package/build/modules/api/TemplateService.js.map +1 -0
  137. package/build/types/KYC.types.d.ts +265 -4
  138. package/build/types/KYC.types.d.ts.map +1 -1
  139. package/build/types/KYC.types.js +15 -0
  140. package/build/types/KYC.types.js.map +1 -1
  141. package/build/types/env.types.d.ts +13 -0
  142. package/build/types/env.types.d.ts.map +1 -0
  143. package/build/types/env.types.js +2 -0
  144. package/build/types/env.types.js.map +1 -0
  145. package/build/utils/cropByObb.d.ts +1 -0
  146. package/build/utils/cropByObb.d.ts.map +1 -1
  147. package/build/utils/cropByObb.js +70 -0
  148. package/build/utils/cropByObb.js.map +1 -1
  149. package/build/utils/deviceDetection.d.ts +6 -0
  150. package/build/utils/deviceDetection.d.ts.map +1 -0
  151. package/build/utils/deviceDetection.js +12 -0
  152. package/build/utils/deviceDetection.js.map +1 -0
  153. package/build/utils/platformAlert.d.ts +20 -0
  154. package/build/utils/platformAlert.d.ts.map +1 -0
  155. package/build/utils/platformAlert.js +67 -0
  156. package/build/utils/platformAlert.js.map +1 -0
  157. package/build/utils/template-transformer.d.ts +10 -0
  158. package/build/utils/template-transformer.d.ts.map +1 -0
  159. package/build/utils/template-transformer.js +365 -0
  160. package/build/utils/template-transformer.js.map +1 -0
  161. package/build/web/WebKYCEntry.d.ts.map +1 -1
  162. package/build/web/WebKYCEntry.js +158 -32
  163. package/build/web/WebKYCEntry.js.map +1 -1
  164. package/package.json +1 -1
  165. package/plugin/build/withVisionCamera.js +3 -4
  166. package/plugin/src/withVisionCamera.js +3 -4
  167. package/plugin/src/withVisionCamera.ts +3 -4
  168. package/src/components/EnhancedCameraView.tsx +31 -2
  169. package/src/components/EnhancedCameraView.web.tsx +24 -0
  170. package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
  171. package/src/components/KYCElements/CameraCapture.tsx +4 -3
  172. package/src/components/KYCElements/CountrySelectionTemplate.tsx +410 -113
  173. package/src/components/KYCElements/EmailVerificationTemplate.tsx +264 -0
  174. package/src/components/KYCElements/FileUpload.tsx +5 -4
  175. package/src/components/KYCElements/FileUploadTemplate.tsx +5 -4
  176. package/src/components/KYCElements/IDCardCapture.tsx +397 -254
  177. package/src/components/KYCElements/LocationCaptureTemplate.tsx +95 -44
  178. package/src/components/KYCElements/OrientationVideoCapture.tsx +6 -3
  179. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +6 -3
  180. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +6 -3
  181. package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
  182. package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
  183. package/src/components/KYCElements/SelfieCapture.tsx +4 -3
  184. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +201 -44
  185. package/src/components/KYCElements/WelcomeTemplate.tsx +289 -0
  186. package/src/components/TemplateKYCExample.tsx +37 -108
  187. package/src/components/TemplateKYCFlowRefactored.tsx +148 -12
  188. package/src/components/example/DynamicTemplateExample.tsx +289 -0
  189. package/src/config/KYCConfig.ts +34 -0
  190. package/src/config/allowedDomains.ts +133 -0
  191. package/src/hooks/useOrientationVideo.ts +5 -4
  192. package/src/hooks/useTemplateKYCFlow.tsx +347 -32
  193. package/src/hooks/useTemplateLoader.ts +102 -0
  194. package/src/i18n/en/index.ts +53 -2
  195. package/src/i18n/fr/index.ts +37 -1
  196. package/src/index.ts +14 -0
  197. package/src/modules/api/CardAuthentification.ts +76 -11
  198. package/src/modules/api/KYCService.ts +129 -45
  199. package/src/modules/api/SelfieVerification.ts +25 -3
  200. package/src/modules/api/TemplateService.ts +167 -0
  201. package/src/types/KYC.types.ts +331 -3
  202. package/src/types/env.types.ts +13 -0
  203. package/src/utils/cropByObb.ts +83 -3
  204. package/src/utils/deviceDetection.ts +11 -0
  205. package/src/utils/platformAlert.ts +86 -0
  206. package/src/utils/template-transformer.ts +445 -0
  207. package/src/web/WebKYCEntry.tsx +199 -50
@@ -1,9 +1,12 @@
1
1
  import React, { useEffect, useState, useCallback } from 'react';
2
- import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
2
+ import { View, Text, StyleSheet, SafeAreaView, ActivityIndicator } from 'react-native';
3
3
  // import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';
4
4
  // import { KYCTemplate } from '../types/KYC.types';
5
5
  import { useI18n } from '../hooks/useI18n';
6
6
  import { TemplateKYCExample } from '../components/TemplateKYCExample';
7
+ import { isCallbackUrlAllowed } from '../config/allowedDomains';
8
+ import KYCConfig from '../config/KYCConfig';
9
+ import { BackendEnvironment } from '../types/env.types';
7
10
 
8
11
  interface WebKYCEntryProps {
9
12
  onComplete?: (data: any) => void;
@@ -14,9 +17,21 @@ interface WebKYCEntryProps {
14
17
  interface URLParams {
15
18
  token?: string;
16
19
  return_url?: string;
20
+ push_url?: string;
17
21
  lang?: string;
18
22
  theme?: string;
19
23
  kyc_id?: string;
24
+ secret?: string; // Optional secret for signature generation
25
+ env?: 'PRODUCTION' | 'SANDBOX'; // Environment mode
26
+ template_id?: string; // Template ID for dynamic template loading
27
+ server_env?: BackendEnvironment; // Backend environment mode
28
+ step?: string; // Step index to resume verification at the correct point
29
+ }
30
+
31
+ interface VerificationSteps {
32
+ document_analyzed?: boolean;
33
+ selfie_analyzed?: boolean;
34
+ liveness_checked?: boolean;
20
35
  }
21
36
 
22
37
  const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
@@ -28,109 +43,185 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
28
43
  const [urlParams, setUrlParams] = useState<URLParams>({});
29
44
  const [isLoading, setIsLoading] = useState(true);
30
45
  const [error, setError] = useState<string | null>(null);
46
+ const [isAnalyzing, setIsAnalyzing] = useState(false);
31
47
 
32
48
  // Parse URL parameters
33
49
  const parseUrlParams = useCallback((): URLParams => {
34
50
  if (typeof window === 'undefined') return {};
35
-
51
+
36
52
  const urlParams = new URLSearchParams(window.location.search);
53
+ const envParam = urlParams.get('env');
54
+ const validEnv = envParam === 'SANDBOX' || envParam === 'PRODUCTION' ? envParam : 'PRODUCTION';
55
+
56
+ const serverEnvParam = urlParams.get('server_env');
57
+ const validServerEnv: BackendEnvironment = serverEnvParam === 'TEST' || serverEnvParam === 'PRODUCTION'
58
+ ? (serverEnvParam as BackendEnvironment)
59
+ : 'PRODUCTION';
60
+
37
61
  return {
38
62
  token: urlParams.get('token') || undefined,
39
63
  return_url: urlParams.get('return_url') || undefined,
64
+ push_url: urlParams.get('push_url') || undefined,
40
65
  lang: urlParams.get('lang') || 'en',
41
66
  theme: urlParams.get('theme') || 'light',
42
67
  kyc_id: urlParams.get('kyc_id') || undefined,
68
+ secret: urlParams.get('secret') || undefined,
69
+ env: validEnv,
70
+ template_id: urlParams.get('template_id') || undefined,
71
+ server_env: validServerEnv,
72
+ step: urlParams.get('step') || undefined,
43
73
  };
44
74
  }, []);
45
75
 
46
- // Safe redirect function with validation
47
- const redirectToReturnUrl = useCallback((params: {
76
+ // Safe redirect function with enhanced validation
77
+ const redirectToReturnUrl = useCallback(async (params: {
48
78
  status: 'completed' | 'cancelled' | 'error';
49
79
  kyc_id?: string;
50
80
  message?: string;
51
- sig?: string;
81
+ processing_state?: 'analyzing' | 'completed' | 'pending';
82
+ verification_steps?: VerificationSteps;
52
83
  }) => {
53
84
  const { return_url } = urlParams;
54
-
85
+
55
86
  if (!return_url) {
56
87
  console.warn('No return_url provided');
57
88
  return;
58
89
  }
59
90
 
60
- // Basic URL validation - ensure it's a valid URL
61
91
  try {
62
- const returnUrl = new URL(return_url);
63
-
64
- // Optional: Add domain allowlist validation here
65
- // const allowedDomains = ['example.com', 'trusted-site.com'];
66
- // if (!allowedDomains.some(domain => returnUrl.hostname.endsWith(domain))) {
67
- // console.error('Return URL not in allowlist');
68
- // return;
69
- // }
70
-
71
- // Build redirect URL with parameters
72
- const redirectUrl = new URL(returnUrl);
73
- redirectUrl.searchParams.set('status', params.status);
74
-
75
- if (params.kyc_id) {
76
- redirectUrl.searchParams.set('kyc_id', params.kyc_id);
77
- }
78
-
79
- if (params.message) {
80
- redirectUrl.searchParams.set('message', params.message);
81
- }
82
-
83
- if (params.sig) {
84
- redirectUrl.searchParams.set('sig', params.sig);
85
- }
92
+ // Enhanced URL validation with domain whitelist
93
+ const validation = isCallbackUrlAllowed(return_url);
94
+ if (!validation.allowed) {
95
+ console.error('Callback URL validation failed:', validation.reason);
96
+ setError(`Security Error: ${validation.reason}`);
86
97
 
87
- // Optional: Send postMessage to parent if in iframe
98
+ // Log suspicious redirect attempt
99
+ console.warn('Suspicious redirect attempt blocked:', {
100
+ url: return_url,
101
+ reason: validation.reason,
102
+ timestamp: new Date().toISOString(),
103
+ });
104
+ return;
105
+ }
106
+ // Send postMessage to parent if in iframe
88
107
  if (window.parent !== window) {
108
+ const targetOrigin = new URL(return_url).origin;
89
109
  window.parent.postMessage({
90
110
  type: 'kyc_result',
91
111
  status: params.status,
92
112
  kyc_id: params.kyc_id,
93
113
  message: params.message,
94
- }, '*');
114
+ processing_state: params.processing_state,
115
+ verification_steps: params.verification_steps,
116
+ }, targetOrigin);
117
+ } else {
118
+ window.location.href = return_url;
95
119
  }
96
-
97
- // Redirect to return URL
98
- window.location.href = redirectUrl.toString();
99
120
  } catch (error) {
100
- console.error('Invalid return URL:', error);
101
- setError('Invalid return URL provided');
121
+ console.error('Error during redirect:', error);
122
+ setError('Failed to redirect to callback URL');
102
123
  }
103
124
  }, [urlParams]);
104
125
 
105
126
  // Handle KYC completion
106
- const handleComplete = useCallback((data: any) => {
127
+ const handleComplete = useCallback(async (data: any) => {
107
128
  console.log('KYC completed:', data);
129
+
130
+ // Check if still processing/analyzing
131
+ const isStillProcessing = data.isProcessing || data.session?.isProcessing;
132
+
133
+ // Handle Push URL webhook if provided
134
+ if (urlParams.push_url) {
135
+ try {
136
+ const verificationState = {
137
+ status: 'success', // verification completed successfully
138
+ result: data, // pass complete data object as result
139
+ };
140
+
141
+ // Send data to provided push_url with a timeout
142
+ const controller = new AbortController();
143
+ const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
144
+
145
+ await fetch(urlParams.push_url, {
146
+ method: 'POST',
147
+ headers: {
148
+ 'Content-Type': 'application/json',
149
+ },
150
+ body: JSON.stringify(verificationState),
151
+ signal: controller.signal,
152
+ });
153
+
154
+ clearTimeout(timeoutId);
155
+ console.log('Successfully pushed KYC data to webhook');
156
+ } catch (err) {
157
+ // Fail open - redirect anyway even if webhook fails
158
+ console.warn('Failed to push data to webhook URL:', err);
159
+ }
160
+ }
161
+
108
162
  redirectToReturnUrl({
109
163
  status: 'completed',
110
164
  kyc_id: data.session_id || urlParams.kyc_id,
111
165
  message: 'KYC process completed successfully',
166
+ processing_state: isStillProcessing ? 'analyzing' : 'completed',
167
+ verification_steps: {
168
+ document_analyzed: data.documentAnalysisComplete || false,
169
+ selfie_analyzed: data.selfieAnalysisComplete || false,
170
+ liveness_checked: data.livenessCheckComplete || false,
171
+ },
112
172
  });
113
173
  onComplete?.(data);
114
- }, [redirectToReturnUrl, urlParams.kyc_id, onComplete]);
174
+ }, [redirectToReturnUrl, urlParams, onComplete]);
115
175
 
116
176
  // Handle KYC error
117
177
  const handleError = useCallback((error: string) => {
118
178
  console.error('KYC error:', error);
179
+ setIsAnalyzing(false);
119
180
  redirectToReturnUrl({
120
181
  status: 'error',
121
182
  kyc_id: urlParams.kyc_id,
122
183
  message: error,
184
+ processing_state: 'pending',
123
185
  });
124
186
  onError?.(error);
125
187
  }, [redirectToReturnUrl, urlParams.kyc_id, onError]);
126
188
 
127
189
  // Handle KYC cancellation
128
190
  const handleCancel = useCallback(() => {
129
- console.log('KYC cancelled');
191
+ console.log('KYC cancelled', urlParams.push_url, urlParams);
192
+ setIsAnalyzing(false);
193
+ if (urlParams.push_url) {
194
+ try {
195
+ const verificationState = {
196
+ status: 'cancelled', // verification cancelled
197
+ result: null, // pass null as result
198
+ };
199
+
200
+ // Send data to provided push_url with a timeout
201
+ const controller = new AbortController();
202
+ const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
203
+
204
+ fetch(urlParams.push_url, {
205
+ method: 'POST',
206
+ headers: {
207
+ 'Content-Type': 'application/json',
208
+ },
209
+ body: JSON.stringify(verificationState),
210
+ signal: controller.signal,
211
+ });
212
+
213
+ clearTimeout(timeoutId);
214
+ console.log('Successfully pushed KYC cancellation data to webhook');
215
+ } catch (err) {
216
+ // Fail open - redirect anyway even if webhook fails
217
+ console.warn('Failed to push data to webhook URL:', err);
218
+ }
219
+ }
130
220
  redirectToReturnUrl({
131
221
  status: 'cancelled',
132
222
  kyc_id: urlParams.kyc_id,
133
223
  message: 'KYC process was cancelled',
224
+ processing_state: 'pending',
134
225
  });
135
226
  onCancel?.();
136
227
  }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
@@ -140,12 +231,17 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
140
231
  try {
141
232
  const params = parseUrlParams();
142
233
  setUrlParams(params);
143
-
234
+
144
235
  // Set language if provided
145
236
  if (params.lang) {
146
237
  setLocale(params.lang);
147
238
  }
148
-
239
+
240
+ // Configure backend environment
241
+ if (params.server_env) {
242
+ KYCConfig.setBackendEnvironment(params.server_env);
243
+ }
244
+
149
245
  setIsLoading(false);
150
246
  } catch (error) {
151
247
  console.error('Error parsing URL parameters:', error);
@@ -181,13 +277,30 @@ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
181
277
 
182
278
  return (
183
279
  <SafeAreaView style={styles.container}>
184
- <TemplateKYCExample
185
- onComplete={handleComplete}
186
- onCancel={handleCancel}
187
- onError={handleError}
188
- language={urlParams.lang || 'en'}
189
- API_KEY={urlParams.token}
190
- />
280
+ {isAnalyzing && (
281
+ <View style={styles.analyzingOverlay}>
282
+ <View style={styles.analyzingContainer}>
283
+ <ActivityIndicator size="large" color="#2DBD60" />
284
+ <Text style={styles.analyzingText}>Analyzing verification data...</Text>
285
+ <Text style={styles.analyzingSubtext}>This may take a few moments</Text>
286
+ </View>
287
+ </View>
288
+ )}
289
+ <TemplateKYCExample
290
+ onComplete={handleComplete}
291
+ onCancel={handleCancel}
292
+ onError={handleError}
293
+ language={urlParams.lang || 'en'}
294
+ API_KEY={urlParams.token}
295
+ templateId={urlParams.template_id}
296
+ env={urlParams.env || 'PRODUCTION'}
297
+ existingSessionId={urlParams.kyc_id}
298
+ initialStep={urlParams.step ? (() => {
299
+ const stepNum = parseInt(urlParams.step, 10);
300
+ console.log('Parsing step from URL:', { stepString: urlParams.step, stepNumber: stepNum, isNaN: isNaN(stepNum) });
301
+ return isNaN(stepNum) ? undefined : stepNum;
302
+ })() : undefined}
303
+ />
191
304
  </SafeAreaView>
192
305
  );
193
306
  };
@@ -196,6 +309,7 @@ const styles = StyleSheet.create({
196
309
  container: {
197
310
  flex: 1,
198
311
  backgroundColor: '#f5f5f5',
312
+ overflow: 'visible' as any, // Allow scrolling on web
199
313
  },
200
314
  loadingText: {
201
315
  fontSize: 18,
@@ -210,6 +324,41 @@ const styles = StyleSheet.create({
210
324
  color: '#dc2626',
211
325
  paddingHorizontal: 20,
212
326
  },
327
+ analyzingOverlay: {
328
+ position: 'absolute',
329
+ top: 0,
330
+ left: 0,
331
+ right: 0,
332
+ bottom: 0,
333
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
334
+ justifyContent: 'center',
335
+ alignItems: 'center',
336
+ zIndex: 9999,
337
+ },
338
+ analyzingContainer: {
339
+ backgroundColor: 'white',
340
+ borderRadius: 12,
341
+ padding: 32,
342
+ alignItems: 'center',
343
+ shadowColor: '#000',
344
+ shadowOffset: { width: 0, height: 4 },
345
+ shadowOpacity: 0.3,
346
+ shadowRadius: 8,
347
+ elevation: 8,
348
+ },
349
+ analyzingText: {
350
+ fontSize: 18,
351
+ fontWeight: '600',
352
+ color: '#333',
353
+ marginTop: 16,
354
+ textAlign: 'center',
355
+ },
356
+ analyzingSubtext: {
357
+ fontSize: 14,
358
+ color: '#666',
359
+ marginTop: 8,
360
+ textAlign: 'center',
361
+ },
213
362
  });
214
363
 
215
364
  export default WebKYCEntry;