Guia do desenvolvedor¶
Este guia mostra o caminho completo: do registro do app até a primeira chamada autenticada na API de integração.
O fluxo é authorization code com PKCE. O client_secret fica no seu
back-end; o browser do usuário só carrega valores públicos.
O fluxo em uma imagem¶
sequenceDiagram
autonumber
participant U as Usuário (seller)
participant P as Seu sistema
participant G as Painel Gubee
participant A as API Gubee
U->>P: Clica em "Conectar com a Gubee"
P->>P: Gera code_verifier e code_challenge (S256)
P->>U: Redireciona para a autorização
U->>G: Aprova o acesso
G->>P: Volta na redirect_uri com code + state
P->>P: Confere o state
P->>A: Troca code + code_verifier por token
A-->>P: access_token + refresh_token
P->>A: Chama /integration/* com Bearer
1. Registrar o app¶
No painel da Gubee, em Integrações → Meus apps, crie o app e anote o
client_id e o client_secret. Cadastre a URI de redirecionamento exata que o
seu sistema vai usar.
Passo a passo em Criar e gerenciar apps.
export GUBEE_CLIENT_ID="seller-id-seuapp-1a2b3c4d"
export GUBEE_CLIENT_SECRET="<guardado no cofre do seu sistema>"
export GUBEE_REDIRECT_URI="https://seusistema.com.br/gubee/callback"
2. Gerar o PKCE¶
Para cada tentativa de conexão, gere um code_verifier aleatório, guarde-o na
sessão do usuário e derive o code_challenge:
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43)
CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" \
| openssl dgst -binary -sha256 \
| openssl base64 | tr '+/' '-_' | tr -d '=')
import base64, hashlib, secrets
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b"=").decode()
code_challenge = base64.urlsafe_b64encode(
hashlib.sha256(code_verifier.encode()).digest()
).rstrip(b"=").decode()
PKCE é obrigatório
O método precisa ser S256. Pedido sem code_challenge, ou com outro
método, é recusado antes de qualquer tela aparecer para o usuário.
Gere também um state aleatório e guarde-o na sessão — é ele que protege contra
requisições forjadas na volta.
3. Mandar o usuário para a autorização¶
O ponto de entrada é o painel da Gubee:
Monte a URL com os parâmetros e redirecione o browser do usuário:
https://admin.gubee.com.br/#/oauth2/authorize
?client_id=seller-id-seuapp-1a2b3c4d
&redirect_uri=https%3A%2F%2Fseusistema.com.br%2Fgubee%2Fcallback
&response_type=code
&code_challenge=5o15PQNwzn47imN3jrYsy1W1ex3drO0xWvmBNpvdu-s
&code_challenge_method=S256
&state=8f14e45fceea167a
| Parâmetro | Obrigatório | Valor |
|---|---|---|
client_id |
Sim | O client_id do app |
redirect_uri |
Sim | Exatamente uma das URIs cadastradas, URL-encoded |
response_type |
Sim | code |
code_challenge |
Sim | O challenge derivado do code_verifier |
code_challenge_method |
Sim | S256 |
state |
Recomendado | Valor aleatório, conferido na volta |
nonce |
Opcional | Repassado sem alteração |
Sempre este endereço, nunca outro
Mandar o usuário direto para o servidor de identidade pula validações da
Gubee e produz um token que a API recusa. O início do fluxo é sempre
admin.gubee.com.br/#/oauth2/authorize.
O usuário faz login se ainda não tiver sessão, aprova o acesso e é devolvido
para a sua redirect_uri.
4. Receber o code¶
A volta chega assim:
No seu endpoint de callback:
- Confira o
statecontra o que você guardou na sessão. Diferente ou ausente: descarte a requisição. - Recupere o
code_verifierdaquela mesma sessão. - Troque o
codepor token imediatamente — ele é de uso único e expira em poucos minutos.
Se o usuário negar o acesso, a volta traz error em vez de code.
5. Trocar o code por token¶
Chamada de back-end para back-end, com o client_secret:
curl -s -X POST "https://auth.gubee.com.br/realms/gubee/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=$GUBEE_CLIENT_ID" \
-d "client_secret=$GUBEE_CLIENT_SECRET" \
-d "code=$CODE" \
-d "redirect_uri=$GUBEE_REDIRECT_URI" \
-d "code_verifier=$CODE_VERIFIER"
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"expires_in": 300,
"refresh_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6...",
"token_type": "Bearer"
}
O expires_in vem em segundos e não é um valor fixo — leia sempre o da
resposta em vez de assumir uma duração no código.
Guarde o refresh_token no cofre, associado ao cliente que autorizou. É ele que
mantém a integração viva.
A troca acontece no seu servidor
O client_secret nunca pode sair do back-end. Não faça esta chamada do
browser, de aplicativo de celular ou de qualquer código que o usuário
consiga inspecionar.
6. Renovar o token¶
O access_token é curto. Renove com o refresh_token:
curl -s -X POST "https://auth.gubee.com.br/realms/gubee/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=$GUBEE_CLIENT_ID" \
-d "client_secret=$GUBEE_CLIENT_SECRET" \
-d "refresh_token=$REFRESH_TOKEN"
Boas práticas:
- Renove antes de expirar, e não depois do primeiro
401. - Não renove em paralelo para o mesmo cliente: centralize em um ponto e deixe as outras chamadas lerem do cache.
- Guarde o
refresh_tokennovo quando a resposta trouxer um. - Trate a falha de renovação como desconexão: o seller pode ter revogado o acesso. Avise-o em vez de repetir a chamada em laço.
7. Chamar a API¶
Com o access_token, use a API de integração normalmente:
curl -s "https://api.gubee.com.br/integration/orders/queue" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json"
A conta sobre a qual o app age é determinada pela autorização — não é preciso (nem possível) escolhê-la na chamada.
Os endpoints são os mesmos documentados na Referência da API.
Erros comuns¶
| Sintoma | Causa provável | O que fazer |
|---|---|---|
| A tela de autorização recusa antes de aparecer | redirect_uri diferente da cadastrada |
Compare caractere a caractere, inclusive barra final |
| Recusa por falta de PKCE | code_challenge ausente ou método diferente de S256 |
Gere o challenge com SHA-256 e envie code_challenge_method=S256 |
| Recusa por app desativado | Interruptor do dono ou da Gubee desligado | Reative na tela do app ou fale com a Gubee |
invalid_grant na troca do code |
code já usado, expirado, ou code_verifier de outra sessão |
Refaça o fluxo do início, garantindo que o verifier é o da mesma sessão |
401 nas chamadas de API |
access_token expirado |
Renove com o refresh_token |
| Renovação começou a falhar sem mudança no código | O seller revogou o acesso | Peça uma nova autorização |
| A autorização é recusada dizendo que o app já foi autorizado | O mesmo usuário já conectou este app | Revogue em Integrações → Apps conectados e autorize de novo |
Lista completa de códigos em Referência.
Checklist antes de publicar¶
-
client_secretem cofre, fora do repositório e fora do front-end -
code_verifierestateguardados por sessão e conferidos na volta - Uma URI de redirecionamento cadastrada por ambiente
- Renovação centralizada, antecipada e sem laço em caso de falha
- Falha de renovação tratada como desconexão, com aviso ao seller
- Tokens fora dos logs
- Caminho de reconexão disponível na sua interface