- 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
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 endpointcarrier.rates.tsx é chamado pela Shopify quando o cliente entra o CEP no checkout:
- Shopify envia rate request com itens, CEP de origem/destino
- App verifica HMAC (
X-Shopify-Hmac-SHA256) - Busca dimensões dos produtos via Admin API (metafields) para cubagem
- Converte para formato BulkRoute e chama
POST /quotes - 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 webhookorders/paid:
- App verifica se o shipping method começa com
BULKROUTE_(se não, ignora — não é pedido do BulkRoute) - Verifica idempotência (se já processou, não recria)
- Converte o pedido Shopify para formato BulkRoute
- Busca metafields de agendamento (se o lojista configurou)
- Chama
POST /ordersno BulkRoute - Salva o mapping
shopify_order_id → bulkroute_shipment_idno 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
Otracking-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 viashopify.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.