Pular para conteúdo

Quickstart 15 minutos

Neste guia voce vai:

  1. Obter um access token pelo seu app OAuth2
  2. Criar um produto completo (categoria, marca, atributos, variacao, preco, estoque e imagens) em uma unica chamada
  3. Poll da fila de pedidos criados
  4. Confirmar o pedido (ack)

Atalho: se voce so quer rodar os comandos, pule direto pro Passo 3. Os passos 1 e 2 sao preparacao.

0. Criar o app OAuth2

A API de integracao e acessada por um app OAuth2: o seller autoriza o seu app uma vez e voce recebe tokens proprios, sem guardar credencial de ninguem.

No painel da Gubee, em Integracoes → Meus apps, crie o app com as permissoes que este guia usa e cadastre a URI de redirecionamento (Criar e gerenciar apps):

Permissao Usada no passo
product:edit 3. Criar produto
order:view 4. Fila de pedidos
order:edit 5. Confirmar o pedido

Para ver os dados pessoais do comprador sem mascara, acrescente order:customer-data (Permissoes dos apps).

export GUBEE_API="https://api.gubee.com.br"
export GUBEE_CLIENT_ID="<client_id do app>"
export GUBEE_CLIENT_SECRET="<client_secret, guardado no cofre do seu sistema>"
export GUBEE_REDIRECT_URI="https://seusistema.com.br/gubee/callback"

API Token esta descontinuado

A troca de API Token por JWT em /integration/tokens/revalidate/apitoken e a forma legada e sera desligada. Integracao nova usa app OAuth2. Quem ja usa API Token deve migrar (Autenticacao por API Token).

1. Obter o access token

O fluxo e authorization code com PKCE. Resumo (passo a passo completo no Guia do desenvolvedor):

  1. Gere code_verifier, code_challenge (S256) e state, e guarde-os na sessao.
  2. Mande o seller para https://admin.gubee.com.br/#/oauth2/authorize?client_id=...&redirect_uri=...&response_type=code&code_challenge=...&code_challenge_method=S256&state=.... Ele aprova o acesso e volta na sua redirect_uri com code e state.
  3. Confira o state e troque o code por token, no seu back-end:
TOKENS=$(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=$(echo "$TOKENS" | jq -r '.access_token')
REFRESH_TOKEN=$(echo "$TOKENS" | jq -r '.refresh_token')

O access_token e curto: leia o expires_in da resposta, nao assuma uma duracao. Antes de vencer, renove com grant_type=refresh_token (Renovar o token). A conta sobre a qual o app age vem da autorizacao do seller, nunca do body.

2. (Opcional) Resolver SKU -> skuId

O endpoint /v2/createupdate aceita sku (seu proprio identificador) e nao exige skuId. Pule este passo se for criar produto novo.

So precisa resolver skuId se for chamar endpoints /v2/bySkuId/{skuId} (leitura V2) ou se for integrar com algum sistema que ja use o identificador interno da Gubee.

curl -s "$GUBEE_API/integration/skus/by-sku?sku=SKU-DEMO-001" \
  -H "Authorization: Bearer $ACCESS_TOKEN" | jq
{
  "sku": "SKU-DEMO-001",
  "skuId": "ABCD-1234-EFGH-5678"
}

Detalhes em SKU vs skuId.

3. Criar produto completo (createupdate)

Este passo faz tudo numa chamada. O endpoint POST /integration/products/v2/createupdate:

  • Cria ou atualiza o produto (idempotente pelo externalId)
  • Cria categoria em cascata se nao existir (envie o caminho com >)
  • Cria marca se nao existir
  • Cria atributos do produto (specifications) e da variacao (variantSpecification) se nao existirem
  • Salva preco, estoque e imagens da variacao na mesma transacao
  • Gera skuId automaticamente para variacoes novas
  • Retorna o productId (externalId) criado/atualizado
curl -s -X POST "$GUBEE_API/integration/products/v2/createupdate" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "PROD-DEMO-001",
    "name": "Tenis Runner Masculino",
    "mainCategory": "Esportes > Calcados > Tenis",
    "brand": "MarcaDemo",
    "originCountry": "BR",
    "type": "VARIANT",
    "specifications": [
      { "name": "Genero", "values": ["Masculino"] },
      { "name": "Indicado para", "values": ["Corrida"] }
    ],
    "variations": [
      {
        "sku": "SKU-DEMO-001",
        "name": "Tenis Runner Preto 42",
        "ean": "7891234567890",
        "eans": [
          { "value": "7891234567890", "main": true },
          { "value": "17891234567897", "main": false }
        ],
        "dimension": { "weight": 0.850, "height": 12, "width": 30, "length": 40 },
        "warrantyTime": 90,
        "handlingTime": 1,
        "cost": 80.00,
        "images": [
          { "url": "https://exemplo.com/img/tenis-preto-1.jpg", "main": true, "order": 0 },
          { "url": "https://exemplo.com/img/tenis-preto-2.jpg", "main": false, "order": 1 }
        ],
        "prices": [
          { "value": 199.90, "type": "DEFAULT" }
        ],
        "stocks": [
          { "warehouseId": "WAREHOUSE-DEFAULT", "qty": 50, "crossDockingTime": "P1D" }
        ],
        "variantSpecification": [
          { "name": "Cor", "values": ["Preto"] },
          { "name": "Tamanho", "values": ["42"] }
        ]
      },
      {
        "sku": "SKU-DEMO-002",
        "name": "Tenis Runner Azul 40",
        "ean": "7891234567891",
        "dimension": { "weight": 0.820, "height": 12, "width": 30, "length": 40 },
        "images": [
          { "url": "https://exemplo.com/img/tenis-azul-1.jpg", "main": true }
        ],
        "prices": [ { "value": 209.90, "type": "DEFAULT" } ],
        "stocks": [ { "warehouseId": "WAREHOUSE-DEFAULT", "qty": 20 } ],
        "variantSpecification": [
          { "name": "Cor", "values": ["Azul"] },
          { "name": "Tamanho", "values": ["40"] }
        ]
      }
    ]
  }' -w "\nHTTP %{http_code}\n"

Resposta (200 OK):

"PROD-DEMO-001"

O retorno e o externalId (productId) do produto criado/atualizado. Nesta unica chamada voce acabou de criar/atualizar:

Entidade Quantidade Observacao
Categoria (Esportes > Calcados > Tenis) 3 Criadas em cascata se nao existiam
Marca (MarcaDemo) 1 Criada se nao existia
Atributo (Genero, Indicado para) 2 Especificacoes do produto
Atributo variante (Cor, Tamanho) 2 Atributos de variacao
Produto 1 ExternalId PROD-DEMO-001, tipo VARIANT
Variacoes (SKUs) 2 SKU-DEMO-001 e SKU-DEMO-002
Preco por SKU 2 199.90 e 209.90
Estoque por SKU 2 50 e 20 unidades no WAREHOUSE-DEFAULT
Imagens 3 Anexadas as variacoes corretas

Consistencia eventual: apos receber 200, o produto fica visivel para GET imediatamente, mas preco e estoque sao propagados via plataforma de streaming de eventos e podem levar 1-5s para refletir no GET /integration/prices/{platform}/{itemId}. Veja CQRS e consistencia eventual.

EAN: a variacao aceita uma lista em eans (itens { "value", "main" }, ate 20, exatamente um main: true). O campo ean continua aceito e esta depreciado, sem data de remocao: quem envia so ean grava esse valor como EAN principal, e a leitura devolve o principal em ean. Ao enviar eans, envie tambem ean com o valor do item principal, como no exemplo: a gravacao da lista e habilitada por ambiente e, enquanto nao estiver, um payload so com eans nao grava os EANs enviados. Regras completas, erros e o que acontece quando os dois campos divergem em Sincronizar Catalogo.

Campos obrigatorios minimos

Para o menor payload possivel (produto SIMPLES sem variacao):

{
  "externalId": "PROD-X",
  "name": "Produto X",
  "mainCategory": "Categoria > Subcategoria",
  "brand": "Marca",
  "variations": [
    {
      "sku": "SKU-X",
      "prices": [{ "value": 99.90, "type": "DEFAULT" }],
      "stocks": [{ "warehouseId": "CD-1", "qty": 10 }]
    }
  ]
}

Demais campos sao opcionais e tem defaults (type=SIMPLE, origin=NATIONAL, status=ACTIVE).

4. Poll da fila de pedidos criados

Para receber pedidos, faca polling periodico da fila created:

curl -s -X GET "$GUBEE_API/integration/orders/queue/created?page=0&size=20" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/hal+json" | jq '._embedded.orderApiDTOList | length'

Resposta (exemplo com 1 pedido):

1

Um pedido individual tem o formato:

{
  "orderId": "ORD-2024-0001",
  "sellerId": "SELLER123",
  "platform": "MERCADOLIVRE",
  "status": "CREATED",
  "createdDt": "2024-06-01T12:34:56Z",
  "items": [
    {
      "sku": "SKU-DEMO-001",
      "skuId": "ABCD-1234-EFGH-5678",
      "qty": 1,
      "price": 199.90
    }
  ],
  "customer": { "name": "Joao da Silva", "email": "joao@example.com" },
  "shipping": { "postalCode": "01310100" }
}

O pedido fica na fila ate que voce confirme via DELETE no passo 5. Se voce nao confirmar, ele continuara sendo retornado a cada polling. Nao faca busy-polling — 15-60s de intervalo e suficiente. Detalhes em Receber Pedidos.

5. Confirmar o pedido (ack)

Apos processar o pedido no seu ERP, remova-o da fila:

curl -s -X DELETE "$GUBEE_API/integration/orders/queue/created/ORD-2024-0001" \
  -H "Authorization: Bearer $ACCESS_TOKEN" -w "\nHTTP %{http_code}\n"

Resposta:

HTTP 200

A partir daqui o pedido entra no ciclo de vida normal (PAID -> INVOICED -> SHIPPED -> DELIVERED). Cada transicao gera nova entrada na fila correspondente (/integration/orders/queue/paid, /invoiced, etc.), ou voce pode assinar webhooks para receber push.

Resumo do fluxo

[app OAuth2 + token] -> [criar produto COMPLETO] -> [fila pedidos] -> [ack]
   1             3                          4             5

3 chamadas autenticadas. Sem necessidade de criar categoria, marca ou atributo antes — o /v2/createupdate resolve tudo internamente.

Quando NAO usar o createupdate

O /v2/createupdate e otimo para 95% dos casos. Use os endpoints especificos quando:

  • Atualizar apenas preco de 1 SKU sem tocar no resto do produto: PUT /integration/prices/bysku (mais rapido, menos payload).
  • Atualizar apenas estoque: PUT /integration/stocks/bysku.
  • Editar parcialmente 1 variacao (cost, ean, eans, dimension, name, images): PATCH /integration/products/variations/sku/{sku}.
  • Sincronizar catalogo em massa (10k+ produtos): prefira os endpoints /integration/categories/bulk + /integration/brands + loop de createupdate, para reutilizar categorias ja criadas (reduz trabalho do backend). Veja Sincronizar Catalogo.

Proximos passos