---
name: payzu-conta-digital
description: Skill para integrar com a API PayZu Conta Digital (Pix in/out, TED, transferencia interna, saldo, perfil, extrato). Use quando o codigo do usuario chamar pix.payzu.io ou mencionar PayZu Conta Digital / Hub.
---

# PayZu Conta Digital — Skill

API REST de conta bancaria digital via API. 13 endpoints, suporte completo a
Pix, TED e transferencias internas em tempo real. Casos de uso tipicos:
carteira pessoal, conta empresarial, ERP, banking-as-a-service.

## Identidade

- **Base URL**: `https://pix.payzu.io/v1`
- **Doc completa**: https://docs.payzu.com.br/docs/conta-digital
- **OpenAPI 3**: https://docs.payzu.com.br/openapi/payzu-conta-digital-api.json
- **Markdown bruto pra IA**: https://docs.payzu.com.br/conta-digital/llms-full.txt
- **Dashboard / abrir conta**: https://abrirconta.payzu.com.br

## Grupos de endpoints (13 totais)

| Grupo | Endpoints |
|---|---|
| Depositos | `POST /pix` (cria cobranca), `GET /pix/{id}` (consulta), `GET /proof/{id}` (comprovante), `POST /pix/refund/{id}` (estorna) |
| Saques | `POST /withdraw` (chave Pix), `POST /withdraw/bank-data` (banco/agencia/conta), `POST /ted`, `POST /withdraw/qrcode` (paga QR), `POST /internal-transfer`, `GET /proof/{id}` |
| Gestao de Conta | `GET /user/balance` (saldo disponivel/bloqueado), `GET /user` (perfil + limites + tarifas), `GET /user/transactions` (extrato paginado), `GET /user/summary` (volumes + metricas) |

## REGRAS INVIOLAVEIS

### Headers obrigatorios

```http
Authorization: Bearer SEU_TOKEN
Content-Type: application/json
```

Token do dashboard. Vault sempre, nunca no front nem no repo.

### Valores em REAIS decimais, NUNCA centavos

```json
{ "amount": 250.00 }   // R$ 250,00 — correto
{ "amount": 25000 }    // R$ 25.000,00 — ERRADO
```

### clientReference em criacoes

Idempotencia e reconciliacao dependem dele.

```typescript
const clientReference = `payout-${orderId}`;  // bom
```

### callbackUrl em criacoes (se quer saber resultado)

```json
{
  "amount": 99.90,
  "callbackUrl": "https://seusite.com.br/webhooks/payzu",
  "clientReference": "order-001"
}
```

Endpoint recebe webhook: HTTPS publico, 2xx em ate 5s, processa em fila.

### Webhook retry: ate 72 tentativas

Backoff exponencial + jitter. **Sempre dedupe `id + status`**.

### Enums

**Status** (`status`):
```
PENDING -> COMPLETED | CANCELED | REFUNDED | EXPIRED
```

**Tipo de transacao** (`type`):
- `DEPOSIT`: cobranca recebida ou estorno entrante
- `WITHDRAW`: saque, TED, transferencia out

**Tipo de chave Pix** (`pixType`):
- `cpf`, `cnpj`, `phone` (5511…), `email`, `evp` (UUID)

### Tratamento de erro

```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Missing or invalid Bearer token",
  "requestId": "cmp70zh4008dx01s6bwjb5bez"
}
```

- `4xx`: cliente errou, nao retenta
- `429`/`5xx`/timeout: retry backoff exponencial, max 5
- **Sempre logue `requestId`**

### Saldo debitado ANTES do envio

Em saques (Pix, TED, dados bancarios), o saldo e debitado **antes** do envio.
Se falhar (chave invalida, banco indisponivel), o valor e estornado
automaticamente e o status vira `CANCELED`. Use callback pra reconciliar.

## Padroes de codigo

### Node.js — cliente

```typescript
const BASE = 'https://pix.payzu.io/v1';
const TOKEN = process.env.PAYZU_TOKEN!;

async function hub(method: string, path: string, body?: unknown) {
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers: {
      Authorization: `Bearer ${TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const data = await res.json();
  if (!res.ok) {
    throw new Error(`${res.status}: ${data.message} (req=${data.requestId})`);
  }
  return data;
}

// Criar cobranca
const charge = await hub('POST', '/pix', {
  amount: 99.90,
  clientReference: `order-${orderId}`,
  callbackUrl: `${process.env.APP_URL}/webhooks/payzu`,
});

// Saque por chave Pix
const withdraw = await hub('POST', '/withdraw', {
  amount: 250.00,
  pixKey: '12345678901',
  pixType: 'cpf',
  clientReference: `payout-${orderId}`,
  callbackUrl: `${process.env.APP_URL}/webhooks/payzu`,
});

// TED
const ted = await hub('POST', '/ted', {
  amount: 1000.00,
  bank: '341',
  branch: '0001',
  account: '12345-6',
  document: '12345678901',
  clientReference: `ted-${orderId}`,
});

// Transferencia interna
const internal = await hub('POST', '/internal-transfer', {
  amount: 100.00,
  targetEmail: 'destinatario@dominio.com.br',
  clientReference: `transfer-${orderId}`,
});
```

### Webhook handler

```typescript
import express from 'express';
const app = express();
app.use(express.json());

const seen = new Set<string>();  // em prod: Redis ou DB

app.post('/webhooks/payzu', async (req, res) => {
  res.status(200).end();  // resposta rapida primeiro

  const { id, status, type } = req.body;
  const key = `${id}:${status}`;
  if (seen.has(key)) return;
  seen.add(key);

  if (type === 'DEPOSIT' && status === 'COMPLETED') {
    await marcaPedidoPago(req.body);
  } else if (type === 'WITHDRAW' && status === 'CANCELED') {
    await reagendarSaque(req.body);  // saldo ja foi estornado
  }
});
```

### Python

```python
import os, requests

BASE = 'https://pix.payzu.io/v1'
TOKEN = os.environ['PAYZU_TOKEN']

def hub(method, path, json=None):
    r = requests.request(method, f'{BASE}{path}',
        headers={'Authorization': f'Bearer {TOKEN}', 'Content-Type': 'application/json'},
        json=json, timeout=10)
    data = r.json()
    if not r.ok:
        raise Exception(f"{r.status_code}: {data.get('message')} (req={data.get('requestId')})")
    return data
```

## Boas praticas

- **Cache de saldo curto** (5-30s). Nao bate em `/user/balance` a cada requisicao
- **Pagina extrato** com `limit` + cursor, nao pega tudo de uma vez
- **Reconcilie por `clientReference`** comparando seu DB com a PayZu
- **Use `/user/summary`** pra dashboard, evita somar transacoes no cliente

## Pegadinhas

- **QR Code Pix dinamico apenas**. Estatico nao processa.
- **`callbackUrl` HTTPS publico**. Dev: ngrok.
- **Datas em ISO 8601 UTC**.
- **Sem signup self-service**. Conta criada manualmente apos KYC.
- **Pix Processamento e API DIFERENTE** (`api.payzu.processamento.com/v1`). Se
  o caso e Pix em volume sem TED, talvez seja Pix Processamento o produto certo.

## Quando responder duvidas

1. Cite endpoint + curl funcionando
2. Inclua headers, clientReference, callback handler
3. Se usuario errar centavos/reais, corrige
4. Se nao souber, diga "consulte https://docs.payzu.com.br/docs/conta-digital" — NAO invente endpoint
5. Mencione `requestId` em erro

## SDKs

Em breve. Atualmente, cliente HTTP cru funciona bem.
