# Apacuana SDK para React Native.

## Descripción

**Apacuana SDK para React Native** es un wrapper completo construido alrededor de `apacuana-sdk-core`. Proporciona una serie de Hooks y un Proveedor de Contexto de React (`Context Provider`) para facilitar la integración de los servicios de Apacuana en aplicaciones móviles desarrolladas con React Native.

Este SDK abstrae la complejidad de la gestión del estado de inicialización y proporciona una API declarativa y fácil de usar para funciones clave como:

  * Generación de certificados digitales en el dispositivo.
  * Firma electrónica de documentos.
  * Consulta de estado de certificados y documentos.
  * Gestión de revocaciones.

## Requisitos

  * React Native: 0.68+ recomendado
  * Android: API Level 23+ (Android 6.0+)
  * iOS: 12.0+ (iPhone 6s y posteriores)
  * Configuración previa de la API de Apacuana con credenciales válidas.

## Instalación

```bash
# Usando npm
npm install apacuana-sdk-react-native

# Usando yarn
yarn add apacuana-sdk-react-native
```

## Uso Básico

Para utilizar el SDK, primero debes envolver el componente raíz de tu aplicación (o la parte de ella que necesite acceso al SDK) con el `ApacuanaProvider`. Luego, dentro de cualquier componente hijo, puedes usar el hook `useApacuana` para acceder a todas las funcionalidades.

### 1\. Configurar el `ApacuanaProvider`

En el archivo principal de tu aplicación (como `App.tsx`), importa y configura el proveedor.

```jsx
import React from 'react';
import { ApacuanaProvider } from 'apacuana-sdk-react-native';
import YourMainAppComponent from './YourMainAppComponent';

// Configuración inicial del SDK
const sdkConfig = {
  apiUrl: "https://api.apacuana.com", // O la URL de tu entorno
  secretKey: "YOUR_SECRET_KEY",
  apiKey: "YOUR_API_KEY",
  verificationId: "YOUR_VERIFICATION_ID",
  customerId: "YOUR_CUSTOMER_ID",
  integrationType: "ONBOARDING",
  encryptionKey: "YOUR_CUSTOM_STRONG_ENCRYPTION_KEY" // ¡Muy importante para producción!
};

const App = () => {
  return (
    <ApacuanaProvider {...sdkConfig}>
      <YourMainAppComponent />
    </ApacuanaProvider>
  );
};

export default App;
```

### 2\. Usar el hook `useApacuana` en un componente

Ahora, en cualquier componente dentro de `ApacuanaProvider`, puedes acceder al estado y las funciones del SDK. El siguiente ejemplo muestra un componente que espera a que el SDK esté listo y luego permite al usuario interactuar con él.

```jsx
import React from 'react';
import { SafeAreaView, View, Text, Button, ActivityIndicator, StyleSheet } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const MyApp = () => {
  const { state } = useApacuana();

  // Muestra un indicador de carga mientras el SDK se inicializa.
  if (state.status === 'initializing' || state.status === 'idle') {
    return (
      <View style={styles.container}>
        <ActivityIndicator size="large" />
        <Text>Inicializando SDK...</Text>
      </View>
    );
  }

  // Muestra un mensaje de error si la inicialización falla.
  if (state.status === 'error') {
    return (
      <View style={styles.container}>
        <Text style={styles.errorText}>Error al inicializar el SDK:</Text>
        <Text>{state.error?.message}</Text>
      </View>
    );
  }

  // Una vez listo, renderiza los componentes que usarán las funciones.
  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.title}>SDK Apacuana ¡Listo!</Text>
      {/* Aquí puedes añadir los componentes con ejemplos de cada función */}
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  title: { fontSize: 22, fontWeight: 'bold', marginBottom: 20 },
  errorText: { color: 'red', fontWeight: 'bold' }
});

export default MyApp;
```

## Configuración del `ApacuanaProvider`

| Propiedad | Tipo | Descripción |
| :--- | :--- | :--- |
| `apiUrl` | `string` | URL base de la API de Apacuana. |
| `apiKey` | `string` | Clave de API para autenticar las solicitudes. |
| `secretKey` | `string` | Clave secreta para autenticación y operaciones criptográficas. |
| `customerId` | `string` | Identificador único del cliente en la plataforma Apacuana. |
| `verificationId` | `string` | ID de verificación asociado al cliente. |
| `integrationType` | `'ONBOARDING'` | `'ONPREMISE'` | Define el flujo de integración a utilizar. |
| `encryptionKey` | `string` (Opcional) | Clave para encriptar/desencriptar datos sensibles. **Es altamente recomendado proveer una clave fuerte y única para producción.** |

## El Hook `useApacuana`

Este hook es el punto de entrada principal para interactuar con el SDK. Retorna un objeto con el estado actual del SDK y todas las funciones disponibles.

### Objeto de Estado (`state`)

  * `state.status`: Indica el estado actual (`'idle'`, `'initializing'`, `'ready'`, `'error'`).
  * `state.error`: Si `status` es `'error'`, este campo contendrá el objeto `Error` correspondiente.

-----

## Funciones Disponibles y Ejemplos Prácticos

A continuación se detallan todas las funciones expuestas por el hook `useApacuana` con un ejemplo práctico para cada una.

### `getConfig()`

Obtiene la configuración con la que fue inicializado el `apacuana-sdk-core`.

  * **Parámetros:** Ninguno.
  * **Retorna:** `object` - El objeto de configuración actual.

#### Ejemplo de Uso

```jsx
import React from 'react';
import { Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const ConfigViewer = () => {
  const { getConfig } = useApacuana();

  const handleShowConfig = () => {
    const config = getConfig();
    // Usamos JSON.stringify para mostrar el objeto de forma legible.
    Alert.alert('Configuración Actual del SDK', JSON.stringify(config, null, 2));
  };

  return <Button title="Mostrar Configuración" onPress={handleShowConfig} />;
};
```

### `getCustomer()`

Obtiene la información completa del cliente asociado a la configuración actual del SDK.

  * **Parámetros:** Ninguno.
  * **Retorna:** `Promise<GetCustomerResponse>` - Una promesa que se resuelve con un objeto que contiene:
      * `data` (`object`):
          * `token` (`string`): ID de sesión para autenticación.
          * `userData` (`object`): Datos detallados del usuario.
      * `success` (`boolean`): Indicador de éxito de la operación.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const CustomerInfo = () => {
  const { getCustomer } = useApacuana();
  const [customerName, setCustomerName] = useState('');

  const handleGetCustomer = async () => {
    try {
      const response = await getCustomer();
      if (response.success) {
        setCustomerName(response.userData.name.value);
        Alert.alert('Éxito', `Cliente obtenido: ${response.data.userData.name.value}`);
      } else {
        Alert.alert('Error', 'No se pudo obtener la información del cliente.');
      }
    } catch (error) {
      Alert.alert('Error de Red', error.message);
    }
  };

  return (
    <View>
      <Button title="Obtener Cliente" onPress={handleGetCustomer} />
      {customerName ? <Text>Nombre del cliente: {customerName}</Text> : null}
    </View>
  );
};
```

### `generateCert(pin)`

Gestiona el ciclo de vida completo para la creación de un certificado digital en el dispositivo. Este proceso incluye:

  * **Parámetros:**
      * `pin` (`string`): Un PIN alfanumérico definido por el usuario que se asociará al certificado para autorizar futuras firmas.
      * `enableSaveWithBiometrics` (`boolean`): Habilitar acceder al certificado mediante biometria.
  * **Retorna:** `Promise<GenerateCertResponse>` - Una promesa que se resuelve con la respuesta de la API, que contiene:
      * `data` (`object`):
        * `cert` (`string`): El certificado generado en base64.
        * `certifiedid` (`string`): Serial del certificado emitido.
      * `success` (`boolean`): Indicador de éxito de la operación.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, TextInput, Button, Alert, StyleSheet } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const CertificateGenerator = () => {
  const { generateCertificate } = useApacuana();
  const [pin, setPin] = useState('');
  const [loading, setLoading] = useState(false);

  const handleGenerate = async () => {
    if (pin.length < 4) {
      Alert.alert('Error', 'El PIN debe tener al menos 4 caracteres.');
      return;
    }
    setLoading(true);
    try {
      const response = await generateCertificate(pin);
      if (response.success) {
        Alert.alert('Éxito', '¡Certificado generado y almacenado de forma segura!');
      } else {
         Alert.alert('Fallo', response.message || 'No se pudo generar el certificado.');
      }
    } catch (error) {
      Alert.alert('Error', error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <View>
      <TextInput
        style={styles.input}
        placeholder="Crea un PIN de 4-6 dígitos"
        keyboardType="number-pad"
        secureTextEntry
        maxLength={6}
        value={pin}
        onChangeText={setPin}
      />
      <Button
        title={loading ? 'Generando...' : 'Generar Certificado'}
        onPress={handleGenerate}
        disabled={loading}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    padding: 10,
    borderRadius: 5,
    marginBottom: 10,
    textAlign: 'center',
  },
});
```

### `getCertStatus()`

Obtiene el estado actual del certificado del usuario.

  * **Parámetros:** Ninguno.
  * **Retorna:** `Promise<GetCertStatusResponse>` - Una promesa que se resuelve con un objeto que contiene:
      * `data` (`object`):
        * `status` (`string`): El estado del certificado.
      * `success` (`boolean`): Indicador de éxito de la operación.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const CertificateStatus = () => {
  const { getCertStatus } = useApacuana();
  const [status, setStatus] = useState('');

  const handleCheckStatus = async () => {
    try {
      const response = await getCertStatus();
      if (response.success) {
        setStatus(response.status);
        Alert.alert('Estado del Certificado', `El estado actual es: ${response.data.status}`);
      }
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return (
    <View>
      <Button title="Verificar Estado del Certificado" onPress={handleCheckStatus} />
      {status ? <Text>Estado: {status}</Text> : null}
    </View>
  );
};
```

### `getDocsByCustomer(data)`

Obtiene una lista paginada de los documentos del usuario.

  * **Parámetros:**
      * `data` (`GetDocsParams`): Un objeto con los siguientes campos:
          * `page` (`number`): Número de página a solicitar.
          * `size` (`number`): Cantidad de resultados por página.
          * `status` (`number`, opcional): Filtra por estado (`-1`: Rechazado, `0`: Pendiente, `1`: Firmado, `2`: En proceso).
  * **Retorna:** `Promise<GetDocsResponse>` - Una promesa que se resuelve con un objeto que contiene:
      * `data` (`object`):
        * `totalRecords` (`number`): El número total de documentos que coinciden con el filtro.
        * `records` (`Array<object>`): Un array de objetos, donde cada objeto es un documento.
      * `success` (`boolean`): Indicador de éxito de la operación.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Text, Button, FlatList, StyleSheet } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const DocumentList = () => {
  const { getDocsByCustomer } = useApacuana();
  const [documents, setDocuments] = useState([]);

  const handleFetchPendingDocs = async () => {
    try {
      // Pedimos la primera página de documentos pendientes (status: 0)
      const response = await getDocsByCustomer({ page: 1, size: 10, status: 0 });
      setDocuments(response.data.records);
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return (
    <View>
      <Button title="Cargar Documentos Pendientes" onPress={handleFetchPendingDocs} />
      <FlatList
        data={documents}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.item}>
            <Text>{item.name}</Text>
            <Text>Estado: {item.status_name}</Text>
          </View>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  item: { padding: 10, borderBottomWidth: 1, borderBottomColor: '#ccc' },
});
```

### `getRevocationReasons()`

Obtiene la lista de motivos de revocación disponibles que se pueden usar en la función `requestRevocation`.

  * **Parámetros:** Ninguno.
  * **Retorna:** `Promise<RevocationReasonsResponse>` - Una promesa que se resuelve con un objeto que contiene:
      * `data` (`object`):
        * `reasons` (`Array<object>`): Un array de objetos, donde cada uno representa un motivo de revocación con `code` y `description`.
      * `success` (`boolean`): Indicador de éxito de la operación.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const RevocationReasons = () => {
  const { getRevocationReasons } = useApacuana();

  const handleFetchReasons = async () => {
    try {
      const response = await getRevocationReasons();
      // Mapeamos las razones a un string para mostrarlas en la alerta.
      const reasonsList = response.data.reasons.map(r => `${r.code}: ${r.description}`).join('\n');
      Alert.alert('Motivos de Revocación', reasonsList);
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return <Button title="Ver Motivos de Revocación" onPress={handleFetchReasons} />;
};
```

### `requestRevocation(reasonCode)`

Inicia una solicitud para revocar el certificado digital del usuario.

  * **Parámetros:**
      * `reasonCode` (`number`): El código numérico que identifica la razón de la revocación. Se obtiene de `getRevocationReasons()`.
  * **Retorna:** `Promise<RevocationResponse>` - Una promesa que se resuelve con un objeto que contiene:
      * `data` (`object`):
        * `revocationStatus` (`string`): El estado de la solicitud (ej. `"pending"`).
        * `requestId` (`string` | `number`): El ID de la solicitud de revocación.

#### Ejemplo de Uso

```jsx
import React from 'react';
import { Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const RevokeCertificate = () => {
  const { requestRevocation } = useApacuana();

  const handleRevoke = () => {
    // El código de motivo normalmente vendría de una selección del usuario.
    const reasonCode = 1; // Ejemplo: 1 = "Compromiso de clave"

    Alert.alert(
      'Confirmar Revocación',
      '¿Estás seguro de que deseas revocar tu certificado? Esta acción no se puede deshacer.',
      [
        { text: 'Cancelar', style: 'cancel' },
        {
          text: 'Sí, Revocar',
          onPress: async () => {
            try {
              await requestRevocation(reasonCode);
              Alert.alert('Éxito', 'La solicitud de revocación ha sido enviada.');
            } catch (error) {
              Alert.alert('Error', error.message);
            }
          },
          style: 'destructive',
        },
      ]
    );
  };

  return <Button title="Revocar Certificado" onPress={handleRevoke} color="red" />;
};
```



### `signDocument(signature)`

Orquesta el proceso de firma de un documento.

  * **Parámetros:**
      * `signature` (`SignDocumentData`): Un objeto que contiene la información de la firma a realizar. Su estructura es:
          * `signature` (`object`):
              * `id` (`string`): Identificador único del proceso de firma.
              * `positions` (`Array<object>`): Un array que define la ubicación y estado de las firmas en el documento.
  * **Retorna:** `Promise<object>` - Una promesa que se resuelve con la respuesta final de la API tras completar el proceso de firma.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { Button, Alert, Text } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

// En una aplicación real, estos datos vendrían de la API (ej. al seleccionar un doc de la lista).
const MOCK_SIGNATURE_REQUEST = {
  signature: {
    id: 'unique-signature-id-from-api-123',
    positions: [{ page: 1, x: 0.5, y: 0.2 }],
  },
};

const DocumentSigner = () => {
  const { signDocument } = useApacuana();
  const [loading, setLoading] = useState(false);

  const handleSign = async () => {
    setLoading(true);
    try {
      await signDocument(MOCK_SIGNATURE_REQUEST);
      Alert.alert('Éxito', 'El documento ha sido firmado correctamente.');
    } catch (error) {
      Alert.alert('Error de Firma', error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <View>
      <Text>Firmar Documento: "Contrato de Servicios.pdf"</Text>
      <Button
        title={loading ? 'Firmando...' : 'Firmar Documento'}
        onPress={handleSign}
        disabled={loading}
      />
    </View>
  );
};
```

### `isCertificateInDevice()`

Verifica si el certificado digital del usuario ya está almacenado en el dispositivo.

  * **Parámetros:** Ninguno.
  * **Retorna:** `Promise<boolean>` - Una promesa que se resuelve con `true` si el certificado existe en el dispositivo, o `false` si no existe.

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const CertCheck = () => {
  const { isCertificateInDevice } = useApacuana();
  const [exists, setExists] = useState(null);

  const handleCheck = async () => {
    try {
      const result = await isCertificateInDevice();
      setExists(result);
      Alert.alert('Certificado', result ? 'Existe en el dispositivo' : 'No existe en el dispositivo');
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return (
    <View>
      <Button title="Verificar Certificado en Dispositivo" onPress={handleCheck} />
      {exists !== null && (
        <Text>
          {exists ? 'Certificado presente' : 'Certificado no encontrado'}
        </Text>
      )}
    </View>
  );
};
```

### `uploadSignatureVariant(data)`

Sube una variante de firma (imagen) para un firmante específico. Esta imagen se utilizará como la representación gráfica de la firma en los documentos.

- **Parámetros:**
  - `data` (`{ file: File, signerId: string }`): Objeto con la imagen y el identificador del firmante.
- **Retorna:** `Promise<object>`

#### Ejemplo de Uso
```jsx
const { uploadSignatureVariant } = useApacuana();
const handleUpload = async (file, signerId) => {
  const result = await uploadSignatureVariant({ file, signerId });
  if (result.success) {
    Alert.alert('Éxito', 'Imagen de firma subida correctamente.');
  }
};
```

### `getSignatureVariant()`

Obtiene la variante de firma (imagen) de un firmante.

- **Parámetros:** Ninguno.
- **Retorna:** `Promise<object>`

#### Ejemplo de Uso
```jsx
const { getSignatureVariant } = useApacuana();
const handleGet = async () => {
  const result = await getSignatureVariant();
  if (result.success) {
    // Mostrar imagen o manejar resultado
  }
};
```

### `deleteSignatureVariant()`

Elimina la variante de firma (imagen) de un firmante.

- **Parámetros:** Ninguno.
- **Retorna:** `Promise<object>`

#### Ejemplo de Uso
```jsx
const { deleteSignatureVariant } = useApacuana();
const handleDelete = async () => {
  const result = await deleteSignatureVariant();
  if (result.success) {
    Alert.alert('Éxito', 'Imagen de firma eliminada.');
  }
};
```

### `getCertTypes()`

Obtiene los tipos de certificados disponibles para el cliente.

- **Parámetros:** Ninguno.
- **Retorna:** `Promise<GetCertTypesResponse>`

#### Ejemplo de Uso
```jsx
const { getCertTypes } = useApacuana();
const handleGetTypes = async () => {
  const result = await getCertTypes();
  if (result.success) {
    // Mostrar tipos de certificados
  }
};
```

### `getRequerimentsByTypeUser(data)`

Obtiene los requisitos para un tipo de usuario específico.

- **Parámetros:**
  - `data` (`{ type: number }`): Objeto con el tipo de usuario.
- **Retorna:** `Promise<GetRequirementsResponse>`

#### Ejemplo de Uso
```jsx
const { getRequerimentsByTypeUser } = useApacuana();
const handleGetReqs = async () => {
  const result = await getRequerimentsByTypeUser({ type: 1 });
  if (result.success) {
    // Mostrar requisitos
  }
};
```

### `addSigner(signerData)`

Agrega un firmante a un documento.

- **Parámetros:**
  - `signerData` (`OnboardingSignerData | object`): Datos del firmante a agregar.
- **Retorna:** `Promise<object>`

#### Ejemplo de Uso
```jsx
const { addSigner } = useApacuana();
const handleAddSigner = async (signerData) => {
  const result = await addSigner(signerData);
  if (result.success) {
    Alert.alert('Éxito', 'Firmante agregado correctamente.');
  }
};
```

### `startLivenessCheck()`

Inicia el flujo de detección de vida (liveness) facial y abre el modal correspondiente. Genera un `sessionId` único y muestra el modal con la UI de liveness.

- **Parámetros:** Ninguno.
- **Retorna:** `string` (sessionId generado para la sesión de liveness)

#### Ejemplo de Uso
```jsx
const { startLivenessCheck } = useApacuana();
const handleLiveness = () => {
  const sessionId = startLivenessCheck();
  // Puedes usar el sessionId para seguimiento o lógica adicional
};
```

---

### `validateFaceLiveness({ sessionId })`

Valida el resultado de una sesión de prueba de vida.

* **Parámetros:**
  * `sessionId` (String, **obligatorio**): El ID de la sesión de prueba de vida que se va a validar.
* **Retorna:** `Promise<boolean>` - Validación de vida

#### Ejemplo de Uso

```jsx
import React, { useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { useApacuana } from 'apacuana-sdk-react-native';

const CertCheck = () => {
  const { validateFaceLiveness } = useApacuana();
  const [exists, setExists] = useState(null);

  const handleCheck = async () => {
    try {
      const result = await validateFaceLiveness();
      setExists(result);
      Alert.alert('Certificado', result ? 'Se ha validado' : 'No se ha validado');
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return (
    <View>
      <Button title="Verificar Certificado en Dispositivo" onPress={handleCheck} />
      {exists !== null && (
        <Text>
          {exists ? 'Certificado presente' : 'Certificado no encontrado'}
        </Text>
      )}
    </View>
  );
};
```

**Ejemplo:**

```javascript
try {
  const response = await apacuana.validateFaceLiveness({
    sessionId: "your-session-id",
  });
  console.log("Resultado de la validación:", response.data);
} catch (error) {
  console.error("Error al validar la sesión de prueba de vida:", error.message);
}
```

### `createApacuanaUser(userData)`

Crea un nuevo usuario en la plataforma de Apacuana. Este método puede llamarse varias veces para ir completando la información de forma parcial; no es necesario enviar todos los datos en una sola llamada. Sin embargo, en cada actualización es obligatorio enviar el número de documento de identidad (`kinddoc+doc`). El registro inicial debe incluir el documento de identidad.

Los documentos requeridos para el usuario se obtienen previamente usando el método `getRequerimentsByTypeUser` y deben enviarse bajo la estructura `{ file-ID: File }`, donde cada clave corresponde al identificador del documento y el valor es el archivo correspondiente.

El objeto completo de usuario que puede acompañar la solicitud es:

```js
{
  email: "usuario@correo.com",
  typeuser: 1,
  name: "Nombre",
  lastname: "Apellido",
  kinddoc: "V",
  doc: 12345678,
  birthdate: "1990-01-01",
  kindrif: "V",
  gender: "M",
  rif: 12345678,
  phone: 4121234567,
  kindphone: "0424",
  state: "Estado",
  municipality: "Municipio",
  parish: "Parroquia",
  postalcode: "1010",
  address: "Dirección",
  fiscaladdress: "Dirección fiscal",
  fiscalkindphone: "0424",
  fiscalphone: 4121234567,
  occupation: "Ocupación",
  degree: "Título",
  university: "Universidad",
  graduationyear: "2010",
  collegiatenumber: "12345",
  collegiateyear: "2011",
  companyname: "Empresa",
  companykindrif: "J",
  companyrif: "J12345678",
  companystate: "Estado",
  companymunicipality: "Municipio",
  companyparish: "Parroquia",
  companyaddress: "Dirección empresa",
  companykindphone: "0212",
  companyphone: "2121234567",
  companypostalcode: "1010",
  companywebpage: "https://empresa.com",
  companycommercialregister: "Registro comercial",
  companyregisterdate: "2015-01-01",
  companyregisternumber: "123456",
  companyconstitutiondate: "2015-01-01",
  companypublishdate: "2015-01-01",
  companyconstitutiondecree: "Decreto",
  companynumberdecree: "123",
  positionprivate: "Cargo privado",
  departmentprivate: "Departamento privado",
  authorizedprivate: "Autorizado privado",
  functionsprivate: "Funciones privado",
  publishprivate: "2015-01-01",
  issuedateprivate: "2015-01-01",
  kindphoneprivate: "0424",
  phoneprivate: 4121234567,
  positionpublic: "Cargo público",
  departmentpublic: "Departamento público",
  authorizedpublic: "Autorizado público",
  functionspublic: "Funciones público",
  publishpublic: "2015-01-01",
  issuedatepublic: "2015-01-01",
  kindphonepublic: "0424",
  phonepublic: 4121234567,
  companyid: "uuid-empresa"
}
```

**Ejemplo:**

```javascript

const { createApacuanaUser } = useApacuana();
const handleLiveness = () => {
  try {
  const userData = {
    usr: "usuario@correo.com",
    pwd: "contraseñaSegura123",
    kinddoc: "V",
    doc: "12345678",
    // ...otros campos opcionales
    files: {
      "file-1": file1, // Instancia de File
      "file-2": file2,
      // ...otros documentos según los requerimientos
    },
  };
  const response = await createApacuanaUser(userData);
  console.log("Usuario creado:", response.data);
} catch (error) {
  console.error("Error al crear el usuario:", error.message);
}
};


```

## Cambios en funciones existentes

- `getCertStatus(data?)`: Ahora acepta un parámetro opcional `data` para compatibilidad futura.
- `signDocument(signature, pin, enableBiometric)`: Ahora requiere los parámetros `pin` y `enableBiometric` para soportar flujos biométricos y de PIN.
- `generateCertificate(pin, enableSaveWithBiometrics)`: Ahora requiere el parámetro `enableSaveWithBiometrics` para soportar almacenamiento seguro con biometría.

## Manejo de Errores

  * **Errores de Inicialización:** Si ocurre un error durante la configuración inicial, el `state.status` cambiará a `'error'` y el objeto `Error` estará disponible en `state.error`.
  * **Errores de Operación:** Si una función es llamada antes de que el SDK esté listo (`state.status !== 'ready'`), lanzará un error.
  * **Errores de API:** Las funciones asíncronas pueden lanzar errores. Es fundamental envolver las llamadas en bloques `try...catch` para manejar adecuadamente respuestas de error.

## Licencia

Este SDK está licenciado bajo términos propietarios.
