Pular para conteúdo

Configurar Webhooks pela API

A configuração de webhooks do seller (o que assinar e para onde enviar) pode ser feita pelo painel (Minha Conta → Notificações de Eventos) ou pela API de integração, em /integration/hookconfigurations. As duas formas gravam a mesma configuração: o que você salva por API aparece no painel, e vice-versa.

Método Caminho Para quê Permissão
GET /integration/hookconfigurations/options Lista os domínios e as tags que podem ser assinados notification:view
GET /integration/hookconfigurations Lê a configuração atual notification:view
PUT /integration/hookconfigurations Substitui a configuração inteira notification:edit
PUT /integration/hookconfigurations/endpoints/{endpointId} Cadastra ou troca a URL de um endpoint notification:edit
DELETE /integration/hookconfigurations/endpoints/{endpointId} Remove um endpoint notification:edit

O seller é sempre o do token: nenhum desses caminhos aceita sellerId. As permissões são as de Permissões dos Apps.

Como a entrega decide o que enviar

Um evento chega no seu endpoint quando as três condições valem:

  1. enable é true;
  2. o domínio do evento está em enabledDomains;
  3. se o evento tem tags, ao menos uma delas está em enabledTags.

A terceira regra é a que mais confunde. Eventos de pedido (ORDER) e de etiqueta (TAG) sempre têm tags. Assinar o domínio ORDER sem nenhuma tag order_* ou tracking_* não entrega nada. Produto, estoque, preço e status da conta não têm tags: basta o domínio.

Todos os endpoints cadastrados recebem todos os eventos assinados; a assinatura é por seller, não por endpoint.

1. Consultar as opções

curl -sS -H "Authorization: Bearer $TOKEN" \
  "https://api.gubee.com.br/integration/hookconfigurations/options"
{
  "domains": [
    { "value": "ORDER", "name": "Pedidos", "description": "Mudanca de status do pedido e eventos de rastreio. Assine as tags order_* e/ou tracking_* desejadas", "requiresTags": true },
    { "value": "PRODUCT", "name": "Produtos", "description": "Variacao criada ou atualizada", "requiresTags": false },
    { "value": "STOCK", "name": "Estoque", "description": "Estoque alterado", "requiresTags": false },
    { "value": "PRICE", "name": "Preco", "description": "Preco alterado", "requiresTags": false },
    { "value": "TAG", "name": "Etiquetas", "description": "Fim do processamento de um grupo de etiquetas. Assine as tags tag_* desejadas", "requiresTags": true },
    { "value": "ACCOUNT", "name": "Status da conta", "description": "Conta congelada, descongelada ou cancelada", "requiresTags": false }
  ],
  "tags": [
    { "value": "order_invoiced", "domain": "ORDER", "group": "ORDER_STATUS", "name": "Faturado" },
    { "value": "tracking_delivered", "domain": "ORDER", "group": "TRACKING_STATUS", "name": "Entregue" },
    { "value": "tag_error", "domain": "TAG", "group": "LABEL", "name": "Erro ao gerar etiquetas" }
  ]
}

A resposta acima está resumida. A lista completa hoje é:

Grupo Domínio Tags
ORDER_STATUS: status do pedido ORDER order_created, order_payed, order_invoiced, order_shipped, order_delivered, order_concluded, order_returned, order_canceled, order_shipment_exception
TRACKING_STATUS: rastreio da entrega ORDER tracking_created, tracking_label_created, tracking_label_issue, tracking_carrier_registered, tracking_ready_for_shipping, tracking_shipped, tracking_in_transit, tracking_out_for_delivery, tracking_ready_for_pickup, tracking_delivered, tracking_delivery_attempt_failed, tracking_delivery_failed, tracking_address_issue, tracking_canceled
LABEL: resultado do grupo de etiquetas TAG tag_complete, tag_partially_complete, tag_error

Monte a sua tela ou configuração a partir do options, não desta tabela: quando a Gubee passar a emitir um status novo, ele aparece primeiro ali.

2. Gravar a configuração inteira

PUT /integration/hookconfigurations substitui tudo de uma vez: enable, enabledDomains, enabledTags e endpoints.

curl -sS -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://api.gubee.com.br/integration/hookconfigurations" \
  -d '{
    "enable": true,
    "enabledDomains": ["ORDER", "STOCK"],
    "enabledTags": ["order_invoiced", "order_shipped", "order_delivered", "order_canceled"],
    "endpoints": [
      { "id": "erp-prod", "url": "https://erp.example.com/gubee/webhook", "platform": "ERP" }
    ]
  }'

A resposta 200 devolve a configuração gravada, no mesmo formato do GET.

Campo Regra
enable Ausente vale true. Com false nada é entregue, mas a configuração fica guardada.
enabledDomains Valores de options.domains. Ausente vale lista vazia.
enabledTags Valores de options.tags. Cada tag exige o domínio dela em enabledDomains. Ausente vale lista vazia.
endpoints Lista completa. Endpoint que não vier na lista é removido. Ausente remove todos.
endpoints[].id Nome do endpoint (urlName): letras, números, - e _, até 64 caracteres, único na lista.
endpoints[].url URL https com nome de host público. Veja Regras da URL.
endpoints[].platform Rótulo livre e opcional. Não filtra eventos.

PUT substitui, não mescla

Para mudar só um item, faça GET, altere o corpo e devolva no PUT. Valores que já estavam gravados (inclusive os que foram salvos pelo painel e a API não aceitaria hoje, como uma URL http) voltam sem erro; só o que você mudou é validado. Para mexer em uma URL sem tocar no resto, use os caminhos de endpoint abaixo.

3. Cadastrar ou trocar a URL de um endpoint

PUT /integration/hookconfigurations/endpoints/{endpointId} grava a URL do endpoint {endpointId} e mantém os outros endpoints, os domínios, as tags e o enable como estão. Se o endpoint não existe, ele é criado.

curl -sS -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://api.gubee.com.br/integration/hookconfigurations/endpoints/erp-prod" \
  -d '{ "url": "https://erp.example.com/gubee/webhook", "platform": "ERP" }'

Responde 200 com a configuração gravada.

Seller que nunca configurou começa desligado

Sem configuração gravada, o GET devolve enable: false e listas vazias (nunca 404). Este caminho não muda o enable: num seller novo, depois de cadastrar a URL, grave os domínios, as tags e "enable": true pelo PUT /integration/hookconfigurations.

Para remover:

curl -sS -X DELETE -H "Authorization: Bearer $TOKEN" \
  "https://api.gubee.com.br/integration/hookconfigurations/endpoints/erp-prod"

Responde 204, ou 404 se não existe endpoint com esse id.

Regras da URL

A URL decide para onde vão os dados de pedido do seller, então a API só aceita endereços públicos:

  • esquema https;
  • nome de host, não IP (https://203.0.113.10/... é recusado);
  • nada de localhost nem de host interno (sem ponto, ou terminado em .local, .internal, .lan, .svc, .cluster.local);
  • sem usuário e senha na URL. Se o seu endpoint precisa de um segredo, use um caminho ou parâmetro difícil de adivinhar (https://erp.example.com/gubee/webhook/7f3c...) e confira no seu lado.

O endpoint precisa responder 2xx em até 5 segundos. O que acontece quando ele não responde está em Política de Retry.

Erros

Validação que falha responde 400 com todas as violações no title, separadas por ;. Nada é gravado.

{
  "title": "Tag [tag_error] requires domain [TAG] in enabledDomains; Endpoint url [http://erp.example.com/hook] must use https",
  "status": 400,
  "message": "error.webhook.invalid",
  "params": "hookConfiguration"
}
Mensagem Causa
Domain [X] is not available Domínio fora de options.domains
Tag [x] is not available Tag fora de options.tags
Tag [x] requires domain [D] in enabledDomains Tag assinada sem o domínio dela. Ela nunca entregaria nada.
Endpoint id [x] must match ... Id vazio, com espaço, acento ou mais de 64 caracteres
Endpoint id [x] is duplicated Dois endpoints com o mesmo id no PUT
Endpoint url [...] must use https / must use a host name, not an IP address / must be a public host / must not contain credentials Veja Regras da URL

O id do endpoint e as notificações perdidas

O id que você escolhe é o {urlName} de GET /integration/notifications/missed/{urlName}: é por ele que você recupera o que não conseguiu receber. Use um nome estável (erp-prod, erp-homolog) e não o troque a cada deploy. Veja Política de Retry.

Próximos passos