npm package: @lina-openx/react-native-lina-pay-sdk
Description: Create Open Finance Payments EasilyCreate Open Finance Payments
Author: Lina OpenX
Latest version: 1.0.1

# react-native-lina-pay-sdk

SDK React Native para integração com Lina Open Finance - Facilitando a criação de pagamentos através do Open Finance.

## 📖 Documentação

- **[Guia do Usuário Completo](./docs/USER_GUIDE.md)** - Documentação detalhada para implementação
- **[Diagramas de Fluxo](./docs/FLOW_DIAGRAM.md)** - Diagramas visuais do fluxo de pagamento

## 🚀 Instalação

```sh
npm install react-native-lina-pay-sdk
```

ou

```sh
yarn add react-native-lina-pay-sdk
```

## 📋 Requisitos

- React Native >= 0.83.0
- Node >= 20

## 🔧 Uso

### Configuração Inicial

Por padrão, o SDK está configurado para usar o ambiente de homologação (HML). Para produção ou outros ambientes, configure as URLs base:

```typescript
import LinaPaySdk from 'react-native-lina-pay-sdk';

// Configurar para produção
LinaPaySdk.configure({
  iamBaseUrl: 'https://iam.prod.linaob.com.br',
  apiBaseUrl: 'https://embedded-payment-manager.prod.linaob.com.br'
});
```

### Listagem de Participantes

Obtenha a lista de instituições financeiras participantes do Open Finance:

```typescript
import { getParticipants, type Participant, LinaPayError } from 'react-native-lina-pay-sdk';

async function fetchParticipants() {
  try {
    const participants = await getParticipants({
      subtenantId: 'seu-subtenant-id',
      subtenantSecret: 'seu-subtenant-secret'
    });

    console.log(`${participants.length} participantes encontrados`);
    
    participants.forEach(participant => {
      console.log(`${participant.customerFriendlyName} - ${participant.registrationNumber}`);
    });
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro Lina Pay:', error.message, error.statusCode);
    } else {
      console.error('Erro desconhecido:', error);
    }
  }
}
```

### Criação de Consentimento de Pagamento

Crie um consentimento para iniciar um pagamento via Open Finance:

```typescript
import { createConsent, type CreateConsentRequest, LinaPayError } from 'react-native-lina-pay-sdk';

async function createPaymentConsent() {
  try {
    const payload: CreateConsentRequest = {
      organisationId: 'c8f0bf49-4744-4933-8960-7add6e590841',
      authorisationServerId: 'c8f0bf49-4744-4933-8960-7add6e590841',
      payment: {
        redirectUri: 'http://example.com/redirect',
        value: 1500.50,
        creditor: {
          name: 'John Doe',
          personType: 'PESSOA_NATURAL',
          cpfCnpj: '12345678901234',
          accountNumber: '1234567890',
          accountIssuer: '0001',
          accountPixKey: 'email@example.com',
          accountIspb: '12345678',
          accountType: 'CACC'
        }
      },
      platform: 'APP'
    };

    const consent = await createConsent(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      payload
    );

    console.log('Consentimento criado:', consent.consentId);
    console.log('Status:', consent.status);
    console.log('URL de redirecionamento:', consent.redirectUrl);
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao criar consentimento:', error.message);
    }
  }
}
```

### Criação de Pagamento

Após o usuário autorizar o consentimento, crie o pagamento usando os parâmetros retornados:

```typescript
import { createPayment, type CreatePaymentRequest, LinaPayError } from 'react-native-lina-pay-sdk';

async function processPayment() {
  try {
    // state, code e idToken são retornados após autorização do consentimento
    const payment = await createPayment(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      {
        state: 'rumUP',
        code: '1RDYVFQnPn721',
        idToken: 'eyJhbGciOiJQUz',
        tenantId: 'tenantId'
      }
    );

    console.log('Pagamento criado:', payment.id);
    console.log('Status:', payment.status);
    console.log('Valor:', payment.value);
    console.log('Itens de pagamento:', payment.payments.length);
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao criar pagamento:', error.message);
    }
  }
}
```

### Enrollment (Cadastro de Dispositivo)

O **Enrollment** permite cadastrar um dispositivo do usuário usando autenticação FIDO2/Passkeys. Uma vez cadastrado, o usuário pode realizar pagamentos sem precisar redirecionar para o banco a cada transação.

#### Criar Enrollment

```typescript
import { createEnrollment, type CreateEnrollmentRequest, LinaPayError } from 'react-native-lina-pay-sdk';
import { Linking } from 'react-native';

async function createDeviceEnrollment() {
  try {
    const enrollment = await createEnrollment(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      {
        organisationId: 'org-uuid',
        authorisationServerId: 'auth-uuid',
        enrollment: {
          document: '12345678901', // CPF do usuário
          deviceName: 'iPhone do João',
          debtor: {
            accountNumber: '123456',
            accountIssuer: '0001',
            accountIspb: '12345678',
            accountType: 'CACC'
          }
        },
        redirectUri: 'https://seu-app.com/enrollment-callback'
      }
    );

    console.log('Enrollment criado:', enrollment.id);
    
    // Redirecionar usuário para autorização
    if (enrollment.redirectUrl) {
      Linking.openURL(enrollment.redirectUrl);
    }
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao criar enrollment:', error.message);
    }
  }
}
```

#### Registrar Dispositivo (após callback)

Após o usuário autorizar no banco e receber o callback, registre o dispositivo:

```typescript
import { registerDevice, type RegisterDeviceRequest, LinaPayError } from 'react-native-lina-pay-sdk';
import { Platform } from 'react-native';

async function registerDeviceAfterCallback(state: string, code: string, idToken: string) {
  try {
    const platform = Platform.OS === 'ios' ? 'IOS' : Platform.OS === 'android' ? 'ANDROID' : 'WEB';
    
    const enrollment = await registerDevice(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      {
        state,
        code,
        idToken,
        tenantId: 'seu-subtenant-id',
        platform
      }
    );

    console.log('Dispositivo registrado:', enrollment.enrollmentId);
    console.log('Status:', enrollment.status); // Deve ser 'AUTHORISED'
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao registrar dispositivo:', error.message);
    }
  }
}
```

#### Listar Enrollments

```typescript
import { getEnrollmentList, LinaPayError } from 'react-native-lina-pay-sdk';

async function listUserEnrollments() {
  try {
    const enrollmentList = await getEnrollmentList(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      '12345678901' // CPF do usuário
    );

    console.log('Total de enrollments:', enrollmentList.enrollments.length);
    enrollmentList.enrollments.forEach(enrollment => {
      console.log(`- ${enrollment.enrollmentId}: ${enrollment.status}`);
    });
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao listar enrollments:', error.message);
    }
  }
}
```

#### Revogar Enrollment

```typescript
import { revokeEnrollment, LinaPayError } from 'react-native-lina-pay-sdk';

async function removeEnrollment() {
  try {
    await revokeEnrollment(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      'enrollment-id-aqui'
    );

    console.log('Enrollment revogado com sucesso');
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao revogar enrollment:', error.message);
    }
  }
}
```

### Pagamento com Enrollment

Após ter um enrollment ativo, você pode realizar pagamentos sem redirecionar o usuário ao banco. O pagamento é autorizado usando autenticação biométrica FIDO2/Passkeys:

```typescript
import { createPaymentWithEnrollment, type PaymentWithEnrollmentRequest, LinaPayError } from 'react-native-lina-pay-sdk';
import { Platform } from 'react-native';

async function payWithEnrollment() {
  try {
    const platform = Platform.OS === 'ios' ? 'IOS' : Platform.OS === 'android' ? 'ANDROID' : 'WEB';
    
    const payment = await createPaymentWithEnrollment(
      {
        subtenantId: 'seu-subtenant-id',
        subtenantSecret: 'seu-subtenant-secret'
      },
      {
        enrollmentId: 'enrollment-id-ativo',
        organisationId: 'org-uuid',
        authorisationServerId: 'auth-uuid',
        payment: {
          value: 1500.50,
          details: 'Pagamento de serviço',
          externalId: 'payment-123',
          redirectUri: 'https://seu-app.com/payment-success',
          cpfCnpj: '12345678901',
          creditor: {
            name: 'Empresa Beneficiária',
            personType: 'PESSOA_JURIDICA',
            cpfCnpj: '12345678000190',
            accountNumber: '123456',
            accountIssuer: '0001',
            accountPixKey: 'empresa@email.com',
            accountIspb: '12345678',
            accountType: 'CACC'
          },
          txId: []
        },
        fidoSignOptions: {
          rp: 'app.linaopenx.com.br',
          platform
        }
      }
    );

    console.log('Pagamento processado:', payment.id);
    console.log('Consent ID:', payment.consentId);
    // O usuário será solicitado a autorizar com biometria automaticamente
  } catch (error) {
    if (error instanceof LinaPayError) {
      console.error('Erro ao processar pagamento:', error.message);
    }
  }
}
```

**Vantagens do Pagamento com Enrollment:**
- ⚡ Mais rápido: sem redirecionamento ao banco
- 🔒 Seguro: autenticação biométrica obrigatória
- 📱 Melhor UX: tudo acontece dentro do app
- 🔄 Ideal para pagamentos recorrentes

### Exemplo Completo com React

```typescript
import React, { useState } from 'react';
import { View, Button, FlatList, Text } from 'react-native';
import { getParticipants, type Participant } from 'react-native-lina-pay-sdk';

export default function ParticipantsList() {
  const [participants, setParticipants] = useState<Participant[]>([]);
  const [loading, setLoading] = useState(false);

  const loadParticipants = async () => {
    setLoading(true);
    try {
      const result = await getParticipants({
        subtenantId: process.env.SUBTENANT_ID!,
        subtenantSecret: process.env.SUBTENANT_SECRET!
      });
      setParticipants(result);
    } catch (error) {
      console.error(error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <View>
      <Button 
        title="Carregar Participantes" 
        onPress={loadParticipants}
        disabled={loading}
      />
      <FlatList
        data={participants}
        keyExtractor={(item) => `${item.organisationId}-${item.authorisationServerId}`}
        renderItem={({ item }) => (
          <View>
            <Text>{item.customerFriendlyName}</Text>
            <Text>{item.legalEntityName}</Text>
            <Text>CNPJ: {item.registrationNumber}</Text>
          </View>
        )}
      />
    </View>
  );
}
```

## 📚 API Reference

### `createConsent(credentials, payload)`

Cria um consentimento de pagamento via Open Finance.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `payload` (objeto, obrigatório):
  - `organisationId` (string, obrigatório): UUID da organização participante
  - `authorisationServerId` (string, obrigatório): UUID do servidor de autorização
  - `payment` (objeto, obrigatório):
    - `redirectUri` (string, obrigatório): URL de redirecionamento após autorização
    - `value` (number, obrigatório): Valor do pagamento (deve ser positivo)
    - `creditor` (objeto, obrigatório):
      - `name` (string, obrigatório): Nome do beneficiário
      - `personType` (string, obrigatório): Tipo de pessoa ('PESSOA_NATURAL' | 'PESSOA_JURIDICA')
      - `cpfCnpj` (string, obrigatório): CPF (11 dígitos) ou CNPJ (14 dígitos)
      - `accountNumber` (string, obrigatório): Número da conta
      - `accountIssuer` (string, obrigatório): Agência
      - `accountPixKey` (string, obrigatório): Chave PIX
      - `accountIspb` (string, obrigatório): Código ISPB
      - `accountType` (string, obrigatório): Tipo de conta ('CACC' | 'SLRY' | 'SVGS' | 'TRAN')
    - `details` (string, opcional): Detalhes do pagamento
    - `externalId` (string, opcional): ID externo
    - `cpfCnpj` (string, opcional): CPF/CNPJ do pagador
    - `debitor` (objeto, opcional): Informações do pagador
    - `schedule` (objeto, opcional): Agendamento do pagamento
    - `txId` (string | string[], opcional): ID(s) da transação
  - `redirectUri` (string, opcional): URL de redirecionamento alternativa
  - `platform` (string, opcional): Plataforma ('APP' | 'WEB')

**Retorna:** `Promise<CreateConsentResponse>`

**Estrutura do CreateConsentResponse:**
```typescript
interface CreateConsentResponse {
  consentId: string;    // URN do consentimento criado
  redirectUrl: string;  // URL para autorização do usuário
  id: string;           // UUID interno do consentimento
}
```

**Exemplo de resposta:**
```json
{
  "consentId": "urn:nubank:796a30aa-0a3c-3f60-acb1-d6097864267e",
  "redirectUrl": "https://nuapp.nubank.com.br/open-banking/authorize?request_uri=...",
  "id": "60735a9c-0036-4b1a-9247-2fd8ef651c7b"
}
```

**Exemplo com Agendamento:**
```typescript
const consentWithSchedule = await createConsent(credentials, {
  organisationId: 'org-uuid',
  authorisationServerId: 'auth-uuid',
  payment: {
    redirectUri: 'http://example.com/redirect',
    value: 1500.50,
    creditor: { /* ... */ },
    schedule: {
      single: {
        date: '2024-09-01'  // Pagamento único em data específica
      }
    }
  }
});
```

**Tipos de Agendamento Disponíveis:**
- `single`: Pagamento único em data específica
- `daily`: Pagamentos diários recorrentes
- `weekly`: Pagamentos semanais recorrentes
- `monthly`: Pagamentos mensais recorrentes
- `custom`: Datas customizadas

---

### `createPayment(credentials, payload)`

Cria um pagamento após validação do consentimento via Open Finance.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `payload` (objeto, obrigatório):
  - `state` (string, obrigatório): Estado retornado após autorização do consentimento
  - `code` (string, obrigatório): Código retornado após autorização do consentimento
  - `idToken` (string, obrigatório): Token ID retornado após autorização do consentimento
  - `tenantId` (string, obrigatório): ID do tenant

**Retorna:** `Promise<CreatePaymentResponse>`

**Estrutura do CreatePaymentResponse:**
```typescript
interface CreatePaymentResponse {
  id: string;                    // UUID do pagamento
  type: PaymentType;             // Tipo do pagamento (ex: 'NOW')
  createDateTime: string;         // Data/hora de criação (ISO 8601)
  externalId?: string;           // ID externo
  externalComment?: string;       // Comentário externo
  lastChangedDateTime: string;   // Data/hora da última alteração (ISO 8601)
  status: PaymentStatus;        // Status do pagamento (ex: 'CONSUMIDO', 'PAGO')
  tenantId: string;              // ID do tenant
  cpfCnpj: string;               // CPF/CNPJ do pagador
  redirectUri: string;           // URL de redirecionamento
  value: string;                 // Valor do pagamento (como string)
  consentId: string;             // URN do consentimento associado
  creditor: PaymentCreditor;     // Informações do beneficiário
  debitor?: PaymentDebitor;      // Informações do pagador
  payments: PaymentItem[];       // Array de itens de pagamento
}

interface PaymentItem {
  endToEndId: string;            // ID end-to-end da transação
  id: string;                    // UUID do item de pagamento
  dueDate: string;               // Data de vencimento (ISO 8601)
  externalComment?: string;      // Comentário externo
  txId: string | null;            // ID da transação (pode ser null)
  status: PaymentItemStatus;    // Status do item (ex: 'PAGO')
  externalPaymentId: string;     // ID externo do pagamento
}
```

**Exemplo de uso:**
```typescript
import { createPayment, type CreatePaymentRequest } from 'react-native-lina-pay-sdk';

const payment = await createPayment(
  {
    subtenantId: 'your-subtenant-id',
    subtenantSecret: 'your-subtenant-secret'
  },
  {
    state: 'rumUP',
    code: '1RDYVFQnPn721',
    idToken: 'eyJhbGciOiJQUz',
    tenantId: 'tenantId'
  }
);

console.log('Payment ID:', payment.id);
console.log('Status:', payment.status);
console.log('Value:', payment.value);
console.log('Payments count:', payment.payments.length);
```

**Observações:**
- Este método deve ser chamado após o usuário autorizar o consentimento
- Os parâmetros `state`, `code` e `idToken` são retornados após a autorização do consentimento
- O valor do pagamento é retornado como string pela API
- O array `payments` contém os detalhes de cada pagamento individual processado

---

### `getParticipants(credentials)`

Obtém a lista de participantes registrados no Open Finance.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina

**Retorna:** `Promise<Participant[]>`

**Estrutura do Participant:**
```typescript
interface Participant {
  organisationId: string;           // UUID da organização
  organisationName: string;          // Nome da organização
  legalEntityName: string;           // Razão social
  registrationNumber: string;        // CNPJ
  authorisationServerId: string;     // UUID do servidor de autorização
  customerFriendlyName: string;      // Nome amigável
  customerFriendlyLogoUri: string;   // URL do logotipo
}
```

**Observações:**
- Participantes com múltiplos servidores de autorização resultam em múltiplas entradas na lista
- Participantes sem servidores de autorização são automaticamente filtrados
- O token de autenticação é gerenciado automaticamente pelo SDK (com cache)

---

### `createEnrollment(credentials, payload)`

Cria um enrollment inicial para registrar um dispositivo do usuário.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `payload` (objeto, obrigatório):
  - `organisationId` (string, obrigatório): UUID da organização participante
  - `authorisationServerId` (string, obrigatório): UUID do servidor de autorização
  - `enrollment` (objeto, obrigatório):
    - `document` (string, opcional): CPF do usuário
    - `externalId` (string, opcional): ID externo
    - `deviceName` (string, opcional): Nome do dispositivo
    - `debtor` (objeto, obrigatório): Dados da conta do pagador
      - `accountNumber` (string): Número da conta
      - `accountIssuer` (string): Agência
      - `accountIspb` (string): Código ISPB
      - `accountType` (string): Tipo de conta ('CACC' | 'SLRY' | 'SVGS' | 'TRAN')
  - `redirectUri` (string, obrigatório): URL do callback após autorização
  - `paymentId` (string, opcional): ID do pagamento relacionado

**Retorna:** `Promise<CreateEnrollmentResponse>`

**Estrutura do CreateEnrollmentResponse:**
```typescript
interface CreateEnrollmentResponse {
  id: string;              // UUID do enrollment
  redirectUrl?: string;     // URL para redirecionar o usuário
  consentId?: string | null; // ID do consentimento (pode ser null)
}
```

---

### `registerDevice(credentials, payload)`

Registra um dispositivo usando autenticação FIDO2/Passkeys após o callback de autorização.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `payload` (objeto, obrigatório):
  - `state` (string): Estado retornado no callback
  - `code` (string): Código retornado no callback
  - `idToken` (string): Token ID retornado no callback
  - `tenantId` (string): Mesmo valor do subtenantId
  - `platform` (string): Plataforma ('ANDROID' | 'IOS' | 'WEB' | 'BROWSER' | 'CROSS_PLATFORM')
  - `rp` (string, opcional): Relying Party ID

**Retorna:** `Promise<Enrollment>`

**Estrutura do Enrollment:**
```typescript
interface Enrollment {
  enrollmentId: string;
  creationDateTime: string;
  status: 'AWAITING_RISK_SIGNALS' | 'AWAITING_ACCOUNT_HOLDER_VALIDATION' | 
          'AWAITING_ENROLLMENT' | 'AUTHORISED' | 'REJECTED' | 'REVOKED';
  statusUpdateDateTime: string;
  permissions: 'PAYMENTS_INITIATE';
  expirationDateTime: string | null;
  // ... outros campos
}
```

**Observações:**
- O dispositivo deve suportar FIDO2/Passkeys
- O usuário precisará autorizar com biometria (Face ID, Touch ID, etc.)
- O enrollment só estará pronto quando o status for `AUTHORISED`

---

### `getEnrollmentList(credentials, cpf)`

Lista todos os enrollments de um usuário pelo CPF.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `cpf` (string, obrigatório): CPF do usuário (11 dígitos)

**Retorna:** `Promise<EnrollmentList>`

**Estrutura do EnrollmentList:**
```typescript
interface EnrollmentList {
  id: string;
  username: string;
  subTenant: string;
  enrollments: EnrollmentUser[];
}
```

---

### `revokeEnrollment(credentials, enrollmentId)`

Revoga um enrollment, desativando o dispositivo cadastrado.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `enrollmentId` (string, obrigatório): ID do enrollment a ser revogado

**Retorna:** `Promise<RevokeEnrollmentResponse>`

---

### `createPaymentWithEnrollment(credentials, payload)`

Cria um pagamento usando um enrollment ativo, sem necessidade de redirecionamento ao banco.

**Parâmetros:**
- `credentials` (objeto, obrigatório):
  - `subtenantId` (string): ID do subtenant fornecido pela Lina
  - `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
- `payload` (objeto, obrigatório):
  - `enrollmentId` (string, obrigatório): ID do enrollment ativo
  - `organisationId` (string, obrigatório): UUID da organização participante
  - `authorisationServerId` (string, obrigatório): UUID do servidor de autorização
  - `paymentId` (string, opcional): ID do pagamento se já foi criado
  - `payment` (objeto, opcional): Dados do pagamento (similar ao `createConsent`)
  - `fidoSignOptions` (objeto, obrigatório):
    - `rp` (string): Relying Party ID
    - `platform` (string): Plataforma ('ANDROID' | 'IOS' | 'WEB' | 'BROWSER' | 'CROSS_PLATFORM')

**Retorna:** `Promise<PaymentWithEnrollmentResponse>`

**Observações:**
- Esta função realiza internamente: criação do consentimento, obtenção de opções FIDO, solicitação de biometria, assinatura e autorização
- O usuário será solicitado a autorizar com biometria automaticamente
- O enrollment deve estar com status `AUTHORISED`

---

### `configure(config)`

Configura as URLs base do SDK para diferentes ambientes.

**Parâmetros:**
- `config` (objeto):
  - `iamBaseUrl` (string, opcional): URL base do serviço de autenticação IAM
  - `apiBaseUrl` (string, opcional): URL base da API do Embedded Payment Manager

**Valores padrão (Homologação):**
```typescript
{
  iamBaseUrl: 'https://iam.hml.linaob.com.br',
  apiBaseUrl: 'https://embedded-payment-manager.hml.linaob.com.br'
}
```

### `LinaPayError`

Classe de erro customizada para tratamento de erros do SDK.

**Propriedades:**
- `message` (string): Mensagem de erro
- `statusCode` (número, opcional): Código HTTP do erro (se aplicável)
- `originalError` (unknown, opcional): Erro original que causou o LinaPayError

## 🔐 Autenticação

O SDK gerencia automaticamente a autenticação OAuth2 com o servidor IAM:
- Token de acesso é obtido usando as credenciais fornecidas
- Token é cacheado e reutilizado enquanto válido
- Renovação automática do token quando expira (5 minutos antes da expiração real)

## ⚠️ Tratamento de Erros

Todos os métodos podem lançar `LinaPayError` nas seguintes situações:

- **Credenciais inválidas**: `statusCode: 401` ou `403`
- **Erro de rede**: Timeout ou sem conexão
- **Erro do servidor**: `statusCode: 500+`
- **Validação de payload**: Campos obrigatórios ausentes ou inválidos
- **Validação de formato**: CPF/CNPJ, URLs, datas ou valores numéricos inválidos

Exemplo de tratamento:

```typescript
import { LinaPayError } from 'react-native-lina-pay-sdk';

try {
  const consent = await createConsent(credentials, payload);
} catch (error) {
  if (error instanceof LinaPayError) {
    // Erros de validação (sem statusCode)
    if (!error.statusCode) {
      console.error('Erro de validação:', error.message);
      // Ex: "payment.value must be greater than zero"
      // Ex: "payment.creditor.cpfCnpj must be a valid CPF or CNPJ"
      return;
    }
    
    // Erros HTTP
    switch (error.statusCode) {
      case 400:
        console.error('Payload inválido:', error.message);
        break;
      case 401:
      case 403:
        console.error('Credenciais inválidas');
        break;
      case 500:
        console.error('Erro no servidor');
        break;
      default:
        console.error('Erro:', error.message);
    }
  }
}
```

## 🧪 Desenvolvimento

### Rodando o Exemplo

O projeto inclui um app de exemplo que demonstra o uso do SDK:

```sh
# Instalar dependências
yarn

# Buildar o SDK
yarn prepare

# Rodar o exemplo no Android
yarn example android

# Rodar o exemplo no iOS
yarn example ios
```

### Testes

```sh
# Rodar testes unitários
yarn test

# Verificar tipos TypeScript
yarn typecheck

# Lint
yarn lint
```

### Estrutura do Projeto

```
src/
├── config/
│   └── environment.ts          # Configuração de URLs
├── controllers/
│   ├── consent.controller.ts   # Controller de consentimentos
│   ├── enrollment.controller.ts # Controller de enrollments
│   ├── participants.controller.ts # Controller de participantes
│   └── payment.controller.ts   # Controller de pagamentos
├── services/
│   ├── auth.service.ts         # Autenticação OAuth2
│   ├── consent.service.ts     # API de consentimentos
│   ├── enrollment.service.ts  # API de enrollments
│   ├── fido.service.ts        # Serviço FIDO2/Passkeys
│   ├── participants.service.ts # API de participantes
│   └── payment.service.ts     # API de pagamentos
├── types/
│   ├── auth.types.ts           # Tipos de autenticação
│   ├── consent.types.ts        # Tipos de consentimento
│   ├── enrollment.types.ts     # Tipos de enrollment
│   ├── fido.types.ts           # Tipos FIDO
│   ├── participants.types.ts  # Tipos de participantes
│   ├── payment.types.ts        # Tipos de pagamento
│   └── index.ts                # Re-exports
├── utils/
│   ├── enrollment.utils.ts     # Utilitários de enrollment
│   └── http.utils.ts           # Utilidades HTTP
└── index.tsx                   # API pública do SDK
```

Desenvolvido por [Lina OpenX](https://www.linaopenx.com.br/) com ❤️