OAuth para apps

Se você faz um bot, plugin ou sistema que várias empresas usam, não peça a chave de API de cada uma. Com OAuth, a loja clica em Autorizar, escolhe a empresa e o que o app pode fazer, e o seu app recebe um token só para isso. A loja tira o acesso quando quiser, em Configuração → OAuth.

Para um bot que só você usa, na sua própria empresa, uma chave restrita basta.

Como funciona

  1. O seu app manda a pessoa para https://oauth.SEU-DOMINIO/authorize.
  2. Ela entra com o GitHub, vê o nome do app, quem o fez e o que ele vai poder fazer, escolhe a empresa e autoriza. Só a dona ou um admin da empresa autoriza apps.
  3. A SuyPay volta para o endereço de retorno do app com um code.
  4. O app troca o code por um access_token (vale 1 hora) e um refresh_token.
  5. O app chama a API normalmente, com Authorization: Bearer suy_oat_....

Criar o app

Em Configuração → OAuth → Criar app, informe:

Campo O que é
Nome, descrição e site o que a loja vê na hora de autorizar
Endereços de retorno para onde a SuyPay volta depois da autorização. Precisa ser igual ao redirect_uri enviado, caractere por caractere. https://, ou http:// só para localhost
O que o app pode pedir as permissões abaixo
Onde o app roda Servidor (tem client_secret) ou Aparelho (app, extensão, CLI: sem segredo)
Webhook do app um endereço para receber os avisos de todas as empresas que autorizaram

Você recebe o client_id (app_...) e, no tipo Servidor, o client_secret (suy_cs_...), mostrado uma única vez. Dá para trocar o segredo depois.

Permissões

scope O app pode
charges criar cobranças (Pix, boleto, cartão), cancelar, simular no modo de teste e consultar só as cobranças que ele criou
payments.read ver todas as vendas e clientes da empresa
refunds devolver pagamentos

Nenhum app vê as chaves das contas conectadas, mexe em contas e regras, faz saques ou divide vendas com subcontas.

1. Mandar a pessoa autorizar

Gere um code_verifier aleatório (43 a 128 caracteres) e o code_challenge, que é o SHA-256 dele em base64url. O PKCE é obrigatório para todo app, mesmo os de servidor.

https://oauth.SEU-DOMINIO/authorize
  ?response_type=code
  &client_id=app_...
  &redirect_uri=https://meubot.com/suypay/callback
  &scope=charges
  &state=um-valor-aleatorio-seu
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Guarde o state e confira que ele volta igual: é o que impede alguém de colar um código de outra pessoa no seu app.

Na volta, a SuyPay chama o seu endereço com ?code=...&state=...&iss=https://oauth.SEU-DOMINIO. Se a pessoa cancelar, vem ?error=access_denied&state=....

2. Trocar o código pelo token

O código vale 2 minutos e funciona uma vez só. Se o mesmo código for usado de novo, a SuyPay entende que ele vazou e cancela os tokens que saíram dele.

curl https://api.suypay.com/oauth/token \
  -u "app_...:suy_cs_..." \
  -d grant_type=authorization_code \
  -d code=O_CODIGO \
  -d redirect_uri=https://meubot.com/suypay/callback \
  -d code_verifier=O_VERIFIER

Apps do tipo Aparelho mandam client_id no corpo em vez do -u.

{
  "access_token": "suy_oat_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "suy_ort_...",
  "scope": "charges",
  "modes": ["test", "live"],
  "organization": { "id": "org_...", "name": "Loja da Maria" }
}

Guarde o organization.id: é a empresa daquele token. Um app autorizado por várias empresas tem um par de tokens para cada uma.

3. Usar a API

curl https://api.suypay.com/v1/payments \
  -H "Authorization: Bearer suy_oat_..." \
  -H "SuyPay-Mode: live" \
  -H "Idempotency-Key: pedido-81723" \
  -H "Content-Type: application/json" \
  -d '{ "method": "pix", "amount": 2990, "customer": { "name": "Fulano" } }'

SuyPay-Mode escolhe entre dados reais (live) e de teste (test), dentro do que a empresa liberou (modes). Sem o cabeçalho, vale live quando a empresa liberou dados reais.

O mesmo token funciona no servidor MCP.

4. Renovar o token

curl https://api.suypay.com/oauth/token \
  -u "app_...:suy_cs_..." \
  -d grant_type=refresh_token \
  -d refresh_token=suy_ort_...

A resposta traz um access_token e um refresh_token novos; o anterior deixa de valer na hora. Se um refresh_token já usado aparecer de novo, a SuyPay entende que ele foi copiado e cancela todos os tokens daquela autorização: a empresa precisa autorizar de novo. Por isso, guarde sempre o último e renove um de cada vez.

O refresh_token vale 90 dias sem uso.

Revogar

Quando a loja desinstala o seu app, revogue:

curl https://api.suypay.com/oauth/revoke -u "app_...:suy_cs_..." -d token=suy_ort_...

A loja também tira o acesso em Configuração → OAuth. A partir daí, a API responde 401 para os tokens daquela empresa.

Webhook do app

Com o webhook do app cadastrado, cada empresa que autoriza passa a mandar os avisos para ele, assinados com o segredo do app (SuyPay-Signature, igual aos webhooks). Cada aviso diz de qual empresa é:

{
  "id": "evt_...",
  "object": "event",
  "type": "payment.succeeded",
  "organization": "org_...",
  "data": { "object": { "id": "pay_...", "status": "succeeded" } }
}

Com só charges, chegam apenas os avisos das cobranças que o app criou. Com payments.read, os de todas as vendas da empresa.

Erros

Onde error Quer dizer
retorno da autorização access_denied a pessoa cancelou
retorno da autorização invalid_scope o app pediu uma permissão que não tem cadastrada
retorno da autorização invalid_request faltou state ou PKCE (code_challenge com S256)
/oauth/token invalid_client client_id ou client_secret errado, ou app desativado
/oauth/token invalid_grant código vencido, já usado, de outro app, redirect_uri ou code_verifier diferente, ou refresh_token já usado
API 401 token vencido ou revogado: renove com o refresh_token
API 403 insufficient_scope o app não tem permissão para essa rota

Um client_id ou endereço de retorno errado não volta para o app: a página de autorização mostra o erro para a pessoa, para ninguém usar a SuyPay como desvio para outro site.

Descoberta automática

Clientes que leem os metadados do servidor de autorização (como alguns clientes MCP) encontram tudo em https://www.suypay.com/.well-known/oauth-authorization-server.