npm package: @rivoo/sdk
Description: Official RivooPay SDK for JavaScript/TypeScript — PIX payments, customers, products, webhooks and more.
Author: Rivoo
Latest version: 1.0.1

# @rivoo/sdk

SDK oficial da **RivooPay** para JavaScript e TypeScript.

Integre pagamentos PIX, gestão de clientes, produtos, webhooks e saques em qualquer ambiente JS — Node.js, NestJS, Next.js, browser e mais.

## Instalação

```bash
npm install @rivoo/sdk
# ou
yarn add @rivoo/sdk
# ou
pnpm add @rivoo/sdk
```

## Quick Start

```ts
import { RivooPay, WebhookEvent } from '@rivoo/sdk';

const rivoopay = new RivooPay({
  apiKey: 'pk_live_sua_chave_aqui',
});
```

## Cobranças (Charges)

### Criar link de pagamento

```ts
const charge = await rivoopay.charges.createPaymentLink({
  total: 5000, // R$ 50,00 (em centavos)
  customer: {
    taxId: '12345678900',
    name: 'João Silva',
    email: 'joao@email.com',
    phone: '11999999999',
  },
  successUrl: 'https://meusite.com/sucesso',
  failedUrl: 'https://meusite.com/falha',
  items: [
    { productId: 'prod_abc123', quantity: 2 },
  ],
});

console.log(charge.data?.url); // URL da página de pagamento
```

### Criar cobrança PIX direta

```ts
const pix = await rivoopay.charges.createPixCharge({
  amount: 1500, // R$ 15,00
  customer: {
    taxId: '12345678900',
    name: 'Maria Santos',
    email: 'maria@email.com',
    phone: '11988888888',
  },
  expiresIn: 900, // 15 minutos
});

console.log(pix.data?.brCode);       // PIX copia-e-cola
console.log(pix.data?.brCodeBase64); // QR Code em base64
```

### Criar QR Code PIX estático

Gera um QR Code PIX com valor fixo:

```ts
const staticPix = await rivoopay.charges.createStaticPixCharge({
  amount: 2500, // R$ 25,00
});

console.log(staticPix.data?.brCode);        // PIX copia-e-cola
console.log(staticPix.data?.qrCodeImage);   // URL da imagem do QR Code (PNG)
console.log(staticPix.data?.correlationID); // ID de correlação do provedor
```

> **Nota:** requer autenticação via API Key ou JWT.

### Consultar cobrança

```ts
const charge = await rivoopay.charges.getById('charge_id_aqui');

console.log(charge.data?.status);        // OPEN | COMPLETED | EXPIRED
console.log(charge.data?.paymentStatus); // PENDING | PROCESSING | PAID | EXPIRED
```

### Gerar PIX para link de pagamento existente

```ts
const pixPayment = await rivoopay.charges.generatePixForCharge('charge_id', {
  customer: {
    taxId: '12345678900',
    name: 'João Silva',
    email: 'joao@email.com',
    phone: '11999999999',
  },
});
```

### Simular pagamento (sandbox)

```ts
// Funciona apenas com cobranças criadas com devMode: true
await rivoopay.charges.simulatePayment('charge_id');
```

### Idempotência

As operações de criação de cobrança suportam chave de idempotência (UUID v4, TTL 24h):

```ts
const charge = await rivoopay.charges.createPixCharge(
  { amount: 5000, customer: { /* ... */ } },
  { idempotencyKey: 'f47ac10b-58cc-4372-a567-0e02b2c3d479' },
);
```

## Clientes (Customers)

```ts
import { DefaultStatus } from '@rivoo/sdk';

// Listar todos
const customers = await rivoopay.customers.list();

// Buscar por ID
const customer = await rivoopay.customers.getById('cust_abc123');

// Criar cliente
const newCustomer = await rivoopay.customers.create({
  name: 'João Silva',
  taxId: '12345678900',
  email: 'joao@email.com',
  phone: '11999999999',
  status: DefaultStatus.ACTIVE,
  postalCode: '01001000',
  address: 'Praça da Sé',
  number: '1',
  district: 'Sé',
});

// Atualizar cliente
await rivoopay.customers.update({
  id: 'cust_abc123',
  phone: '11977777777',
  status: DefaultStatus.INACTIVE,
});
```

## Produtos (Products)

```ts
// Listar produtos
const products = await rivoopay.products.list({ status: DefaultStatus.ACTIVE });

// Buscar por ID
const product = await rivoopay.products.getById('prod_abc123');

// Buscar por SKU
const product = await rivoopay.products.getBySku('PLAN-MONTHLY');

// Criar produto
const newProduct = await rivoopay.products.create({
  name: 'Plano Mensal',
  description: 'Assinatura mensal do serviço',
  price: 4990, // R$ 49,90 (em centavos)
  sku: 'PLAN-MONTHLY',
});

// Atualizar produto
await rivoopay.products.update({
  id: 'prod_abc123',
  price: 5990,
});
```

## Webhooks

```ts
import { WebhookEvent } from '@rivoo/sdk';

// Listar webhooks
const webhooks = await rivoopay.webhooks.list();

// Criar webhook
const webhook = await rivoopay.webhooks.create({
  name: 'Meu Webhook',
  url: 'https://meusite.com/webhooks/rivoopay',
  events: [WebhookEvent.CHARGE_PAID, WebhookEvent.CHARGE_EXPIRED],
});

// Atualizar webhook
await rivoopay.webhooks.update({
  id: 'wh_abc123',
  events: [WebhookEvent.CHARGE_PAID],
});

// Deletar webhook
await rivoopay.webhooks.delete('wh_abc123');

// Listar eventos disponíveis
const events = await rivoopay.webhooks.listEvents();

// Estatísticas da fila
const stats = await rivoopay.webhooks.getQueueStats();
```

## Conta (Account)

```ts
// Consultar saldo
const balance = await rivoopay.account.getBalance();

// Criar saque (transferência PIX)
const withdraw = await rivoopay.account.withdraw({
  value: 10000, // R$ 100,00
});

// Listar histórico de saques
const withdrawals = await rivoopay.account.listWithdrawals();
```

## Configuração Avançada

### Opções do cliente

```ts
const rivoopay = new RivooPay({
  // Autenticação (obrigatório: apiKey OU accessToken)
  apiKey: 'pk_live_...',

  // URL customizada (padrão: https://api.rivoopay.app.br)
  baseUrl: 'https://minha-api.com',

  // Ambiente sandbox
  sandbox: true,

  // Timeout em ms (padrão: 30000)
  timeout: 15000,

  // Retentativas automáticas em 429/5xx (padrão: 2)
  maxRetries: 3,

  // Headers extras
  headers: {
    'X-Custom-Header': 'valor',
  },

  // fetch customizado (Node.js < 18)
  fetch: customFetchImplementation,
});
```

### Tratamento de erros

```ts
import {
  RivooPay,
  RivooPayApiError,
  RivooPayRateLimitError,
  RivooPayIdempotencyError,
  RivooPayTimeoutError,
  RivooPayNetworkError,
} from '@rivoo/sdk';

try {
  await rivoopay.charges.createPixCharge({ /* ... */ });
} catch (error) {
  if (error instanceof RivooPayRateLimitError) {
    console.log(`Rate limited. Retry in ${error.retryAfter}s`);
  } else if (error instanceof RivooPayIdempotencyError) {
    console.log('Idempotency key conflict');
  } else if (error instanceof RivooPayTimeoutError) {
    console.log('Request timed out');
  } else if (error instanceof RivooPayNetworkError) {
    console.log('Network error:', error.message);
  } else if (error instanceof RivooPayApiError) {
    console.log(`API error ${error.statusCode}: ${error.message}`);
    console.log('Response body:', error.body);
  }
}
```

## Uso com NestJS

```ts
import { Module } from '@nestjs/common';
import { RivooPay } from '@rivoo/sdk';

@Module({
  providers: [
    {
      provide: RivooPay,
      useFactory: () =>
        new RivooPay({ apiKey: process.env.RIVOOPAY_API_KEY }),
    },
  ],
  exports: [RivooPay],
})
export class RivooPayModule {}

// No service:
@Injectable()
export class PaymentService {
  constructor(private readonly rivoopay: RivooPay) {}

  async createCharge(amount: number) {
    return this.rivoopay.charges.createPixCharge({
      amount,
      customer: { /* ... */ },
    });
  }
}
```

## Valores monetários

Todos os valores monetários na SDK são representados em **centavos** (inteiros):

| Valor real | Valor na SDK |
|-----------|-------------|
| R$ 5,00   | `500`       |
| R$ 49,90  | `4990`      |
| R$ 100,00 | `10000`     |

O valor mínimo para cobranças é **500** (R$ 5,00).

## Tipos e Enums

Todos os tipos TypeScript são exportados para uso direto:

```ts
import type {
  Customer,
  CreateCustomerInput,
  ChargeDetail,
  CreatePixChargeInput,
  CreateStaticPixChargeInput,
  StaticPixChargeData,
  StaticPixChargeResponse,
  Product,
  Webhook,
  RivooPayResponse,
} from '@rivoo/sdk';

import {
  DefaultStatus,
  ChargeStatus,
  PaymentStatus,
  WebhookEvent,
  WithdrawStatus,
} from '@rivoo/sdk';
```

## Compatibilidade

| Ambiente        | Suportado |
|----------------|-----------|
| Node.js ≥ 18   | ✅        |
| Bun            | ✅        |
| Deno            | ✅        |
| Browser (ESM)  | ✅        |
| NestJS         | ✅        |
| Next.js        | ✅        |
| React Native   | ✅        |

> Para Node.js < 18, passe uma implementação de `fetch` via a opção `fetch` (ex: `node-fetch` ou `undici`).

## Licença

MIT