Autenticação
A BSPAY usa duas camadas de segurança:
A BSPAY usa duas camadas de segurança:
- OAuth2 Bearer (
Authorization) — exigido em todas as rotas - Assinatura HMAC (
X-Signature+X-Timestamp+X-Nonce) — exigida nas rotas financeiras (cashout, transferência interna, conversão)
1. Bearer Token (OAuth2 Client Credentials)
Quatro passos pra ficar autenticado:
- Crie uma credencial de API no Dashboard — você recebe
client_ideclient_secret - Aguarde a ativação pelo administrador da conta
- Gere um access token via
POST /v2/oauth/token - Envie o token no header
Authorization: Bearer {token}em cada requisição
Gerar token
POST /v2/oauth/token
Envie suas credenciais codificadas em Base64 no header Authorization e grant_type=client_credentials no body:
Após 5 tentativas erradas seguidas, o IP é bloqueado por 5 minutos (
IP_BLOCKED_TEMPORARILY). Rate limit do endpoint: 30 reqs/min/IP.
Usar o token
Inclua o token em todas as requisições:
Ciclo de vida
| Propriedade | Valor |
|---|---|
| Validade | 1 hora (3600 segundos) |
| Renovação | Gere um novo token com as mesmas credenciais |
| Múltiplos tokens | Cada chamada a /oauth/token gera um token independente |
| Revogação | Tokens expiram automaticamente — não há endpoint de revogação |
Nunca exponha credenciais no frontend. O client_secret e o access_token devem ser usados exclusivamente em chamadas servidor-a-servidor. Exposição no client-side compromete a segurança da sua conta.
2. Assinatura HMAC (rotas financeiras)
Operações que movimentam dinheiro exigem três headers adicionais além do Bearer token:
Rotas que exigem HMAC:
POST /v2/transactions/cashoutPOST /v2/pix/payment(legacy)POST /v2/internal_transfers/paymentPOST /v2/conversions/new
Como gerar a assinatura
A string assinada é a concatenação {timestamp}.{nonce}.{rawBody} com pontos como separador, hash com HMAC-SHA256 usando seu signing_key, resultado em hex lowercase.
Validações no servidor
| Regra | Janela | Erro se violar |
|---|---|---|
X-Timestamp próximo do horário atual | ±5 minutos | INVALID_TIMESTAMP (401) |
X-Nonce único nos últimos 5 minutos (anti-replay) | 5 min | REPLAY_DETECTED (401) |
X-Signature bate com hash recalculado | — | INVALID_SIGNATURE (401) |
| Header obrigatório ausente | — | MISSING_SIGNATURE (401) |
Use o body raw exato. A string assinada precisa usar exatamente o mesmo bytes que você envia no body. Se você re-serializar JSON após assinar (ou se uma lib re-formata), a assinatura quebra.
O signing_key é diferente do client_secret. Você gera o signing_key no Dashboard ao habilitar HMAC para a credencial. Trate como senha — nunca commite no repo.
