Documentacao  /  Prompt Completo de IA

Prompt Completo de IA

Documentacao integral da API TrevoPay em texto puro, otimizada para LLMs. Cole no ChatGPT, Claude, Gemini ou qualquer assistente de IA e peca: "integre no meu checkout" — a IA gera o codigo, voce so coloca a sua chave.

Como usar

  1. Clique em Copiar para area de transferencia.
  2. Cole no chat do seu assistente de IA preferido.
  3. Descreva o que voce quer (ex.: "crie um checkout PHP com PIX").
  4. Substitua os placeholders sk_test_... pela sua chave em Desenvolvedores.
684 linhas · 22,8 KB · UTF-8
Abrir em texto puro
llms.txt — TrevoPay
# TrevoPay — API de Pagamentos PIX (PIX IN + PIX OUT)

> Gateway de pagamento PIX via API REST+JSON. Voce cria cobrancas (PIX IN)
> e saques (PIX OUT) programaticamente e recebe confirmacoes por webhook
> assinado. Valores SEMPRE em centavos (int). Envelope padrao de resposta:
> { "success": bool, "data": object|null, "error": object|null }.

Site:      https://treevopay.com
Dashboard: https://treevopay.com/index?pagina=desenvolvedores
API base:  https://api.treevopay.com
Docs:      https://treevopay.com/docs
Status:    https://status.treevopay.com

## Regras essenciais (leia ANTES de enviar a primeira chamada)

Estas regras valem para TODO endpoint da API — PIX IN (cobrancas) e PIX OUT
(saques). Repetimos elas dentro de cada endpoint para nao precisar voltar.

1. amount SEMPRE em centavos (int). Nunca float, nunca string com virgula.
   - 1990  = R$ 19,90
   - 1616  = R$ 16,16
   - 100   = R$ 1,00
   - 50000 = R$ 500,00
   ARMADILHA COMUM: enviar 19.90 achando que cobra R$ 19,90 — vira 19
   centavos (R$ 0,19). Errado. O certo eh 1990.

2. Idempotency-Key obrigatoria em TODO POST que movimenta dinheiro
   (/v1/charges e /v1/cashouts). String de 8 a 200 chars. Use o id do
   seu pedido. Mesma key + mesmo corpo = mesma resposta (nunca duplica).

3. Webhook eh a fonte de verdade. Nunca libere acesso ao cliente confiando
   no retorno do front-end. So libere depois do webhook charge.paid
   (HMAC-SHA256 validado em tempo constante) ou apos GET /v1/charges/{id}.

4. HTTPS obrigatorio em producao. Chamadas HTTP fora de localhost retornam
   400 https_required. Sem excecoes.

5. Datas ISO-8601 UTC (sufixo Z). Moeda sempre "BRL". Campos em camelCase
   em request e response. Encoding sempre UTF-8.

6. Prefixos de ID: ch_ (cobrancas), bp_co_ (saques), whsec_ (signing
   secret de webhook), pk_test_/sk_test_/pk_live_/sk_live_ (API keys).

## Visao geral

A TrevoPay e um gateway de pagamento focado em PIX — PIX IN (entrada, via
cobranca/QR Code) e PIX OUT (saida, via cashout programatico) — para
infoprodutores e plataformas SaaS brasileiras. A API segue tres principios:

1. Baseada em intencao. Cada endpoint faz exatamente o que o nome diz.
   POST /v1/charges cria uma cobranca. POST /v1/cashouts realiza um saque.
   Sem aliases, sem ambiguidade.

2. Consistente. Toda resposta segue o envelope { data, error, success }.
   Se success=true, os dados estao em data. Se success=false, a falha esta
   em error com { code, message }. data e error sao mutuamente exclusivos.

3. Idempotente. POSTs que movimentam dinheiro exigem o header
   Idempotency-Key. Reenviar com a mesma key + mesmo corpo devolve a MESMA
   resposta — voce nunca duplica cobranca nem saque.

## Ambientes

- Producao:        https://api.treevopay.com
- Desenvolvimento: http://localhost:1515 (router PHP local)

Todos os exemplos abaixo usam a URL de producao. Versao atual: v1.

A versao da API e prefixada na URL (/v1/...). Mudancas que quebram
compatibilidade sobem a versao (v2). Adicoes nao-disruptivas (novos campos
opcionais, novos eventos, novos endpoints) permanecem em v1.

## Quick start (3 passos)

1. Gere uma API Key no painel TrevoPay: Dashboard > Ferramentas > API.
   Voce recebe um par pk_test_... / sk_test_... (e depois pk_live_ / sk_live_).

2. Faca POST /v1/charges com amount em centavos. A resposta traz o brCode
   (copia-e-cola PIX) e o brCodeBase64 (PNG inline do QR Code).

3. Cadastre seu webhook em Dashboard > Ferramentas > Webhooks e aguarde o
   evento charge.paid. Valide a assinatura HMAC antes de liberar o acesso.

## Autenticacao

Toda chamada de servidor usa o header:

    Authorization: Bearer SUA_SECRET

Tipos de chave:

- pk_test_... : chave publicavel de teste. NAO autentica chamadas server.
- sk_test_... : chave secreta de teste. Nunca movimenta dinheiro real.
- pk_live_... : chave publicavel de producao.
- sk_live_... : chave secreta de producao. Movimenta dinheiro real.

Regras de seguranca:

- A secret (sk_) aparece SOMENTE UMA VEZ na criacao. Guarde-a no seu cofre
  de segredos (Doppler, AWS Secrets Manager, GitHub Actions secrets, etc.).
- Nunca exponha sk_live_ no frontend, em mobile, em apps desktop, em
  repositorios publicos ou em logs.
- Rotacione chaves comprometidas no painel imediatamente. A chave antiga
  passa a retornar 401 key_revoked.
- A chave determina o ambiente: sk_test_ sempre cria cobranca em mode=test;
  sk_live_ em mode=live. Nao da pra misturar.

## Escopos (scopes)

Cada chave pode ter um subconjunto de escopos. Por padrao a chave criada no
painel recebe todos os escopos do plano. Use a API admin para emitir chaves
de escopo reduzido (ex.: somente leitura).

- CHARGE:CREATE  : criar cobrancas PIX
- CHARGE:READ    : consultar cobrancas
- CASHOUT:CREATE : criar saques PIX (cashout)
- CASHOUT:READ   : consultar saques

Chamar um endpoint sem escopo: 403 insufficient_scope.

## Criar cobranca PIX (PIX IN)

POST /v1/charges

REGRAS CRITICAS PRA PIX IN (resumo — detalhes na secao "Regras essenciais"):

- amount em centavos (int). 1990 = R$ 19,90. NUNCA 19.90 ou "19,90".
- Idempotency-Key obrigatorio (8-200 chars). Use o id do seu pedido.
- HTTPS obrigatorio. So libere acesso pelo webhook charge.paid (HMAC).

Headers obrigatorios:

- Authorization: Bearer sk_live_... (ou sk_test_...)
- Content-Type: application/json
- Idempotency-Key: string unica por cobranca, 8 a 200 caracteres

Sobre a Idempotency-Key:

- Mesma key + mesmo corpo: devolve a MESMA cobranca (nao duplica).
- Mesma key + corpo diferente: erro 409 idempotency_conflict.
- Outra requisicao em vooo com a mesma key: 409 idempotency_in_progress.
- A mesma key e reaproveitavel por 24h; depois desse periodo ela e liberada.
- Use seu identificador interno (ex.: id do pedido) como Idempotency-Key.

Campos do corpo (JSON):

- amount (int, obrigatorio): valor em centavos. Ex.: 1990 = R$ 19,90.
    minimo: 100 (R$ 1,00)
    maximo: 100000000 (R$ 1.000.000,00)
- description (string, opcional): nome do produto/cobranca. Ate 255 chars.
- externalId (string, opcional): seu identificador interno. Ate 120 chars.
- customer (object, opcional):
    - name (string): nome do cliente.
    - email (string): e-mail valido.
    - taxId (string): 11 digitos (CPF) ou 14 digitos (CNPJ), apenas numeros.
    - cellphone (string): DDD + numero, apenas digitos, 10 ou 11 chars.
- utm (object, opcional): { source, medium, campaign, term, content } —
  ecoado de volta no webhook charge.paid (uso analitico).
- mode: definido pela chave usada, retornado na resposta. Valores: test | live.

Exemplo de requisicao:

```bash
curl -X POST https://api.treevopay.com/v1/charges \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-123" \
  -d '{
    "amount": 1990,
    "description": "Curso de PIX",
    "externalId": "PED-123",
    "customer": {
      "name": "Joao Silva",
      "email": "joao@exemplo.com",
      "taxId": "12345678909",
      "cellphone": "11999998888"
    },
    "utm": { "source": "instagram", "medium": "bio" }
  }'
```

Resposta (201 Created):

```json
{
  "success": true,
  "data": {
    "id": "ch_2f1a8c9d4e5b6a7c8d9e0f12",
    "amount": 1990,
    "currency": "BRL",
    "status": "pending",
    "description": "Curso de PIX",
    "externalId": "PED-123",
    "brCode": "00020101021126...520400005303986540519.905802BR6304ABCD",
    "brCodeBase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
    "expiresAt": "2026-05-29T14:00:00Z",
    "mode": "live"
  },
  "error": null
}
```

Campos da resposta:

- id          : identificador unico da cobranca (prefixo ch_).
- amount      : echo do valor em centavos.
- currency    : sempre "BRL".
- status      : pending | paid | expired | failed | refunded.
- description : echo da descricao.
- externalId  : echo do seu identificador.
- brCode      : payload EMV PIX. Mostre como "copia e cola".
- brCodeBase64: PNG do QR Code, ja embutido como data URI. Pronto pra
                colocar em <img src="..."> sem nova requisicao.
- expiresAt   : ISO-8601 UTC. Apos esse momento o status vira expired.
- mode        : test | live (segue a chave usada).

## Consultar cobranca

GET /v1/charges/{id}

Headers:

- Authorization: Bearer sk_test_... ou sk_live_...

Use para polling de fallback. O caminho preferencial e webhook — polling
existe para casos em que o webhook ainda nao chegou (latencia de rede do
PSP) ou para reconciliacao em lote.

```bash
curl https://api.treevopay.com/v1/charges/ch_2f1a8c9d4e5b6a7c8d9e0f12 \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"
```

Resposta: mesmo formato da criacao, com o status atualizado.

## Status possiveis (cobranca)

- pending  : aguardando pagamento. Estado inicial.
- paid     : pagamento confirmado pelo PSP.
- expired  : prazo do QR expirou sem pagamento (expiresAt < agora).
- failed   : falha operacional (raro — erro interno do PSP).
- refunded : pagamento devolvido ao cliente.

O status e monotonico: paid nao volta para pending; expired nao volta para
pending. Refund e o unico estado terminal possivel apos paid.

## Criar saque PIX / cashout (PIX OUT)

POST /v1/cashouts

Saque PIX programatico (B2B/B2C). Util para plataformas que precisam pagar
prestadores, afiliados ou repassar valores ao cliente final.

REGRAS CRITICAS PRA PIX OUT (resumo — detalhes na secao "Regras essenciais"):

- amount em centavos (int, >= 1). 50000 = R$ 500,00. NUNCA float.
- pixKey + pixKeyType precisam casar:
    cpf    -> 11 digitos sem mascara
    cnpj   -> 14 digitos sem mascara
    phone  -> so digitos com DDD (ex.: 11999998888)
    email  -> minusculas
    random -> UUID v4
- Idempotency-Key obrigatorio (8-200 chars). Use o id do payout.
- Producao exige bspay_cashout_enabled=1 no painel admin (senao 503).
- HTTP 202 != saque feito. Confirmacao real vem por webhook cashout.confirmed.

Headers obrigatorios:

- Authorization: Bearer sk_live_... (com escopo CASHOUT:CREATE)
- Content-Type: application/json
- Idempotency-Key: string unica por saque, 8 a 200 caracteres

Restricoes em producao:

- Cashout em mode=live exige bspay_cashout_enabled=1 no painel admin.
  Quando desligado: 503 cashout_disabled.
- Cashout via API roda atualmente apenas com o driver BSPAY. Outros
  providers retornam 501 cashout_not_supported.
- Sandbox (sk_test_) roda livre — testa fluxo sem mover dinheiro.

Campos do corpo (JSON):

- amount (int, obrigatorio)      : valor em centavos (>= 1).
- pixKey (string, obrigatorio)   : chave PIX do destinatario, ate 200 chars.
- pixKeyType (string, obrigatorio): tipo da chave. Um de:
    - cpf
    - cnpj
    - email
    - phone
    - random
- externalId (string, opcional)  : seu identificador. Ate 64 chars. Quando
                                   omitido, geramos um deterministico a
                                   partir da Idempotency-Key.
- description (string, opcional) : descricao livre. Ate 140 chars.

Exemplo:

```bash
curl -X POST https://api.treevopay.com/v1/cashouts \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: saque-afiliado-789" \
  -d '{
    "amount": 50000,
    "pixKey": "joao@exemplo.com",
    "pixKeyType": "email",
    "externalId": "PAYOUT-789",
    "description": "Comissao afiliado abril/2026"
  }'
```

Resposta (202 Accepted):

```json
{
  "success": true,
  "data": {
    "id": "bp_co_a1b2c3d4e5f6a7b8",
    "amount": 50000,
    "currency": "BRL",
    "status": "pending",
    "externalId": "PAYOUT-789",
    "transactionId": "TXN-PSP-99887766",
    "pixKey": "joao@exemplo.com",
    "pixKeyType": "email",
    "description": "Comissao afiliado abril/2026",
    "failureReason": null,
    "mode": "live",
    "requestedAt": "2026-05-29T14:00:00Z",
    "confirmedAt": null
  },
  "error": null
}
```

O HTTP 202 indica que o saque foi aceito e enviado ao PSP. A confirmacao
final (status=confirmed ou status=failed) vem via webhook cashout.*.

## Consultar saque

GET /v1/cashouts/{id}

```bash
curl https://api.treevopay.com/v1/cashouts/bp_co_a1b2c3d4e5f6a7b8 \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"
```

## Status possiveis (saque)

- pending   : registrado e enviado ao PSP, aguardando confirmacao.
- confirmed : saque liquidado na chave PIX do destinatario.
- failed    : falha na execucao (ver failureReason).

## Webhooks

Cadastre uma URL de webhook em Dashboard > Ferramentas > Webhooks. A cada
mudanca de status enviamos um POST assinado para o seu endpoint. A fonte de
verdade e o servidor: nunca libere acesso confiando apenas no navegador.

Eventos de cobranca:

- charge.paid     : pagamento confirmado.
- charge.expired  : cobranca expirou sem pagamento.
- charge.failed   : falha operacional.
- charge.refunded : pagamento devolvido.

Eventos de saque:

- cashout.confirmed : saque liquidado.
- cashout.failed    : saque falhou (ver failureReason).

Headers enviados em cada entrega:

- X-Trevo-Event     : nome do evento (ex.: charge.paid).
- X-Trevo-Timestamp : epoch em segundos (anti-replay).
- X-Trevo-Signature : HMAC-SHA256 em hexadecimal.
- X-Trevo-Delivery  : id unico da entrega (use para deduplicar).

Corpo do webhook charge.paid (JSON completo):

```json
{
  "event": "charge.paid",
  "createdAt": "2026-05-29T14:01:12Z",
  "data": {
    "id": "ch_2f1a8c9d4e5b6a7c8d9e0f12",
    "externalId": "PED-123",
    "amount": 1990,
    "status": "paid",
    "paidAt": "2026-05-29T14:01:10Z",
    "utm": {
      "source": "instagram",
      "medium": "bio",
      "campaign": null,
      "term": null,
      "content": null
    },
    "customer": {
      "name": "Joao Silva",
      "email": "joao@exemplo.com",
      "taxId": "12345678909",
      "cellphone": "11999998888"
    }
  }
}
```

Politica de retry:

- 1 tentativa imediata apos o evento.
- Retries com backoff exponencial por ate 24h se o seu endpoint nao
  responder 2xx.
- Timeout esperado do seu endpoint: 10s. Responda 2xx rapido e processe
  em background.
- Janela anti-replay do timestamp: 5 minutos (300 segundos).
- Idempotente: o mesmo evento pode chegar mais de uma vez. Use
  X-Trevo-Delivery + uma tabela de deduplicacao no seu lado.

Validar a assinatura (PHP):

```php
<?php
$secret = 'whsec_SEU_SIGNING_SECRET';
$body = file_get_contents('php://input');
$ts   = $_SERVER['HTTP_X_TREVO_TIMESTAMP'] ?? '';
$sig  = $_SERVER['HTTP_X_TREVO_SIGNATURE'] ?? '';

// rejeita replay: timestamp com mais de 300s
if (!ctype_digit((string) $ts) || abs(time() - (int) $ts) > 300) {
    http_response_code(400);
    exit;
}

// assinatura = HMAC-SHA256(timestamp + "." + corpo_cru, signing_secret)
$expected = hash_hmac('sha256', $ts . '.' . $body, $secret);

// comparacao em tempo constante (nunca use ==)
if (!hash_equals($expected, $sig)) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);
// libere o acesso aqui usando $event['data']['externalId'], etc.
http_response_code(200);
```

Validar a assinatura (Node.js):

```js
const crypto = require('crypto');

function verifyWebhook(req, secret) {
  const ts  = req.headers['x-trevo-timestamp'] || '';
  const sig = req.headers['x-trevo-signature'] || '';
  const raw = req.rawBody;            // string crua, NAO o JSON parseado

  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

  const expected = crypto.createHmac('sha256', secret)
                         .update(`${ts}.${raw}`)
                         .digest('hex');

  // comparacao tempo-constante
  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(sig, 'hex');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

Validar a assinatura (Python):

```python
import hmac, hashlib, time

def verify_webhook(headers, raw_body: bytes, secret: str) -> bool:
    ts  = headers.get('X-Trevo-Timestamp', '')
    sig = headers.get('X-Trevo-Signature', '')
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        return False
    msg = f"{ts}.{raw_body.decode('utf-8')}".encode('utf-8')
    expected = hmac.new(secret.encode('utf-8'), msg, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)
```

## Sandbox (testar sem dinheiro)

Use sk_test_. Crie a cobranca normalmente; o brCode e o QR vem em formato
valido (ficticios — nao funcionam no app do banco). Para simular o
pagamento e disparar o webhook de saida:

```bash
curl -X POST https://api.treevopay.com/sandbox/simulate-payment/ch_2f1a8c9d4e5b6a7c8d9e0f12 \
  -H "Authorization: Bearer sk_test_SUA_CHAVE"
```

Parametros opcionais:

- ?silent=1 : marca pago sem disparar webhook. Use para testar a
              reconciliacao ativa (polling GET /v1/charges/{id}).

Cashout em sandbox roda livre — mode=test sempre retorna status=confirmed
sem bater no PSP.

## Codigo de exemplo — criar cobranca em outras linguagens

JavaScript (Node.js, fetch nativo):

```js
const res = await fetch('https://api.treevopay.com/v1/charges', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_SUA_CHAVE',
    'Content-Type':  'application/json',
    'Idempotency-Key': 'pedido-123',
  },
  body: JSON.stringify({
    amount: 1990,
    description: 'Curso de PIX',
    externalId: 'PED-123',
    customer: { name: 'Joao Silva', email: 'joao@exemplo.com' },
  }),
});
const { data, error } = await res.json();
if (error) throw new Error(error.message);
console.log(data.brCode);
```

Python (requests):

```python
import requests, uuid

resp = requests.post(
    'https://api.treevopay.com/v1/charges',
    headers={
        'Authorization': 'Bearer sk_live_SUA_CHAVE',
        'Content-Type':  'application/json',
        'Idempotency-Key': f'pedido-{uuid.uuid4()}',
    },
    json={
        'amount': 1990,
        'description': 'Curso de PIX',
        'externalId': 'PED-123',
    },
    timeout=15,
)
resp.raise_for_status()
print(resp.json()['data']['brCode'])
```

PHP (cURL):

```php
<?php
$ch = curl_init('https://api.treevopay.com/v1/charges');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer sk_live_SUA_CHAVE',
        'Content-Type: application/json',
        'Idempotency-Key: pedido-123',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'amount'      => 1990,
        'description' => 'Curso de PIX',
        'externalId'  => 'PED-123',
    ]),
]);
$res = json_decode(curl_exec($ch), true);
echo $res['data']['brCode'];
```

## Rate limits

- 100 requisicoes por minuto por API key.
- Ao exceder, a resposta e 429 rate_limited com o header Retry-After
  (segundos para esperar antes de tentar de novo).
- Use jitter (random 0-1s) ao retryar para evitar thundering herd.

## Erros

Em erro, data e null e error traz { code, message }. O HTTP status code
indica a categoria, o code indica a causa especifica.

Codigos por categoria:

| HTTP | code                       | Quando acontece                              |
|------|----------------------------|----------------------------------------------|
| 400  | idempotency_key_required   | Falta header Idempotency-Key.                |
| 400  | invalid_json               | Body nao e JSON valido.                      |
| 400  | https_required             | Chamada via HTTP em ambiente nao-local.      |
| 401  | invalid_credentials        | Chave invalida, malformada ou inexistente.   |
| 401  | key_revoked                | Chave revogada no painel.                    |
| 403  | insufficient_scope         | Chave nao tem o escopo (ex.: CHARGE:CREATE). |
| 404  | charge_not_found           | Cobranca nao existe para esta conta.         |
| 404  | cashout_not_found          | Saque nao existe para esta conta.            |
| 404  | not_found                  | Rota inexistente.                            |
| 409  | idempotency_conflict       | Mesma key + corpo diferente.                 |
| 409  | idempotency_in_progress    | Mesma key em processamento.                  |
| 422  | validation_error           | Campo invalido (ex.: amount <= 0).           |
| 429  | rate_limited               | Excedeu 100 req/min.                         |
| 501  | cashout_not_supported      | Provider ativo nao suporta cashout via API.  |
| 503  | cashout_disabled           | Cashout live desabilitado no painel admin.   |
| 5xx  | internal_error             | Falha interna. Reportar com correlation id.  |

Exemplo de resposta de erro:

```json
{
  "success": false,
  "data": null,
  "error": {
    "code": "validation_error",
    "message": "amount must be greater than 0"
  }
}
```

## Indo para producao

Checklist:

- [ ] Troque sk_test_ por sk_live_ em todos os ambientes.
- [ ] Use sempre HTTPS — nunca aceite webhook em endpoint HTTP.
- [ ] Valide a assinatura HMAC do webhook ANTES de qualquer side-effect.
- [ ] Use hash_equals / timingSafeEqual / hmac.compare_digest, nunca ==.
- [ ] Cheque o X-Trevo-Timestamp (rejeite se desviar > 5min do agora).
- [ ] Use X-Trevo-Delivery para deduplicar (webhook pode chegar 2x).
- [ ] Use Idempotency-Key em todas as cobrancas (id do pedido funciona).
- [ ] Logue o id da cobranca + correlation id para suporte.
- [ ] Trate 429 com backoff + jitter; nao retentar 4xx (exceto 429).
- [ ] Monitore o status na pagina /status (incidentes em tempo real).

## Boas praticas de seguranca

- Nunca exponha sk_live_ no frontend (JS publico, app mobile, repos
  publicos, logs estruturados que vao pro Datadog/CloudWatch).
- Sempre valide o webhook via HMAC-SHA256 em tempo constante.
- Utilize HTTPS em producao (impostos pelo nosso /v1/* — vai retornar
  https_required se chamar via HTTP).
- Utilize Idempotency-Key em todas as cobrancas e saques.
- Nao confie apenas no frontend para confirmar pagamentos — sempre
  re-valide via GET /v1/charges/{id} ou via webhook autenticado.
- Compare assinaturas com funcoes tempo-constante (hash_equals,
  timingSafeEqual, hmac.compare_digest). Nunca com == ou ===.
- Rotacione chaves periodicamente. Mantenha apenas as chaves em uso ativas.
- Restrinja escopo: chaves de leitura usam apenas CHARGE:READ /
  CASHOUT:READ; chaves de criacao tem o escopo correspondente.

## Convencoes

- Datas: ISO-8601 com timezone UTC (sufixo Z). Ex.: 2026-05-29T14:00:00Z.
- Valores monetarios: SEMPRE int em centavos. 1990 = R$ 19,90. Nunca
  enviar float ou string formatada.
- Moeda: sempre "BRL" (only PIX). Outras moedas nao sao suportadas.
- IDs:
    - ch_   : cobrancas (charges)
    - bp_co_: saques (cashouts)
    - whsec_: signing secret de webhook
    - pk_test_ / sk_test_ / pk_live_ / sk_live_ : API keys
- Casing: camelCase para campos de request/response. snake_case so em
  campos internos do banco (nunca expostos via API).
- Encoding: UTF-8 em request e response. Sempre.

## Suporte

- Documentacao web : https://treevopay.com/docs
- llms.txt (esta)  : https://treevopay.com/llms.txt
- Dashboard        : https://treevopay.com/index?pagina=desenvolvedores
- Webhooks logs    : https://treevopay.com/index?pagina=integracoes_webhooks
- Status / uptime  : https://status.treevopay.com
- E-mail suporte   : suporte@treevopay.com

## Exemplo cURL minimo (copia-e-cola)

```bash
curl -X POST https://api.treevopay.com/v1/charges \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-123" \
  -d '{"amount":1990,"description":"Curso","externalId":"PED-123"}'
```

Versao canonica machine-readable (para crawlers e agentes de IA externos): treevopay.com/llms.txt  ·  Voltar para a documentacao