Skip to main content
O BulkRoute tem um app Shopify dedicado (não só uma integração via API) que roda embedded no admin da Shopify. O app:
  • Aparece como carrier service no checkout — o cliente vê as cotações do BulkRoute direto no checkout da Shopify
  • Cria shipments automaticamente quando o pedido é pago (webhook orders/paid)
  • Sincroniza tracking de volta para a Shopify (fulfillment + tracking number)
  • Recebe webhooks GDPR obrigatórios (customers/data_request, customers/redact, shop/redact)

Como funciona

O app vive no monorepo bulkroute-integrations/apps/shopify (repo separado do bulkroute), usa React Router 7 + @shopify/shopify-app-react-router + Prisma, e roda em Node na porta 3005 (shopify-app.bulkroute.com.br).

App embedded (iframe)

O app é embedded (embedded = true no shopify.app.toml). A Shopify carrega o app dentro de um <iframe> no admin da loja (admin.shopify.com/store/<loja>/apps/<app>). O AppProvider do @shopify/shopify-app-react-router injeta o App Bridge + Polaris Web Components (CDN) automaticamente. O app tem 3 telas no admin da Shopify:
  • Configuration — configurar API Key do BulkRoute (bk_live_...) e CEP de origem
  • Scheduling — configurar agendamento de coletas
  • Tracking Sync — disparar sync manual de tracking

Carrier Service (cotação no checkout)

O endpoint carrier.rates.tsx é chamado pela Shopify quando o cliente entra o CEP no checkout:
  1. Shopify envia rate request com itens, CEP de origem/destino
  2. App verifica HMAC (X-Shopify-Hmac-SHA256)
  3. Busca dimensões dos produtos via Admin API (metafields) para cubagem
  4. Converte para formato BulkRoute e chama POST /quotes
  5. Retorna rates no formato Shopify (código BULKROUTE_<carrier>)
O Carrier Service exige plano Shopify Advanced ou Plus. Em lojas com plano inferior, o carrier service não aparece no checkout — nesses casos, o lojista pode usar o app só para criação de shipments + tracking sync.

Criação automática de shipments

Quando um pedido é pago, a Shopify dispara o webhook orders/paid:
  1. App verifica se o shipping method começa com BULKROUTE_ (se não, ignora — não é pedido do BulkRoute)
  2. Verifica idempotência (se já processou, não recria)
  3. Converte o pedido Shopify para formato BulkRoute
  4. Busca metafields de agendamento (se o lojista configurou)
  5. Chama POST /orders no BulkRoute
  6. Salva o mapping shopify_order_id → bulkroute_shipment_id no Prisma

Sincronização de tracking

Primário: webhook

Quando o BulkRoute atualiza o status de um shipment, dispara webhook para o app Shopify (webhooks.bulkroute.tsx), que cria um fulfillment na Shopify com o tracking number.

Backup: cron de 15 minutos

O tracking-sync.ts roda a cada 15 minutos como backup — verifica shipments que não foram atualizados via webhook e sincroniza o status. Limite de 50 orders por shop por run, com throttle de 500ms entre chamadas.

Webhooks

Os webhooks são registrados via shopify.app.toml e auto-sincronizados no deploy:

Scopes

Pré-requisitos

  • Shopify: plano Advanced ou Plus (necessário para Carrier Services)
  • BulkRoute: conta ativa com API Key (bk_live_...)
  • Servidor: Node + PM2 + nginx + Cloudflare (DNS/HTTPS) — o app roda em shopify-app.bulkroute.com.br:3005

Endpoints da API BulkRoute (backend principal)

O app Shopify chama estes endpoints do backend BulkRoute: O backend BulkRoute também tem rotas de integração em /integrations/shopify (no server/) para gerenciar a conexão via painel admin — mas o app embedded é o que roda dentro da Shopify.

Troubleshooting