Pular para conteúdo

Status da conta

Parceiros que cobram ou administram sellers na Gubee (ERPs, hubs, revendas) podem congelar, descongelar e cancelar a conta de um seller vinculado ao seu app OAuth2, sempre informando o motivo e quem pediu a mudança do seu lado. Toda mudança fica na trilha de auditoria da Gubee e é avisada por webhook.

Recurso Quando
POST /integration/accounts/{sellerId}/status-changes Congelar a conta por inadimplência, descongelar quando o seller regularizar, cancelar no fim do contrato
GET /integration/accounts/{sellerId}/status Conferir o status atual, as travas da conta e o histórico das mudanças feitas pelo seu app
Webhook ACCOUNT_STATUS_CHANGED Saber quando o status da conta mudou, inclusive por ação da Gubee ou de outro parceiro

Os três status

Status O que significa
ACTIVE Conta funcionando normalmente
FROZEN Conta congelada: existe ao menos uma trava reversível. Integrações e canais param e o seller não entra no painel
CANCELED Conta cancelada. Só a Gubee reverte, dentro do prazo de retenção

Travas

O status é consequência das travas que a conta tem. Cada trava tem um dono:

Trava (type) Quem põe Quem tira
PARTNER_FREEZE Um app parceiro, com FREEZE Só o mesmo app, com UNFREEZE
GUBEE_SUSPENSION A Gubee (suspensão) Só a Gubee
CANCELED Um app parceiro, com CANCEL, ou a Gubee Só a Gubee, dentro do prazo de retenção
  • A conta fica FROZEN enquanto houver qualquer trava reversível: a do seu app, a de outro parceiro ou uma suspensão da Gubee.
  • CANCELED prevalece sobre as demais travas.
  • Cada parceiro congela de forma independente. Se dois apps congelaram a mesma conta, o UNFREEZE de um tira só a trava dele: a conta continua FROZEN até o outro também descongelar.
  • Uma conta desativada antes desta API pode aparecer como FROZEN sem nenhuma trava.

Quem pode o quê

Ação Permissão O que faz
FREEZE account:freeze Põe uma trava do seu app na conta. A conta fica FROZEN
UNFREEZE account:freeze Tira a trava do seu app. A conta só volta a ACTIVE se não houver outra trava
CANCEL account:cancel Cancela a conta (CANCELED)
Consultar status account:status:view Lê status, travas e o histórico do seu app

O que um parceiro não pode fazer:

  • tirar a trava de outro parceiro;
  • tirar uma suspensão da Gubee (GUBEE_SUSPENSION);
  • reverter um cancelamento. Depois de CANCEL, toda ação do parceiro na conta recebe 409. Só a Gubee reverte, dentro de 90 dias.

Cancelar é definitivo para o parceiro

Use CANCEL só no fim do contrato. Para interromper a conta temporariamente (inadimplência, pedido do seller), use FREEZE.

Pré-requisitos

  1. Permissões aprovadas pela Gubee. account:status:view, account:freeze e account:cancel não ficam disponíveis a todo app: peça a liberação ao seu contato comercial na Gubee. Depois de aprovado, o app passa a ter uma service account e pode obter token com client_credentials.
  2. Vínculo com o seller. O seller precisa ter autorizado o seu app com as permissões da ação (fluxo do Guia do desenvolvedor). É essa autorização que cria o vínculo entre o app e o seller. Sem ela, nenhuma chamada sobre aquele seller passa.
  3. O sellerId do caminho tem de ser um seller vinculado. Um app nunca age sobre um seller que não o autorizou: a resposta é 403.

Acrescentar as permissões a um app já publicado

Alterar as permissões de um app revoga na hora a autorização de todos os sellers conectados. Cada um precisa autorizar o app de novo. Detalhes em Permissões dos apps.

Obter o token (client_credentials)

As chamadas de status da conta são de servidor para servidor. Use o fluxo client_credentials com o client_id e o client_secret do app:

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=client_credentials" \
  -d "client_id=$GUBEE_CLIENT_ID" \
  -d "client_secret=$GUBEE_CLIENT_SECRET"
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "expires_in": 300,
  "token_type": "Bearer"
}
  • O token não traz refresh_token: peça um novo quando estiver perto de vencer. O expires_in vem em segundos e não é fixo; leia sempre o da resposta.
  • O mesmo token serve para todos os sellers vinculados ao app. O seller da chamada é o sellerId do caminho, conferido contra os vínculos do app.
  • O client_secret nunca sai do seu back-end.

Os exemplos abaixo usam:

export GUBEE_API="https://api.gubee.com.br"
export JWT="<access_token do client_credentials>"
export SELLER_ID="<sellerId vinculado ao app>"

Mudar o status

POST /integration/accounts/{sellerId}/status-changes

Headers

Header Obrigatório Descrição
Authorization sim Bearer <access_token>
Content-Type sim application/json
Idempotency-Key sim Chave única do pedido, até 255 caracteres (ex.: um UUID). Veja Idempotência
X-Correlation-Id não Identificador de correlação do seu lado (letras, números e ._:-, até 100 caracteres). Sem ele, a Gubee gera um

Corpo

Campo Tipo Obrigatório Descrição
action string sim FREEZE, UNFREEZE ou CANCEL
reasonCode string sim Motivo padronizado. Veja reasonCodes
reason string só com OTHER Motivo em texto livre, até 500 caracteres
requestedBy.name string sim Nome de quem, do seu lado, pediu a mudança (até 200 caracteres)
requestedBy.email string sim E-mail dessa pessoa (até 254 caracteres)
requestedBy.externalId string não Id dessa pessoa no seu sistema (até 100 caracteres)

requestedBy

requestedBy identifica o operador do seu lado: a pessoa que mandou congelar ou cancelar. Ele fica na trilha de auditoria da Gubee junto com o app que fez a chamada (o clientId vem do token, nunca do corpo). Se a mudança for automática, informe o responsável pela regra automática ou uma caixa de e-mail do time.

reasonCodes

reasonCode Quando usar
PAYMENT_OVERDUE Inadimplência do seller com o parceiro
MERCHANT_REQUEST Pedido do próprio seller
CONTRACT_ENDED Fim do contrato entre o seller e o parceiro
FRAUD_SUSPECTED Suspeita de fraude
MIGRATION Migração de conta ou de plataforma
OTHER Outro motivo. Exige reason

Congelar (FREEZE)

curl -s -X POST "$GUBEE_API/integration/accounts/$SELLER_ID/status-changes" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c9a52-7d0e-4b8a-9f61-2c4d5e6f7a80" \
  -d '{
    "action": "FREEZE",
    "reasonCode": "PAYMENT_OVERDUE",
    "reason": "Fatura de setembro em aberto",
    "requestedBy": {
      "name": "Ana Operadora",
      "email": "ana@parceiro.com",
      "externalId": "op-7"
    }
  }'

Resposta 202 Accepted:

{
  "sellerId": "seller-1",
  "previousStatus": "ACTIVE",
  "status": "FROZEN",
  "locks": [
    {
      "type": "PARTNER_FREEZE",
      "mine": true,
      "clientId": "partner-erp-x",
      "reasonCode": "PAYMENT_OVERDUE",
      "reason": "Fatura de setembro em aberto",
      "requestedBy": "ana@parceiro.com",
      "at": "2026-10-15T10:30:00"
    }
  ],
  "change": {
    "action": "FREEZE",
    "reasonCode": "PAYMENT_OVERDUE",
    "reason": "Fatura de setembro em aberto",
    "requestedBy": {
      "name": "Ana Operadora",
      "email": "ana@parceiro.com",
      "externalId": "op-7"
    },
    "at": "2026-10-15T10:30:00"
  },
  "replayed": false
}

Headers da resposta: Idempotent-Replayed (true ou false) e X-Correlation-Id (informe ao suporte da Gubee).

Descongelar (UNFREEZE)

curl -s -X POST "$GUBEE_API/integration/accounts/$SELLER_ID/status-changes" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8b2e4d61-1a3f-4c5b-a7d9-0e1f2a3b4c5d" \
  -d '{
    "action": "UNFREEZE",
    "reasonCode": "PAYMENT_OVERDUE",
    "reason": "Fatura de setembro quitada",
    "requestedBy": {
      "name": "Ana Operadora",
      "email": "ana@parceiro.com"
    }
  }'

O UNFREEZE tira só a trava do seu app. Confira o status da resposta: se ainda vier FROZEN, a conta tem outra trava (de outro parceiro ou da Gubee), listada em locks com mine: false.

{
  "sellerId": "seller-1",
  "previousStatus": "FROZEN",
  "status": "FROZEN",
  "locks": [
    { "type": "GUBEE_SUSPENSION", "mine": false, "at": "2026-10-10T08:00:00" }
  ],
  "change": {
    "action": "UNFREEZE",
    "reasonCode": "PAYMENT_OVERDUE",
    "reason": "Fatura de setembro quitada",
    "requestedBy": { "name": "Ana Operadora", "email": "ana@parceiro.com" },
    "at": "2026-10-20T09:12:00"
  },
  "replayed": false
}

Cancelar (CANCEL)

curl -s -X POST "$GUBEE_API/integration/accounts/$SELLER_ID/status-changes" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: c4d5e6f7-0a1b-4c2d-8e3f-4a5b6c7d8e9f" \
  -d '{
    "action": "CANCEL",
    "reasonCode": "CONTRACT_ENDED",
    "requestedBy": {
      "name": "Carlos Financeiro",
      "email": "carlos@parceiro.com"
    }
  }'

A resposta vem com "status": "CANCELED" e a trava CANCELED em locks. A partir daí, qualquer FREEZE, UNFREEZE ou CANCEL do parceiro nesta conta recebe 409.

Resposta da mudança

Campo Descrição
sellerId O seller do caminho
previousStatus Status antes do pedido. Ausente num replay
status Status depois do pedido: ACTIVE, FROZEN ou CANCELED
locks Travas da conta depois do pedido. Veja Privacidade das travas
change A mudança aplicada (num replay, a do pedido original)
replayed true quando a resposta é o replay de um pedido anterior com a mesma Idempotency-Key

Datas (at) vêm em ISO 8601 sem fuso, no horário de Brasília (America/Sao_Paulo).

Consultar o status

GET /integration/accounts/{sellerId}/status — exige account:status:view.

curl -s "$GUBEE_API/integration/accounts/$SELLER_ID/status" \
  -H "Authorization: Bearer $JWT"
{
  "sellerId": "seller-1",
  "status": "FROZEN",
  "locks": [
    {
      "type": "PARTNER_FREEZE",
      "mine": true,
      "clientId": "partner-erp-x",
      "reasonCode": "PAYMENT_OVERDUE",
      "reason": "Fatura de setembro em aberto",
      "requestedBy": "ana@parceiro.com",
      "at": "2026-10-15T10:30:00"
    },
    { "type": "GUBEE_SUSPENSION", "mine": false, "at": "2026-10-10T08:00:00" }
  ],
  "history": [
    {
      "action": "FREEZE",
      "reasonCode": "PAYMENT_OVERDUE",
      "reason": "Fatura de setembro em aberto",
      "requestedBy": { "name": "Ana Operadora", "email": "ana@parceiro.com" },
      "at": "2026-10-15T10:30:00"
    }
  ]
}

Privacidade das travas e do histórico

  • Travas do seu app (mine: true) vêm completas: clientId, reasonCode, reason, requestedBy (e-mail) e at.
  • Qualquer outra trava (de outro parceiro, a suspensão da Gubee, o cancelamento) vem só com type, mine: false e at. Você sabe que ela existe (e por que o seu UNFREEZE não reativou a conta), mas não quem a pôs nem o motivo.
  • history traz só as mudanças feitas pelo seu app, entre as 20 mais recentes da conta, da mais recente para a mais antiga.
  • type pode ganhar valores novos: trate um valor desconhecido sem falhar.

Idempotência

O header Idempotency-Key é obrigatório no POST. A chave vale por app: duas chamadas do seu app com a mesma chave são o mesmo pedido.

Situação Resposta
Chave nova A mudança é aplicada: 202, replayed: false
Mesma chave, mesmo corpo Replay: 202 com o resultado original, replayed: true e header Idempotent-Replayed: true. Nada é reaplicado e não conta no limite por hora
Mesma chave, corpo diferente 422 (idempotencyConflict)

Gere uma chave nova (um UUID) para cada mudança que você quer fazer e reuse a mesma chave nas retentativas dessa mudança (timeout, 503, queda de conexão). Assim uma retentativa nunca congela ou cancela duas vezes.

Limite de requisições

Cada app pode fazer 20 mudanças de status por hora, somando todos os sellers. Acima disso a resposta é 429 com o header Retry-After (segundos até poder tentar de novo). Replays não contam no limite. O GET de status segue os limites das demais rotas /integration/*.

Erros

Os erros seguem o formato Problem (RFC 7807). O identificador do erro (errorKey) vem no campo message, prefixado por error.:

{
  "title": "Too many account status changes; retry later",
  "status": 429,
  "message": "error.rateLimitExceeded",
  "params": "accountStatus",
  "retryAfterSeconds": 1260,
  "limit": 20
}

O corpo pode trazer outros campos; ignore os que não conhecer.

HTTP errorKey Quando O que fazer
400 invalidStatusCommand Idempotency-Key ausente ou longa demais, action ou reasonCode ausente, OTHER sem reason, reason com mais de 500 caracteres, requestedBy ausente ou incompleto. O title lista todos os problemas Corrija o pedido; não repita igual
401 — Token ausente, malformado ou expirado Obtenha um novo token
403 — O token não tem a permissão da ação (account:freeze, account:cancel ou account:status:view). O corpo traz required_scope Confira a permissão aprovada no app e a autorização do seller
403 sellerNotAuthorized O sellerId do caminho não é um seller vinculado ao app Confira o sellerId; peça ao seller que autorize o app
403 accountStatusActionForbidden Ação não permitida a parceiros Não repita: a ação é exclusiva da Gubee
404 accountNotFound Conta não encontrada Confira o sellerId
409 accountStatusConflict Transição inválida no estado atual: conta já congelada pelo seu app, UNFREEZE sem trava do seu app, conta cancelada, ou mudança concorrente na mesma conta Consulte o status (GET) e decida; numa mudança concorrente, tente de novo
422 idempotencyConflict Idempotency-Key já usada pelo seu app com outro corpo Use uma chave nova para um pedido diferente
429 rateLimitExceeded Mais de 20 mudanças na última hora Espere os segundos de Retry-After
503 accountStatusUnavailable Serviço de contas indisponível Tente de novo mais tarde, com a mesma Idempotency-Key e espera crescente

Efeitos na conta do seller

FROZEN CANCELED
Login do seller no painel Bloqueado Bloqueado
Integrações e canais Param Param
Webhooks do seller Pausados (não apagados); o aviso ACCOUNT_STATUS_CHANGED ainda é entregue Pausados
Cobrança da Gubee Continua normalmente Para na data do cancelamento; o mês do cancelamento é cobrado cheio (sem proporcional)
Volta atrás UNFREEZE do mesmo app (ou a Gubee, no caso da suspensão) Só a Gubee, em até 90 dias
  • Ao descongelar, integrações e webhooks voltam com a configuração que tinham antes do congelamento. Nada é perdido.
  • Depois do cancelamento, os dados da conta ficam retidos por 90 dias, prazo em que a equipe da Gubee pode reverter o cancelamento a pedido. O parceiro não reverte.

Webhook ACCOUNT_STATUS_CHANGED

A cada mudança de status da conta (pelo seu app, por outro parceiro ou pela Gubee) a Gubee envia um webhook do domínio ACCOUNT com type ACCOUNT_STATUS_CHANGED. Para recebê-lo, habilite o domínio ACCOUNT na configuração de webhook do seller (veja Eventos).

Diferente dos demais domínios, este evento não tem recurso para consultar: os dados vêm no próprio payload, no campo data.

{
  "resource": "",
  "itemId": "seller-1",
  "sellerId": "seller-1",
  "domain": "ACCOUNT",
  "type": "ACCOUNT_STATUS_CHANGED",
  "attempts": 1,
  "sent": "2026-10-15T13:30:01.120000Z",
  "received": "2026-10-15T13:30:00.845000Z",
  "data": {
    "sellerId": "seller-1",
    "status": "FROZEN",
    "previousStatus": "ACTIVE",
    "action": "FREEZE",
    "reasonCode": "PAYMENT_OVERDUE",
    "actor": { "type": "PARTNER_APP" },
    "effectiveAt": "2026-10-15T10:30:00"
  }
}
Campo de data Descrição
sellerId Seller da conta
status Status depois da mudança: ACTIVE, FROZEN ou CANCELED
previousStatus Status antes da mudança
action FREEZE, UNFREEZE, CANCEL, ou uma ação da Gubee: SUSPEND, UNSUSPEND, REVERT_CANCEL
reasonCode Motivo padronizado
actor.type Quem mudou: PARTNER_APP (algum parceiro), STAFF (equipe Gubee) ou SYSTEM
effectiveAt Quando a mudança valeu (ISO 8601 sem fuso, horário de Brasília)
  • O payload não traz dados pessoais nem o clientId do parceiro: um actor.type PARTNER_APP pode ser outro app. Para saber se a mudança foi sua, compare com o seu histórico (GET .../status).
  • Um UNFREEZE que não reativa a conta também gera o evento, com status e previousStatus FROZEN.
  • O aviso de congelamento é entregue mesmo com os webhooks do seller pausados.
  • A entrega é at-least-once: o mesmo evento pode chegar mais de uma vez. Deduplique por data.status + data.effectiveAt (veja Idempotência de webhooks).
  • action, reasonCode e actor.type podem ganhar valores novos: trate um valor desconhecido sem falhar.

Boas práticas

  • Congele, não cancele, quando houver chance de o seller voltar.
  • Uma Idempotency-Key por intenção, reusada em toda retentativa da mesma mudança.
  • Leia o status da resposta depois de UNFREEZE: a conta pode continuar FROZEN por outra trava.
  • Trate 409 consultando o status antes de repetir.
  • Respeite o Retry-After no 429, em vez de repetir em laço.
  • Guarde o X-Correlation-Id da resposta: é o que o suporte da Gubee pede para rastrear um pedido.