# Finos eKYC SDK Module v0.0.31

A comprehensive React Native module for electronic Know Your Customer (eKYC) operations including Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, and C06 residence verification.

## 🚀 Features

- **📡 NFC Scanning** - Vietnamese CCCD NFC reading
- **🏠 C06 Verification** - Residence verification
- **📄 OCR Processing** - Document text recognition
- **👁️ Liveness Detection** - Anti-spoofing face verification
- **👤 Face Comparison** - Identity verification through face matching
- **🔧 SDK Management** - Initialization and lifecycle management
- **📱 Cross-platform** - Android support with iOS compatibility layer

## 📦 Installation

```bash
npm install @finos_sdk/sdk-ekyc@0.0.31
```

## 🛠️ Setup

### Android Configuration

1. Add permissions to `android/app/src/main/AndroidManifest.xml`:

```xml
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```

2. Add NFC intent filters:

```xml
<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
```

## 📖 Usage

### Basic Setup

```typescript
import { finosEKYC } from '@finos_sdk/sdk-ekyc';

// Initialize SDK
await finosEKYC.initialize();

// Get SDK info
const sdkInfo = await finosEKYC.getSDKInfo();
console.log('SDK Version:', sdkInfo.version);
```

### NFC Scanning

```typescript
import { finosEKYC, NfcConfig } from '@finos_sdk/sdk-ekyc';

const nfcConfig: NfcConfig = {
  appKey: 'your-app-key',
  documentNumber: '123456789',
  birthDate: '1990-01-01',
  expireDate: '2030-01-01',
  transactionId: 'txn-123',
  facePathStorage: '/storage/emulated/0/Download'
};

try {
  const result = await finosEKYC.startNfcScan(nfcConfig);
  console.log('NFC Result:', result.event, result.data);
} catch (error) {
  console.error('NFC Error:', error);
}
```

### OCR Processing

```typescript
import { finosEKYC, OcrConfig } from '@finos_sdk/sdk-ekyc';

const ocrConfig: OcrConfig = {
  appKey: 'your-app-key',
  idImagePath: 'base64-image-data',
  expectedDocumentSide: 'front',
  transactionId: 'txn-123'
};

try {
  const result = await finosEKYC.startOCR(ocrConfig);
  console.log('OCR Result:', result.event, result.data);
} catch (error) {
  console.error('OCR Error:', error);
}
```

### Liveness Detection

```typescript
import { finosEKYC, LivenessConfig, SDKFaceDetectStatus } from '@finos_sdk/sdk-ekyc';

const livenessConfig: LivenessConfig = {
  appKey: 'your-app-key',
  selfieImage: 'base64-selfie-data',
  usingRandomAction: true,
  transactionId: 'txn-123',
  isStraight: true,
  // New parameters for version 1.3.0
  isActiveLiveness: true,
  autoCapture: true,
  isShowCameraFont: true,
  customActions: [SDKFaceDetectStatus.LEFT, SDKFaceDetectStatus.RIGHT],
  activeActionCount: 2
};

try {
  const result = await finosEKYC.startLiveness(livenessConfig);
  console.log('Liveness Result:', result.event, result.data);
} catch (error) {
  console.error('Liveness Error:', error);
}
```

### Face Comparison (Face Matching)

```typescript
import { finosEKYC, FaceServiceConfig } from '@finos_sdk/sdk-ekyc';

const faceConfig: FaceServiceConfig = {
  appKey: 'your-app-key',
  transactionId: 'txn-123',
  selfieImage: 'base64-selfie-data',
  idImage: 'base64-id-image-data'
};

try {
  const result = await finosEKYC.startFaceCompare(faceConfig);
  console.log('Face Compare Result:', result.event, result.data);
} catch (error) {
  console.error('Face Compare Error:', error);
}
```

### C06 Residence Verification

```typescript
import { finosEKYC, C06Config } from '@finos_sdk/sdk-ekyc';

const c06Config: C06Config = {
  appKey: 'your-app-key',
  sod: 'sample-sod-data',
  idCardNumber: '123456789',
  recentLocation: 'Ho Chi Minh City',
  transactionId: 'txn-123'
};

try {
  const result = await finosEKYC.checkC06(c06Config);
  console.log('C06 Result:', result.event, result.data);
} catch (error) {
  console.error('C06 Error:', error);
}
```

## 🎧 Event Listeners

```typescript
// NFC Events
finosEKYC.onNfcScanStart((data) => {
  console.log('NFC scan started:', data);
});

finosEKYC.onNfcScanSuccess((data) => {
  console.log('NFC scan success:', data);
});

finosEKYC.onNfcError((error) => {
  console.error('NFC error:', error);
});

// OCR Events
finosEKYC.onOCRSuccess((data) => {
  console.log('OCR success:', data);
});

finosEKYC.onOCRError((error) => {
  console.error('OCR error:', error);
});

// Liveness Events
finosEKYC.onLivenessSuccess((data) => {
  console.log('Liveness success:', data);
});

finosEKYC.onLivenessError((error) => {
  console.error('Liveness error:', error);
});

// Face Compare Events
finosEKYC.onFaceCompareSuccess((data) => {
  console.log('Face compare success:', data);
});

finosEKYC.onFaceCompareError((error) => {
  // error là EKYCError: { event, code, message } (native customCode/customMessage đã map vào code, message)
  console.error('Face compare error:', error.code, error.message);
});

// Khi catch bất kỳ API nào (NFC, OCR, Liveness, Face Compare, SMS OTP, eSign), dùng chung getEkycError:
// import { finosEKYC, getEkycError } from '@finos_sdk/sdk-ekyc';
// try { await finosEKYC.startFaceCompare(config); } catch (e) {
//   const err = getEkycError(e); // { event, code, message }
//   if (err.code === '109') { /* handle face mismatch */ }
// }

// C06 Events
finosEKYC.onC06Success((data) => {
  console.log('C06 success:', data);
});

finosEKYC.onC06Error((error) => {
  console.error('C06 error:', error);
});
```

## 🔄 Lifecycle Management

```typescript
import { AppState } from 'react-native';

// Handle app lifecycle
AppState.addEventListener('change', (nextAppState) => {
  if (nextAppState === 'active') {
    finosEKYC.onResume();
  } else if (nextAppState === 'background') {
    finosEKYC.onPause();
  }
});

// Handle new intent (Android)
finosEKYC.handleNewIntent();
```

## 🧹 Cleanup

```typescript
// Remove all event listeners
finosEKYC.removeAllListeners();
```

## 📋 Configuration Types

### NfcConfig
```typescript
interface NfcConfig {
  appKey: string;
  documentNumber: string;
  birthDate: string;
  expireDate: string;
  transactionId?: string;
  facePathStorage?: string;
}
```

### OcrConfig
```typescript
interface OcrConfig {
  appKey: string;
  idImagePath: string;
  expectedDocumentSide: string;
  transactionId: string;
}
```

### LivenessConfig
```typescript
interface LivenessConfig {
  appKey: string;
  selfieImage: string;
  usingRandomAction: boolean;
  transactionId: string;
  isStraight: boolean;
  switchFrontCamera?: boolean;
  // New parameters for version 1.3.0
  isActiveLiveness?: boolean; // Enable active liveness detection (default: false)
  autoCapture?: boolean;      // Enable auto capture (default: true)
  isShowCameraFont?: boolean; // Show camera font (default: true)
  customActions?: SDKFaceDetectStatus[]; // Custom actions array (LEFT, RIGHT, STRAIGHT)
  activeActionCount?: number; // Number of random actions (1-10), only used when customActions = null (default: 2)
}

enum SDKFaceDetectStatus {
  LEFT = "LEFT",
  RIGHT = "RIGHT",
  STRAIGHT = "STRAIGHT"
}
```

### FaceServiceConfig
```typescript
interface FaceServiceConfig {
  appKey: string;
  transactionId: string;
  selfieImage: string;
  idImage: string;
}
```

### C06Config
```typescript
interface C06Config {
  appKey: string;
  sod: string;
  idCardNumber: string;
  recentLocation: string;
  transactionId?: string;
}
```

## 🚨 Error Handling

The module provides comprehensive error handling with detailed error messages:

```typescript
try {
  await finosEKYC.startNfcScan(config);
} catch (error) {
  if (error.message.includes('SDK is not initialized')) {
    // Initialize SDK first
    await finosEKYC.initialize();
  } else if (error.message.includes('Required field')) {
    // Check configuration
    console.error('Configuration error:', error.message);
  } else {
    // Handle other errors
    console.error('Unexpected error:', error);
  }
}
```

## 📱 Platform Support

- **Android**: Full support for all features
- **iOS**: Compatibility layer (some features may be limited)

## 🔧 Requirements

- React Native 0.77.0+
- Android API Level 24+
- NFC-capable device for NFC features
- Camera permission for OCR and Liveness features

## 📄 License

MIT License - see LICENSE file for details.

## 🤝 Support

For support and questions:
- GitHub Issues: https://github.com/finosvn/finos.ekyc.sdk/issues
- Documentation: https://github.com/finosvn/finos.ekyc.sdk#readme

## 🔄 Version History

### v0.0.31
- ✅ Enhanced error handling and validation
- ✅ Improved SDK initialization
- ✅ Better TypeScript support
- ✅ Comprehensive event listeners
- ✅ Platform-specific optimizations
- ✅ Updated documentation and examples
