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

# Entrar com a WyzeCash (OAuth)

> Ponha o botão "Entrar com a WyzeCash" no seu sistema: a pessoa entra com a conta WyzeCash dela e você lê só o nome e o resumo de vendas.

Com o OAuth, quem tem conta WyzeCash entra no **seu** sistema com a conta dela, sem senha nova e sem te passar chave de API. Ela vê na tela da WyzeCash o que o seu sistema vai ver e clica em **Permitir**.

É **só leitura** e pouca coisa:

| Escopo | O seu sistema vê | Rota |
| - | - | - |
| `profile` (sempre) | o nome da conta e um ID dela só para o seu sistema | `GET /oauth/userinfo` |
| `avatar` (se você marcar) | a foto do perfil (`picture`, um endereço de imagem) | `GET /oauth/userinfo` |
| `reports:read` (se você marcar) | quantas vendas pagas ela fez e o valor movimentado no período | `GET /oauth/summary` |

> [!WARNING]
>
> Nenhum escopo dá acesso a e-mail, CPF/CNPJ, telefone, saldo, extrato, clientes ou pagadores. Nada escreve: o token OAuth não saca, não envia Pix e não cria cobrança, e não vale nas rotas `/v1`.

## Criar o OAuth

No painel, em **Integrações e API › OAuth › Criar OAuth** (pede o código do app autenticador):

* **Nome** do seu sistema (aparece para quem for entrar).
* **Link de retorno**, até 5: para onde a pessoa volta depois de autorizar. Endereço `https` completo (ou `http://localhost` para testar), sem `#` e sem `*`. O pedido precisa mandar exatamente um deles.
* **Escopos**: `profile` vem sempre; marque `avatar` se quiser a foto do perfil e `reports:read` se o seu sistema precisa do resumo de vendas. O sistema só consegue pedir o que estiver marcado.

Você recebe o **Client ID** (`bkc_...`) e o **Client Secret** (`bks_...`). Na tabela, o secret fica borrado com o botão de mostrar. Guarde o secret só no servidor do seu sistema, nunca no site, no app ou no navegador.

## O botão pronto

Em cada OAuth da tabela, o botão **Pegar o botão** entrega:

* o HTML do botão "Entrar com a WyzeCash", para colar no seu site;
* o link de autorização já com o seu Client ID, o link de retorno e os escopos;
* um exemplo da rota do seu servidor que monta o link final.

> [!NOTE]
>
> O link não pode ser fixo: o `state` e o `code_challenge` mudam a cada login, por segurança. Por isso o botão aponta para uma rota do **seu** servidor (ex.: `/entrar-com-bukiopay`), que gera os dois, guarda na sessão e redireciona para a WyzeCash.

Quem clica entra na conta WyzeCash do jeito que já entra no painel: com e-mail e senha ou com o Google (e o 2FA, se tiver ligado). O seu sistema nunca vê a senha nem o login do Google.

## O fluxo

É o OAuth 2.0 com código de autorização e **PKCE (S256) obrigatório**.

**1. Mande a pessoa para autorizar**

Gere um `code_verifier` aleatório (43 a 128 caracteres de `A-Z a-z 0-9 - . _ ~`) e um `state` aleatório, e guarde os dois na sessão. Calcule o `code_challenge` = SHA-256 do verifier em base64url e leve a pessoa para:

```text theme={null}
https://app.wyzecash.com.br/oauth/autorizar
  ?client_id=bkc_SEU_CLIENT_ID
  &redirect_uri=https://meusistema.com.br/bukio/callback
  &response_type=code
  &scope=profile%20avatar%20reports:read
  &state=VALOR_ALEATORIO
  &code_challenge=SHA256_DO_VERIFIER_EM_BASE64URL
  &code_challenge_method=S256
```

Sem sessão, ela entra primeiro (com o 2FA, se tiver) e volta para a autorização. Ela vê o nome do seu sistema, quem criou, para onde vai voltar e o que você vai ver.

**2. Receba o código**

Ao permitir, ela volta para o seu link com `?code=...&state=...`. Confira se o `state` é o mesmo que você guardou. Se ela cancelar, volta com `?error=access_denied&state=...`.

O `code` vale **60 segundos** e uma vez só.

**3. Troque o código pelo token (no servidor)**

```bash theme={null}
curl -X POST https://api.wyzecash.com.br/oauth/token \
  -u bkc_SEU_CLIENT_ID:bks_SEU_CLIENT_SECRET \
  -d grant_type=authorization_code \
  -d code=CODIGO_QUE_VOLTOU \
  -d redirect_uri=https://meusistema.com.br/bukio/callback \
  -d code_verifier=O_VERIFIER_GUARDADO
```

```json theme={null}
{
  "access_token": "bka_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "bkr_...",
  "scope": "profile reports:read"
}
```

O corpo vai como `application/x-www-form-urlencoded` (JSON também é aceito). O Client ID e o Client Secret vão no `Authorization: Basic` ou no corpo (`client_id`, `client_secret`), nunca nos dois.

**4. Leia o nome e o resumo**

```bash theme={null}
curl https://api.wyzecash.com.br/oauth/userinfo \
  -H "Authorization: Bearer bka_..."
```

```json theme={null}
{
  "sub": "9f2c4b1e7a0d4c3f8b6e5a2d1c0f9e8a",
  "name": "Maria Silva",
  "picture": "https://app.wyzecash.com.br/avatars/7KQ2M9XP4RZTB8ND6HCV3W1J5PFQ0GSA"
}
```

O `sub` é o ID dessa conta **só para o seu sistema** (outro sistema vê outro ID). Use ele para ligar a pessoa ao cadastro do seu lado. O `picture` só vem com o escopo `avatar` (e é `null` se a pessoa não tem foto); quando ela troca a foto, o endereço muda, então leia de novo no próximo login.

```bash theme={null}
curl "https://api.wyzecash.com.br/oauth/summary?from=2026-10-01&to=2026-10-31" \
  -H "Authorization: Bearer bka_..."
```

```json theme={null}
{ "from": "2026-10-01", "to": "2026-10-31", "transactions": 42, "amount": 1234500, "currency": "BRL" }
```

`transactions` são as vendas pagas no período (Pix, cartão e cripto) e `amount` o valor bruto delas, em centavos. Os dias são de Brasília; sem `from` e `to`, os últimos 30 dias; no máximo 366 dias por consulta.

## Renovar o token

O token de acesso vale **1 hora**. Para outro, use o `refresh_token` (vale 30 dias):

```bash theme={null}
curl -X POST https://api.wyzecash.com.br/oauth/token \
  -u bkc_SEU_CLIENT_ID:bks_SEU_CLIENT_SECRET \
  -d grant_type=refresh_token \
  -d refresh_token=bkr_...
```

A resposta traz um `refresh_token` **novo**: guarde ele e jogue o antigo fora.

> [!WARNING]
>
> Usar um `refresh_token` antigo de novo (ou o mesmo `code` duas vezes) é tratado como vazamento: a conexão inteira cai e a pessoa recebe um aviso. Ela precisa entrar com a WyzeCash outra vez.

## Sair (revogar)

```bash theme={null}
curl -X POST https://api.wyzecash.com.br/oauth/revoke \
  -u bkc_SEU_CLIENT_ID:bks_SEU_CLIENT_SECRET \
  -d token=bkr_...
```

Revogar o `refresh_token` desfaz a conexão; o `access_token`, só ele. Responde `200` sempre.

A pessoa também desconecta quando quiser, no painel, em **Integrações e API › OAuth › Apps conectados**. A conexão cai sozinha quando ela troca a senha, quando a conta é bloqueada, quando você exclui o OAuth e depois de 90 dias sem uso.

## Erros

`/oauth/token` e `/oauth/revoke` respondem no formato do OAuth:

```json theme={null}
{ "error": "invalid_grant", "error_description": "Código inválido, vencido ou já usado." }
```

| Erro | Quando |
| - | - |
| `invalid_client` (401) | Client ID ou Client Secret errado, ou OAuth excluído |
| `invalid_grant` | código vencido, já usado, de outro OAuth, `redirect_uri` diferente, `code_verifier` que não confere, `refresh_token` vencido ou desconectado |
| `invalid_request` | faltou um campo (`code`, `code_verifier`, `token`) |
| `unsupported_grant_type` | `grant_type` diferente de `authorization_code` e `refresh_token` |

`/oauth/userinfo` e `/oauth/summary` seguem o formato da API ([Erros](https://docs.wyzecash.com.br/erros.md)): `401 INVALID_TOKEN` (token vencido, revogado ou de conta desconectada) e `403 INSUFFICIENT_SCOPE` (falta o escopo), com `WWW-Authenticate: Bearer error="..."`.

Na tela de autorização, pedido sem PKCE S256, sem `state` ou com escopo que o OAuth não marcou volta para o seu link com `error=invalid_request` ou `error=invalid_scope`. Client ID inexistente ou link de retorno não cadastrado não voltam para lugar nenhum: a tela mostra o erro.

## Bibliotecas prontas

Qualquer biblioteca de OAuth 2.0 com PKCE serve. Os endereços estão nos metadados:

```bash theme={null}
curl https://api.wyzecash.com.br/.well-known/oauth-authorization-server
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.