> ## Documentation Index
> Fetch the complete documentation index at: https://docs.garu.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js SDK

> Integre pagamentos Garu no seu projeto Node.js em minutos

## Visão Geral

A SDK Node.js da Garu permite integrar pagamentos PIX, Cartão de Crédito e Boleto no seu projeto com poucas linhas de código. A SDK abstrai a API REST, usando valores em centavos e status simplificados para facilitar a integração.

<Note>
  **Pré-requisito:** Você precisa de uma chave de API. Veja como obter em
  [Autenticação](/api-reference/autenticacao).
</Note>

## Instalação

```bash theme={null}
npm install @garuhq/node
```

## Inicialização

```javascript theme={null}
import { Garu } from "@garuhq/node";

const garu = new Garu({
  apiKey: process.env.GARU_API_KEY,
});
```

<Warning>
  Nunca coloque sua chave de API diretamente no código. Use variáveis de
  ambiente.
</Warning>

## Cobranças

### Criar uma cobrança PIX

```javascript theme={null}
const charge = await garu.charges.create({
  amount: 4990, // R$ 49,90 em centavos
  method: "pix",
  customer: {
    name: "João Silva",
    email: "joao@email.com",
    document: "12345678900",
  },
});

console.log(charge.id); // ID da cobrança
console.log(charge.pixCode); // Código PIX copia-e-cola
console.log(charge.qrCodeUrl); // URL do QR Code
```

### Criar uma cobrança com cartão de crédito

```javascript theme={null}
const charge = await garu.charges.create({
  amount: 29700, // R$ 297,00 em centavos
  method: "credit_card",
  installments: 3,
  customer: {
    name: "Maria Silva",
    email: "maria@email.com",
    document: "98765432100",
  },
});
```

### Listar cobranças

```javascript theme={null}
const charges = await garu.charges.list({
  status: "paid",
  limit: 10,
});

for (const charge of charges.data) {
  console.log(`${charge.id}: R$ ${charge.amount / 100} — ${charge.status}`);
}
```

### Consultar uma cobrança

```javascript theme={null}
const charge = await garu.charges.get("charge_12345");
console.log(charge.status); // "paid", "pending", "refunded", etc.
```

### Reembolsar uma cobrança

```javascript theme={null}
const refund = await garu.charges.refund("charge_12345");
console.log(refund.status); // "refunded"
```

## Clientes

### Criar um cliente

```javascript theme={null}
const customer = await garu.customers.create({
  name: "João Silva",
  email: "joao@email.com",
  document: "12345678900",
  phone: "11999999999",
});
```

### Listar clientes

```javascript theme={null}
const customers = await garu.customers.list({ limit: 20 });
```

### Consultar um cliente

```javascript theme={null}
const customer = await garu.customers.get("cust_abc123");
```

### Atualizar um cliente

```javascript theme={null}
const customer = await garu.customers.update("cust_abc123", {
  phone: "11988888888",
});
```

### Remover um cliente

```javascript theme={null}
await garu.customers.delete("cust_abc123");
```

### Filtrar clientes em atraso

```javascript theme={null}
const overdue = await garu.customers.list({ status: "overdue" });
// retorna apenas clientes com pelo menos uma cobrança agendada em atraso
```

<h2 id="scheduledcharges">
  Cobranças agendadas
</h2>

PIX e Boleto agendados para uma data futura. A Garu envia o e-mail no vencimento e
alerta o time se atrasar. Disponível a partir do `@garuhq/node` 0.5.

### Criar uma cobrança agendada

```javascript theme={null}
const charge = await garu.scheduledCharges.create({
  customerId: 42,
  amount: 297.5, // BRL decimal, NÃO centavos
  type: "one_time",
  dueDate: "2026-06-15", // YYYY-MM-DD, fuso de São Paulo
  methods: ["pix", "boleto"],
  description: "Mensalidade Junho",
});
console.log(charge.id); // sch_abc123
```

O SDK anexa `X-Idempotency-Key` automaticamente em cada `create`, então retries de rede
não duplicam a cobrança.

### Listar e filtrar

```javascript theme={null}
// Múltiplos status como array
const upcoming = await garu.scheduledCharges.list({
  status: ["scheduled", "due_today"],
  limit: 50,
});

// Em atraso de um cliente específico
const overdueForCustomer = await garu.scheduledCharges.list({
  status: "overdue",
  customerId: 42,
});

// Janela de vencimento + busca pelo cliente
const this_month = await garu.scheduledCharges.list({
  dueFrom: "2026-06-01",
  dueTo: "2026-06-30",
  search: "maria",
});
```

### Detalhes (cobrança + linha do tempo + transações)

```javascript theme={null}
const { charge, events, transactions } =
  await garu.scheduledCharges.get("sch_abc123");

// charge.amount é BRL decimal; transactions[].value é centavos.
```

### Ações no ciclo de vida

```javascript theme={null}
// Adiar
await garu.scheduledCharges.postpone("sch_abc123", {
  newDueDate: "2026-07-01",
  reason: "cliente pediu mais prazo",
});

// Pausar (sem lembretes até retomar)
await garu.scheduledCharges.pause("sch_abc123", { reason: "em negociação" });

// Retomar
await garu.scheduledCharges.resume("sch_abc123");

// Marcar como paga (pagamento off-Garu)
await garu.scheduledCharges.markPaid("sch_abc123", {
  paymentDate: "2026-06-20",
  externalReference: "TED 4472881",
});

// Cobrar agora (dispara na hora, sem esperar o vencimento; idempotente por ciclo)
const result = await garu.scheduledCharges.chargeNow("sch_abc123");
result.outcome; // 'dispatched' | 'already_sent' | 'not_sent' | 'failed'
result.message; // texto pt-BR pronto para exibir
```

Veja [Cobranças agendadas](/guias/cobrancas-agendadas) para o ciclo de vida completo
e a tabela de status permitidos por ação.

## Chaves de Idempotência

Use chaves de idempotência para garantir que uma operação não seja executada duas vezes, mesmo em caso de retry:

```javascript theme={null}
const charge = await garu.charges.create(
  {
    amount: 4990,
    method: "pix",
    customer: { email: "joao@email.com" },
  },
  {
    idempotencyKey: "order_12345",
  },
);
```

<Tip>
  Use o ID do pedido no seu sistema como chave de idempotência. Assim, mesmo que
  a requisição seja enviada duas vezes, apenas uma cobrança será criada.
</Tip>

## Tratamento de Erros

```javascript theme={null}
import { Garu, GaruError } from "@garuhq/node";

try {
  const charge = await garu.charges.create({
    amount: 100, // valor muito baixo
    method: "pix",
    customer: { email: "joao@email.com" },
  });
} catch (error) {
  if (error instanceof GaruError) {
    console.error(`Erro ${error.status}: ${error.message}`);
    console.error("Detalhes:", error.errors);
  } else {
    throw error;
  }
}
```

**Códigos de erro comuns:**

<AccordionGroup>
  <Accordion title="400 — Dados inválidos">
    Verifique os campos enviados. A resposta inclui detalhes sobre quais campos
    estão incorretos.
  </Accordion>

  <Accordion title="401 — Chave de API inválida ou ausente">
    Confira se a variável `GARU_API_KEY` está definida e se a chave é válida.
  </Accordion>

  <Accordion title="404 — Recurso não encontrado">
    O ID informado não corresponde a nenhum recurso existente.
  </Accordion>

  <Accordion title="409 — Conflito de idempotência">
    A chave de idempotência já foi usada com dados diferentes. Use uma chave
    única por operação.
  </Accordion>

  <Accordion title="422 — Regra de negócio violada">
    A requisição é válida mas viola uma regra de negócio (ex: valor mínimo,
    status incompatível).
  </Accordion>

  <Accordion title="429 — Rate limit excedido">
    Aguarde alguns segundos e tente novamente. Implemente backoff exponencial em
    automações.
  </Accordion>
</AccordionGroup>

## Recursos

<CardGroup cols={2}>
  <Card title="Repositório GitHub" icon="github" href="https://github.com/Garu-Pagamentos/garu-node">
    Código-fonte e documentação técnica
  </Card>

  <Card title="Pacote npm" icon="npm" href="https://www.npmjs.com/package/@garuhq/node">
    @garuhq/node no npm
  </Card>
</CardGroup>

## Próximos Passos

<CardGroup cols={2}>
  <Card title="MCP Server" icon="plug" href="/guias/mcp-server">
    Conecte agentes de IA à API
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api-reference/webhooks">
    Receba notificações de pagamento
  </Card>
</CardGroup>
