Autenticação

A BSPAY usa duas camadas de segurança:

A BSPAY usa duas camadas de segurança:

  1. OAuth2 Bearer (Authorization) — exigido em todas as rotas
  2. 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:

  1. Crie uma credencial de API no Dashboard — você recebe client_id e client_secret
  2. Aguarde a ativação pelo administrador da conta
  3. Gere um access token via POST /v2/oauth/token
  4. 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:

Authorization: Basic {base64(client_id:client_secret)}
Content-Type: application/json
{ "grant_type": "client_credentials" }
cURL
PHP
JavaScript
Python
curl -X POST https://api.bspay.co/v2/oauth/token \
  -H "Authorization: Basic $(echo -n 'SEU_CLIENT_ID:SEU_CLIENT_SECRET' | base64)" \
  -H "Content-Type: application/json" \
  -d '{"grant_type": "client_credentials"}'
Sucesso
401 INVALID_CREDENTIALS
403 IP_BLOCKED_TEMPORARILY
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 3600,
  "meta": {
    "request_id": "93e93fccf4e7413880bb4495",
    "timestamp": "2026-04-04T14:23:37Z"
  }
}

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:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
curl https://api.bspay.co/v2/account/balance \
  -H "Authorization: Bearer SEU_ACCESS_TOKEN"

Ciclo de vida

PropriedadeValor
Validade1 hora (3600 segundos)
RenovaçãoGere um novo token com as mesmas credenciais
Múltiplos tokensCada chamada a /oauth/token gera um token independente
RevogaçãoTokens expiram automaticamente — não há endpoint de revogação

2. Assinatura HMAC (rotas financeiras)

Operações que movimentam dinheiro exigem três headers adicionais além do Bearer token:

X-Signature: hex(hmac_sha256(timestamp + "." + nonce + "." + body, signing_key))
X-Timestamp: <unix_seconds>
X-Nonce:     <uuid_v4>

Rotas que exigem HMAC:

  • POST /v2/transactions/cashout
  • POST /v2/pix/payment (legacy)
  • POST /v2/internal_transfers/payment
  • POST /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.

PHP
Node.js
Python
Go
$signingKey = $YOUR_SIGNING_KEY;
$body       = json_encode(['amount' => 50.00, 'currency' => 'BRL', /* ... */]);
$timestamp  = (string) time();
$nonce      = bin2hex(random_bytes(16));

$payload   = "{$timestamp}.{$nonce}.{$body}";
$signature = hash_hmac('sha256', $payload, $signingKey);

$ch = curl_init('https://api.bspay.co/v2/transactions/cashout');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer {$token}",
        "Content-Type: application/json",
        "X-Signature: {$signature}",
        "X-Timestamp: {$timestamp}",
        "X-Nonce: {$nonce}",
    ],
    CURLOPT_POSTFIELDS => $body,
]);
$res = json_decode(curl_exec($ch), true);

Validações no servidor

RegraJanelaErro se violar
X-Timestamp próximo do horário atual±5 minutosINVALID_TIMESTAMP (401)
X-Nonce único nos últimos 5 minutos (anti-replay)5 minREPLAY_DETECTED (401)
X-Signature bate com hash recalculadoINVALID_SIGNATURE (401)
Header obrigatório ausenteMISSING_SIGNATURE (401)

Esta página foi útil?