omnipay-reactnative-sdk 1.2.2-beta.8 → 1.2.3-beta.0

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 (66) hide show
  1. package/README.md +43 -93
  2. package/android/build.gradle +0 -9
  3. package/android/src/main/AndroidManifest.xml +0 -5
  4. package/android/src/main/java/com/omniretail/omnipay/OmnipayActivityPackage.java +1 -4
  5. package/lib/commonjs/components/OmnipayProvider.js +1 -1
  6. package/lib/commonjs/components/biometrics/FaceVerification.js +235 -275
  7. package/lib/commonjs/components/biometrics/FaceVerification.js.map +1 -1
  8. package/lib/commonjs/index.js +0 -33
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/module/components/OmnipayProvider.js +1 -1
  11. package/lib/module/components/biometrics/FaceVerification.js +237 -277
  12. package/lib/module/components/biometrics/FaceVerification.js.map +1 -1
  13. package/lib/module/index.js +0 -6
  14. package/lib/module/index.js.map +1 -1
  15. package/lib/typescript/components/biometrics/FaceVerification.d.ts +1 -3
  16. package/lib/typescript/components/biometrics/FaceVerification.d.ts.map +1 -1
  17. package/lib/typescript/index.d.ts +0 -2
  18. package/lib/typescript/index.d.ts.map +1 -1
  19. package/package.json +4 -2
  20. package/src/components/OmnipayProvider.tsx +1 -1
  21. package/src/components/biometrics/FaceVerification.tsx +232 -317
  22. package/src/index.tsx +0 -7
  23. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraView.java +0 -153
  24. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraViewManager.java +0 -49
  25. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessModule.java +0 -557
  26. package/ios/OmnipayLivenessCameraView.h +0 -15
  27. package/ios/OmnipayLivenessCameraView.m +0 -80
  28. package/ios/OmnipayLivenessCameraViewManager.m +0 -19
  29. package/ios/OmnipayLivenessModule.h +0 -38
  30. package/ios/OmnipayLivenessModule.m +0 -615
  31. package/lib/commonjs/components/biometrics/LivenessDetection.js +0 -149
  32. package/lib/commonjs/components/biometrics/LivenessDetection.js.map +0 -1
  33. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js +0 -15
  34. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
  35. package/lib/commonjs/components/biometrics/PermissionManager.js +0 -279
  36. package/lib/commonjs/components/biometrics/PermissionManager.js.map +0 -1
  37. package/lib/commonjs/components/biometrics/index.js +0 -45
  38. package/lib/commonjs/components/biometrics/index.js.map +0 -1
  39. package/lib/commonjs/components/biometrics/types.js +0 -17
  40. package/lib/commonjs/components/biometrics/types.js.map +0 -1
  41. package/lib/module/components/biometrics/LivenessDetection.js +0 -129
  42. package/lib/module/components/biometrics/LivenessDetection.js.map +0 -1
  43. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js +0 -7
  44. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
  45. package/lib/module/components/biometrics/PermissionManager.js +0 -272
  46. package/lib/module/components/biometrics/PermissionManager.js.map +0 -1
  47. package/lib/module/components/biometrics/index.js +0 -12
  48. package/lib/module/components/biometrics/index.js.map +0 -1
  49. package/lib/module/components/biometrics/types.js +0 -16
  50. package/lib/module/components/biometrics/types.js.map +0 -1
  51. package/lib/typescript/components/biometrics/LivenessDetection.d.ts +0 -33
  52. package/lib/typescript/components/biometrics/LivenessDetection.d.ts.map +0 -1
  53. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts +0 -18
  54. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts.map +0 -1
  55. package/lib/typescript/components/biometrics/PermissionManager.d.ts +0 -58
  56. package/lib/typescript/components/biometrics/PermissionManager.d.ts.map +0 -1
  57. package/lib/typescript/components/biometrics/index.d.ts +0 -5
  58. package/lib/typescript/components/biometrics/index.d.ts.map +0 -1
  59. package/lib/typescript/components/biometrics/types.d.ts +0 -73
  60. package/lib/typescript/components/biometrics/types.d.ts.map +0 -1
  61. package/omnipay-reactnative-sdk.podspec +0 -50
  62. package/src/components/biometrics/LivenessDetection.ts +0 -178
  63. package/src/components/biometrics/OmnipayLivenessCameraView.tsx +0 -19
  64. package/src/components/biometrics/PermissionManager.ts +0 -317
  65. package/src/components/biometrics/index.ts +0 -11
  66. package/src/components/biometrics/types.ts +0 -86
@@ -1,211 +1,98 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import {
3
3
  View,
4
4
  Modal,
5
5
  Dimensions,
6
+ Platform,
6
7
  StyleSheet,
7
8
  TouchableOpacity,
8
9
  Image,
9
10
  Text,
10
11
  ActivityIndicator,
11
12
  } from 'react-native';
12
- import { LivenessDetection } from './LivenessDetection';
13
- import { OmnipayLivenessCameraView } from './OmnipayLivenessCameraView';
14
- import { CameraPermissionManager, PermissionResult } from './PermissionManager';
15
- import { LivenessChallenge, type LivenessConfig } from './types';
13
+ import {
14
+ Camera,
15
+ useCameraDevice,
16
+ useCameraPermission,
17
+ } from 'react-native-vision-camera';
16
18
 
17
19
  type FaceVerificationProps = {
18
20
  onClose: () => void;
19
- onSuccess: (result?: any) => void;
21
+ onSuccess: () => void;
20
22
  primaryColor: string;
21
- config?: Partial<LivenessConfig>;
22
23
  };
23
24
 
24
- type DetectionState =
25
- | 'initializing'
26
- | 'starting'
27
- | 'running'
28
- | 'completed'
29
- | 'failed';
30
-
31
25
  const FaceVerification: React.FC<FaceVerificationProps> = ({
32
26
  onClose,
33
27
  onSuccess,
34
28
  primaryColor,
35
- config,
36
29
  }) => {
37
- const [state, setState] = useState<DetectionState>('initializing');
38
- const [error, setError] = useState<string | null>(null);
39
- const [isSupported, setIsSupported] = useState<boolean>(false);
40
- const [currentChallenge, setCurrentChallenge] =
41
- useState<LivenessChallenge | null>(null);
42
- const [challengeProgress, setChallengeProgress] = useState<string>('');
43
-
44
- useEffect(() => {
45
- checkSupport();
46
- // eslint-disable-next-line react-hooks/exhaustive-deps
47
- }, []);
30
+ const device = useCameraDevice('front');
31
+ const { hasPermission, requestPermission } = useCameraPermission();
32
+ const [isRequestingPermission, setIsRequestingPermission] = useState(false);
48
33
 
49
- const checkSupport = async () => {
34
+ const handleRequestPermission = async () => {
35
+ setIsRequestingPermission(true);
50
36
  try {
51
- console.log('🔍 Starting liveness detection initialization...');
52
-
53
- // Step 1: Request camera permission first
54
- console.log('📹 Requesting camera permission...');
55
- const permissionResponse =
56
- await CameraPermissionManager.requestCameraPermission();
57
-
58
- if (permissionResponse.result !== PermissionResult.GRANTED) {
59
- console.log('❌ Camera permission denied:', permissionResponse.result);
60
- setState('failed');
61
- setError(
62
- permissionResponse.result === PermissionResult.BLOCKED
63
- ? 'Camera permission is blocked. Please enable it in device settings.'
64
- : 'Camera permission is required for face verification.'
65
- );
66
- return;
67
- }
68
-
69
- console.log('✅ Camera permission granted');
70
-
71
- // Step 2: Check device support (hardware/framework capability)
72
- console.log('🔍 Checking device capabilities...');
73
- const supported = await LivenessDetection.isSupported();
74
- console.log('📱 Device support result:', supported);
75
-
76
- setIsSupported(supported);
77
- if (supported) {
78
- console.log('✅ Device supports liveness detection, starting...');
79
- await startDetection();
80
- } else {
81
- console.log('❌ Device does not support liveness detection');
82
- setState('failed');
83
- setError('Liveness detection is not supported on this device');
84
- }
85
- } catch (err) {
86
- console.error('💥 Error during initialization:', err);
87
- setState('failed');
88
- setError('Failed to initialize liveness detection');
37
+ await requestPermission();
38
+ } catch (error) {
39
+ console.error('Error requesting camera permission:', error);
40
+ } finally {
41
+ setIsRequestingPermission(false);
89
42
  }
90
43
  };
91
44
 
92
- const startDetection = async () => {
93
- if (!isSupported) {
94
- return;
95
- }
96
-
97
- setState('starting');
98
- setError(null);
99
-
100
- try {
101
- // Permission already checked in checkSupport(), proceed with detection
102
- console.log('🚀 Starting liveness detection with config...');
103
-
104
- const livenessConfig = {
105
- ...LivenessDetection.getDefaultConfig(),
106
- ...config,
107
- };
108
-
109
- const result = await LivenessDetection.startDetection(livenessConfig, {
110
- onChallengeStart: (challenge) => {
111
- setCurrentChallenge(challenge);
112
- setState('running');
113
- setChallengeProgress(getChallengeInstruction(challenge));
114
- },
115
- onChallengeSuccess: (challenge, _challengeResult) => {
116
- setChallengeProgress(
117
- `✓ ${getChallengeInstruction(challenge)} completed`
118
- );
119
- },
120
- onChallengeFailure: (challenge, reason) => {
121
- setError(`Failed: ${reason}, ${challenge}`);
122
- },
123
- onAllChallengesComplete: () => {
124
- setChallengeProgress(
125
- 'All challenges completed! Taking final photo...'
126
- );
127
- },
128
- onScreenshotCaptured: (_screenshot) => {
129
- // Screenshot captured, detection will complete soon
130
- },
131
- onDetectionFailed: (reason) => {
132
- setError(reason);
133
- setState('failed');
134
- },
135
- });
136
-
137
- if (result.success) {
138
- setState('completed');
139
- setTimeout(() => {
140
- onSuccess(result);
141
- }, 1000); // Brief delay to show success state
142
- } else {
143
- setState('failed');
144
- setError(result.failureReason || 'Face verification failed');
145
- }
146
- } catch (err) {
147
- setState('failed');
148
- setError(err instanceof Error ? err.message : 'Unknown error occurred');
149
- }
150
- };
151
-
152
- const getChallengeInstruction = (challenge: LivenessChallenge): string => {
153
- switch (challenge) {
154
- case LivenessChallenge.SMILE:
155
- return 'Please smile';
156
- case LivenessChallenge.BLINK:
157
- return 'Please blink';
158
- case LivenessChallenge.TURN_LEFT:
159
- return 'Please turn your head left';
160
- case LivenessChallenge.TURN_RIGHT:
161
- return 'Please turn your head right';
162
- default:
163
- return 'Follow the instruction';
164
- }
165
- };
45
+ const renderPermissionRequest = () => (
46
+ <View style={styles.permissionContainer}>
47
+ <View style={styles.permissionIconContainer}>
48
+ <Text style={styles.permissionIcon}>📷</Text>
49
+ </View>
50
+ <Text style={styles.permissionTitle}>Camera Permission Required</Text>
51
+ <Text style={styles.permissionDescription}>
52
+ To verify your identity, we need access to your camera. This allows us
53
+ to capture your face for secure verification.
54
+ </Text>
55
+ <TouchableOpacity
56
+ style={[styles.permissionButton, { backgroundColor: primaryColor }]}
57
+ onPress={handleRequestPermission}
58
+ disabled={isRequestingPermission}
59
+ >
60
+ {isRequestingPermission ? (
61
+ <ActivityIndicator color="white" size="small" />
62
+ ) : (
63
+ <Text style={styles.permissionButtonText}>Allow Camera Access</Text>
64
+ )}
65
+ </TouchableOpacity>
66
+ </View>
67
+ );
166
68
 
167
- const getStateMessage = (): string => {
168
- switch (state) {
169
- case 'initializing':
170
- return 'Initializing camera...';
171
- case 'starting':
172
- return 'Starting face verification...';
173
- case 'running':
174
- return challengeProgress || 'Look at the camera';
175
- case 'completed':
176
- return 'Face verification completed!';
177
- case 'failed':
178
- return error || 'Face verification failed';
179
- default:
180
- return 'Please wait...';
181
- }
182
- };
69
+ const renderNoDevice = () => (
70
+ <View style={styles.errorContainer}>
71
+ <Text style={styles.errorTitle}>Camera Not Available</Text>
72
+ <Text style={styles.errorSubtitle}>
73
+ No front camera detected on this device. Face verification requires a
74
+ front-facing camera.
75
+ </Text>
76
+ </View>
77
+ );
183
78
 
184
- const getStateColor = (): string => {
185
- switch (state) {
186
- case 'completed':
187
- return '#4CAF50';
188
- case 'failed':
189
- return '#F44336';
190
- case 'running':
191
- return primaryColor;
192
- default:
193
- return '#666';
194
- }
195
- };
79
+ const renderCamera = () => {
80
+ if (!device) return null;
196
81
 
197
- const handleRetry = () => {
198
- setState('initializing');
199
- setError(null);
200
- setCurrentChallenge(null);
201
- setChallengeProgress('');
202
- checkSupport();
82
+ return (
83
+ <View style={styles.cameraContainer}>
84
+ <Camera device={device} style={styles.camera} isActive={true} />
85
+ <View style={styles.cameraOverlay}>
86
+ <View style={styles.faceFrame} />
87
+ <Text style={styles.instructionText}>
88
+ Position your face within the frame
89
+ </Text>
90
+ </View>
91
+ </View>
92
+ );
203
93
  };
204
94
 
205
- const showRetryButton =
206
- state === 'failed' &&
207
- error !==
208
- 'Camera permission is blocked. Please enable it in device settings.';
95
+ console.log(onSuccess, primaryColor);
209
96
 
210
97
  return (
211
98
  <Modal
@@ -217,7 +104,7 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
217
104
  <TouchableOpacity
218
105
  style={styles.backdrop}
219
106
  activeOpacity={1}
220
- onPress={() => {}}
107
+ onPress={onClose}
221
108
  >
222
109
  <View style={[styles.container]}>
223
110
  <TouchableOpacity style={styles.close} onPress={onClose}>
@@ -226,61 +113,10 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
226
113
  style={styles.closeIcon}
227
114
  />
228
115
  </TouchableOpacity>
229
-
230
116
  <View style={styles.contentContainer}>
231
- <Text style={styles.title}>Face Verification</Text>
232
-
233
- {/* Camera Preview */}
234
- <View style={styles.cameraContainer}>
235
- {state === 'running' && isSupported ? (
236
- <OmnipayLivenessCameraView style={styles.camera} />
237
- ) : (
238
- <View style={[styles.camera, styles.cameraPlaceholder]}>
239
- {state === 'initializing' || state === 'starting' ? (
240
- <ActivityIndicator size="large" color={primaryColor} />
241
- ) : state === 'completed' ? (
242
- <View style={styles.successIcon}>
243
- <Text style={styles.successText}>✓</Text>
244
- </View>
245
- ) : (
246
- <View style={styles.errorIcon}>
247
- <Text style={styles.errorText}>!</Text>
248
- </View>
249
- )}
250
- </View>
251
- )}
252
-
253
- {/* Overlay with instructions */}
254
- <View style={styles.overlay}>
255
- <Text style={[styles.instruction, { color: getStateColor() }]}>
256
- {getStateMessage()}
257
- </Text>
258
- </View>
259
- </View>
260
-
261
- {/* Progress indicator for challenges */}
262
- {state === 'running' && currentChallenge && (
263
- <View style={styles.progressContainer}>
264
- <Text style={styles.challengeText}>
265
- {getChallengeInstruction(currentChallenge)}
266
- </Text>
267
- </View>
268
- )}
269
-
270
- {/* Action buttons */}
271
- <View style={styles.buttonContainer}>
272
- {showRetryButton && (
273
- <TouchableOpacity
274
- style={[
275
- styles.retryButton,
276
- { backgroundColor: primaryColor },
277
- ]}
278
- onPress={handleRetry}
279
- >
280
- <Text style={styles.retryButtonText}>Try Again</Text>
281
- </TouchableOpacity>
282
- )}
283
- </View>
117
+ {!hasPermission && renderPermissionRequest()}
118
+ {hasPermission && !device && renderNoDevice()}
119
+ {hasPermission && device && renderCamera()}
284
120
  </View>
285
121
  </View>
286
122
  </TouchableOpacity>
@@ -288,136 +124,215 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
288
124
  );
289
125
  };
290
126
 
291
- const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
127
+ export default FaceVerification;
292
128
 
293
129
  const styles = StyleSheet.create({
294
- modal: {
295
- margin: 0,
130
+ hide: {
131
+ display: 'none',
296
132
  },
297
- backdrop: {
133
+ full: {
298
134
  flex: 1,
299
- backgroundColor: 'rgba(0, 0, 0, 0.8)',
300
- justifyContent: 'center',
135
+ width: '100%',
136
+ height: '100%',
137
+ },
138
+ webview: {
139
+ flex: 1,
140
+ width: '100%',
141
+ height: Dimensions.get('window').height - 40,
142
+ backgroundColor: 'white',
143
+ borderTopRightRadius: 20,
144
+ borderTopLeftRadius: 20,
145
+ paddingTop: 150,
146
+ },
147
+ webviewLoader: {
148
+ zIndex: 3,
149
+ backgroundColor: 'white',
301
150
  alignItems: 'center',
151
+ justifyContent: 'center',
152
+ flex: 1,
153
+ width: '100%',
154
+ height: '100%',
155
+ position: 'absolute',
156
+ top: 0,
157
+ left: 0,
158
+ borderTopRightRadius: 20,
159
+ borderTopLeftRadius: 20,
160
+ },
161
+ backdrop: {
162
+ backgroundColor: 'rgba(0,0,0,0.3)',
163
+ flex: 1,
164
+ justifyContent: 'flex-end',
165
+ position: 'relative',
166
+ height: '100%',
302
167
  },
303
168
  container: {
304
- width: screenWidth * 0.9,
305
- maxHeight: screenHeight * 0.8,
306
169
  backgroundColor: 'white',
307
- borderRadius: 16,
308
- padding: 20,
309
- alignItems: 'center',
170
+ borderTopRightRadius: 20,
171
+ borderTopLeftRadius: 20,
172
+ maxHeight: Dimensions.get('window').height - 120,
173
+ flex: 1,
174
+ position: 'relative',
175
+ ...(Platform.OS === 'android' && { overflow: 'hidden' }),
176
+ },
177
+ modal: {
178
+ flex: 1,
179
+ backgroundColor: 'rgba(0,0,0,0.48)',
180
+ height: '100%',
181
+ width: '100%',
310
182
  },
311
183
  close: {
312
184
  position: 'absolute',
313
- top: 15,
314
- right: 15,
315
- zIndex: 10,
316
- padding: 5,
185
+ top: 10,
186
+ right: 10,
187
+ backgroundColor: 'white',
188
+ height: 24,
189
+ width: 24,
190
+ borderRadius: 1000,
191
+ alignItems: 'center',
192
+ justifyContent: 'center',
193
+ zIndex: 2,
317
194
  },
318
195
  closeIcon: {
319
- width: 20,
320
- height: 20,
321
- tintColor: '#666',
196
+ height: 12,
197
+ width: 12,
322
198
  },
323
199
  contentContainer: {
324
- width: '100%',
325
- alignItems: 'center',
326
- paddingTop: 20,
200
+ height: '100%',
201
+ position: 'relative',
202
+ borderTopRightRadius: 20,
203
+ borderTopLeftRadius: 20,
204
+ padding: 16,
327
205
  },
328
- title: {
329
- fontSize: 24,
330
- fontWeight: 'bold',
331
- color: '#333',
332
- marginBottom: 20,
333
- textAlign: 'center',
206
+ testContent: {
207
+ paddingTop: 30,
208
+ paddingLeft: 16,
334
209
  },
335
- cameraContainer: {
336
- width: screenWidth * 0.7,
337
- height: screenWidth * 0.9,
338
- borderRadius: 12,
339
- overflow: 'hidden',
340
- backgroundColor: '#f0f0f0',
341
- position: 'relative',
210
+ testTwoContent: {
211
+ paddingTop: 10,
212
+ paddingLeft: 16,
213
+ },
214
+ errorSubtitle: {
215
+ textAlign: 'center',
216
+ fontSize: 14,
217
+ color: '#5e7079',
342
218
  marginBottom: 20,
219
+ paddingHorizontal: 8,
220
+ marginTop: 14,
221
+ },
222
+ errorContainer: {
223
+ flex: 1,
224
+ justifyContent: 'center',
225
+ alignItems: 'center',
226
+ width: Dimensions.get('window').width,
227
+ height: Dimensions.get('window').height,
228
+ zIndex: 2,
229
+ backgroundColor: 'white',
230
+ },
231
+ retryButton: {
232
+ minWidth: 160,
233
+ marginHorizontal: 'auto',
234
+ },
235
+ button: {
236
+ borderRadius: 6,
237
+ paddingHorizontal: 12,
238
+ paddingVertical: 14,
239
+ borderWidth: 1,
240
+ alignItems: 'center',
241
+ justifyContent: 'center',
343
242
  },
243
+ buttonText: { color: 'white', fontSize: 16, paddingHorizontal: 30 },
344
244
  camera: {
345
245
  flex: 1,
346
246
  width: '100%',
347
- height: '100%',
247
+ height: 400,
348
248
  },
349
- cameraPlaceholder: {
249
+ // Permission request styles
250
+ permissionContainer: {
251
+ flex: 1,
350
252
  justifyContent: 'center',
351
253
  alignItems: 'center',
352
- backgroundColor: '#f5f5f5',
254
+ paddingHorizontal: 24,
255
+ paddingVertical: 40,
353
256
  },
354
- overlay: {
355
- position: 'absolute',
356
- bottom: 0,
357
- left: 0,
358
- right: 0,
359
- backgroundColor: 'rgba(0, 0, 0, 0.7)',
360
- padding: 15,
257
+ permissionIconContainer: {
258
+ width: 80,
259
+ height: 80,
260
+ borderRadius: 40,
261
+ backgroundColor: '#f0f0f0',
262
+ justifyContent: 'center',
361
263
  alignItems: 'center',
264
+ marginBottom: 24,
362
265
  },
363
- instruction: {
364
- fontSize: 16,
365
- fontWeight: '600',
366
- textAlign: 'center',
367
- color: 'white',
368
- },
369
- progressContainer: {
370
- marginBottom: 20,
371
- alignItems: 'center',
266
+ permissionIcon: {
267
+ fontSize: 40,
372
268
  },
373
- challengeText: {
374
- fontSize: 18,
269
+ permissionTitle: {
270
+ fontSize: 20,
375
271
  fontWeight: '600',
376
- color: '#333',
272
+ color: '#1a1a1a',
377
273
  textAlign: 'center',
274
+ marginBottom: 12,
378
275
  },
379
- buttonContainer: {
380
- flexDirection: 'row',
381
- justifyContent: 'center',
382
- gap: 15,
276
+ permissionDescription: {
277
+ fontSize: 16,
278
+ color: '#666',
279
+ textAlign: 'center',
280
+ lineHeight: 22,
281
+ marginBottom: 32,
383
282
  },
384
- retryButton: {
385
- paddingHorizontal: 30,
386
- paddingVertical: 12,
283
+ permissionButton: {
284
+ paddingHorizontal: 32,
285
+ paddingVertical: 16,
387
286
  borderRadius: 8,
287
+ minWidth: 200,
388
288
  alignItems: 'center',
289
+ justifyContent: 'center',
389
290
  },
390
- retryButtonText: {
291
+ permissionButtonText: {
391
292
  color: 'white',
392
293
  fontSize: 16,
393
294
  fontWeight: '600',
394
295
  },
395
- successIcon: {
396
- width: 60,
397
- height: 60,
398
- borderRadius: 30,
399
- backgroundColor: '#4CAF50',
400
- justifyContent: 'center',
401
- alignItems: 'center',
296
+ // Error styles
297
+ errorTitle: {
298
+ fontSize: 18,
299
+ fontWeight: '600',
300
+ color: '#1a1a1a',
301
+ textAlign: 'center',
302
+ marginBottom: 8,
402
303
  },
403
- successText: {
404
- fontSize: 30,
405
- color: 'white',
406
- fontWeight: 'bold',
304
+ // Camera styles
305
+ cameraContainer: {
306
+ flex: 1,
307
+ position: 'relative',
407
308
  },
408
- errorIcon: {
409
- width: 60,
410
- height: 60,
411
- borderRadius: 30,
412
- backgroundColor: '#F44336',
309
+ cameraOverlay: {
310
+ position: 'absolute',
311
+ top: 0,
312
+ left: 0,
313
+ right: 0,
314
+ bottom: 0,
413
315
  justifyContent: 'center',
414
316
  alignItems: 'center',
415
317
  },
416
- errorText: {
417
- fontSize: 30,
318
+ faceFrame: {
319
+ width: 200,
320
+ height: 250,
321
+ borderWidth: 3,
322
+ borderColor: 'white',
323
+ borderRadius: 100,
324
+ borderStyle: 'dashed',
325
+ backgroundColor: 'transparent',
326
+ },
327
+ instructionText: {
418
328
  color: 'white',
419
- fontWeight: 'bold',
329
+ fontSize: 16,
330
+ fontWeight: '500',
331
+ textAlign: 'center',
332
+ marginTop: 20,
333
+ backgroundColor: 'rgba(0,0,0,0.5)',
334
+ paddingHorizontal: 16,
335
+ paddingVertical: 8,
336
+ borderRadius: 20,
420
337
  },
421
338
  });
422
-
423
- export default FaceVerification;
package/src/index.tsx CHANGED
@@ -2,11 +2,4 @@ import Omnipay from './components/OmnipayView';
2
2
 
3
3
  export { OmnipayProvider } from './components/OmnipayProvider';
4
4
  export { useOmnipay } from './hooks/useOmnipay';
5
-
6
- // Biometric components and utilities
7
- export { FaceVerification, LivenessDetection } from './components/biometrics';
8
-
9
- // Biometric types
10
- export * from './components/biometrics/types';
11
-
12
5
  export default Omnipay;