Pular para conteúdo

SHOPIFY ORDER FULFILL - Marcar Pedido como Enviado

O que é este Node?

O SHOPIFY ORDER FULFILL é o node responsável por marcar pedidos como enviados (fulfilled) no Shopify, registrando código de rastreamento e notificando o cliente.

Por que este Node existe?

Registrar envios é essencial para logística e atendimento. O SHOPIFY ORDER FULFILL existe para:

  1. Rastreamento: Registrar código de rastreamento para cliente acompanhar
  2. Notificação: Enviar email automático informando envio
  3. Status: Atualizar status do pedido para "enviado"
  4. Integração: Sincronizar envios com transportadoras
  5. Gestão: Controlar pedidos pendentes de envio

Como funciona internamente?

Quando o SHOPIFY ORDER FULFILL é executado, o sistema:

  1. Valida credenciais e orderId
  2. Prepara dados de fulfillment (tracking, transportadora)
  3. Envia requisição POST para /admin/api/{version}/orders/{orderId}/fulfillments.json
  4. Shopify marca como enviado e notifica cliente
  5. Retorna fulfillment criado com ID e dados
  6. Salva resultado na variável especificada
  7. Continua flow para próximo node

Código interno (shopify.executor.ts:78-83):

case 'fulfill': {
  const orderId = this.replaceVariables(node.data.orderId, context.variables);
  const fulfillment = JSON.parse(this.replaceVariables(JSON.stringify(node.data.fulfillment), context.variables));
  const response = await axios.post(`${baseUrl}/orders/${orderId}/fulfillments.json`, { fulfillment }, { headers });
  result = response.data;
  break;
}

Quando você DEVE usar este Node?

Use SHOPIFY ORDER FULFILL quando precisar marcar pedidos como enviados:

Casos de uso:

  1. Envio registrado: "Registrar código de rastreamento dos Correios"
  2. Integração transportadora: "Atualizar status quando transportadora coleta"
  3. Notificar cliente: "Informar que pedido foi despachado"
  4. Gestão logística: "Marcar pedidos separados como enviados"
  5. Atualização manual: "Registrar envio feito manualmente"

Quando NÃO usar:

  • Pedido não pago: Verifique financial_status antes de enviar
  • Sem estoque: Não marque como enviado se não enviou
  • Cancelado: Não fulfille pedidos cancelados

Parâmetros

Campo Tipo Obrigatório Descrição
config.shopName string Sim Nome da loja (sem .myshopify.com)
config.accessToken string Sim Token de acesso da API
config.apiVersion string Não Versão da API (padrão: 2025-01)
orderId string/number Sim ID do pedido a marcar como enviado
fulfillment object Sim Dados do envio (tracking, company)
fulfillment.tracking_number string Não Código de rastreamento
fulfillment.tracking_company string Não Nome da transportadora
fulfillment.tracking_url string Não URL de rastreamento
fulfillment.notify_customer boolean Não Enviar email ao cliente (padrão: true)
responseVariable string Não Nome da variável (padrão: shopifyResult)

Exemplo 1: Marcar como Enviado com Rastreamento

Objetivo: Registrar envio com código de rastreamento dos Correios.

JSON para Importar

{
  "name": "Shopify - Registrar Envio",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Número Pedido",
        "parameters": {
          "message": "Digite o número do pedido:",
          "variable": "orderId"
        }
      }
    },
    {
      "id": "shopify_1",
      "type": "shopify",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Buscar Pedido",
        "operation": "get",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "orderId": "{{orderId}}",
        "responseVariable": "order"
      }
    },
    {
      "id": "input_2",
      "type": "input",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Código Rastreamento",
        "parameters": {
          "message": "Pedido #{{order.order.order_number}}\nCliente: {{order.order.customer.first_name}}\n\nDigite o código de rastreamento:",
          "variable": "trackingCode"
        }
      }
    },
    {
      "id": "shopify_2",
      "type": "shopify",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Marcar Enviado",
        "operation": "fulfill",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "orderId": "{{orderId}}",
        "fulfillment": {
          "tracking_number": "{{trackingCode}}",
          "tracking_company": "Correios",
          "tracking_url": "https://rastreamento.correios.com.br/app/index.php?objeto={{trackingCode}}",
          "notify_customer": true
        },
        "responseVariable": "fulfillment"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Confirmação",
        "parameters": {
          "message": "✅ ENVIO REGISTRADO COM SUCESSO!\n\nPedido #{{order.order.order_number}}\nCliente: {{order.order.customer.first_name}} {{order.order.customer.last_name}}\n📦 Rastreamento: {{trackingCode}}\n🚚 Transportadora: Correios\n\n✉️ Cliente foi notificado por email com link de rastreamento."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "shopify_1" },
    { "source": "shopify_1", "target": "input_2" },
    { "source": "input_2", "target": "shopify_2" },
    { "source": "shopify_2", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o número do pedido:
Usuário: 5234567890123
Sistema: Pedido #1234
Cliente: João

Digite o código de rastreamento:
Usuário: BR123456789BR
Sistema: ✅ ENVIO REGISTRADO COM SUCESSO!

Pedido #1234
Cliente: João Silva
📦 Rastreamento: BR123456789BR
🚚 Transportadora: Correios

✉️ Cliente foi notificado por email com link de rastreamento.

Exemplo 2: Envio em Lote (Múltiplos Pedidos)

Objetivo: Marcar múltiplos pedidos como enviados de uma vez.

JSON para Importar

{
  "name": "Shopify - Envio em Lote",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "shopify_1",
      "type": "shopify",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Listar Pendentes",
        "operation": "list",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "status": "open",
        "limit": 50,
        "responseVariable": "orders"
      }
    },
    {
      "id": "loop_1",
      "type": "loop",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Loop Pedidos",
        "parameters": {
          "items": "{{orders.orders}}",
          "itemVariable": "order",
          "indexVariable": "i"
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Pago e Não Enviado?",
        "parameters": {
          "conditions": [
            {
              "variable": "order.financial_status",
              "operator": "==",
              "value": "paid"
            },
            {
              "variable": "order.fulfillment_status",
              "operator": "==",
              "value": "null"
            }
          ],
          "operator": "AND"
        }
      }
    },
    {
      "id": "shopify_2",
      "type": "shopify",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Marcar Enviado",
        "operation": "fulfill",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "orderId": "{{order.id}}",
        "fulfillment": {
          "tracking_company": "Transportadora Express",
          "notify_customer": true
        },
        "responseVariable": "fulfilled"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Log",
        "parameters": {
          "message": "✅ Pedido #{{order.order_number}} marcado como enviado\nCliente: {{order.customer.first_name}}"
        }
      }
    },
    {
      "id": "delay_1",
      "type": "delay",
      "position": { "x": 1300, "y": 50 },
      "data": {
        "label": "Rate Limit",
        "parameters": {
          "duration": 1,
          "unit": "seconds"
        }
      }
    },
    {
      "id": "merge_1",
      "type": "merge",
      "position": { "x": 1500, "y": 100 },
      "data": { "label": "Próximo" }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1700, "y": 100 },
      "data": {
        "label": "Resumo",
        "parameters": {
          "message": "✅ Processamento concluído!\n\nPedidos processados: {{orders.orders.length}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "shopify_1" },
    { "source": "shopify_1", "target": "loop_1" },
    { "source": "loop_1", "target": "condition_1" },
    { "source": "condition_1", "target": "shopify_2", "label": "true" },
    { "source": "condition_1", "target": "merge_1", "label": "false" },
    { "source": "shopify_2", "target": "message_1" },
    { "source": "message_1", "target": "delay_1" },
    { "source": "delay_1", "target": "merge_1" },
    { "source": "merge_1", "target": "loop_1", "label": "next" },
    { "source": "loop_1", "target": "message_2", "label": "done" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: ✅ Pedido #1234 marcado como enviado
Cliente: João

Sistema: ✅ Pedido #1235 marcado como enviado
Cliente: Maria

Sistema: ✅ Pedido #1236 marcado como enviado
Cliente: Pedro

Sistema: ✅ Processamento concluído!

Pedidos processados: 50

Resposta do Node

{
  "fulfillment": {
    "id": 4234567890123,
    "order_id": 5234567890123,
    "status": "success",
    "created_at": "2025-01-15T10:30:00-03:00",
    "tracking_number": "BR123456789BR",
    "tracking_company": "Correios",
    "tracking_url": "https://rastreamento.correios.com.br/app/index.php?objeto=BR123456789BR",
    "tracking_urls": [
      "https://rastreamento.correios.com.br/app/index.php?objeto=BR123456789BR"
    ],
    "notify_customer": true,
    "line_items": [
      {
        "id": 12345678901234,
        "fulfillment_id": 4234567890123,
        "quantity": 2
      }
    ]
  }
}

Boas Práticas

SIM: - Sempre verifique se pedido foi pago antes de marcar como enviado - Registre código de rastreamento sempre que disponível - Use tracking_url para facilitar rastreamento do cliente - Deixe notify_customer como true para informar cliente automaticamente - Use delays entre múltiplos fulfillments (rate limiting) - Registre logs de envios para auditoria

NÃO: - Não marque como enviado se não enviou de fato - Não envie pedidos não pagos - Não esqueça de informar transportadora - Não faça fulfillments em massa sem rate limiting - Não ignore erros de fulfillment

Dicas

Dica 1 - Notificação: Shopify envia email automático com rastreamento se notify_customer: true.

Dica 2 - Transportadoras: Valores comuns: Correios, Jadlog, Loggi, Total Express, DHL, FedEx.

Dica 3 - Partial Fulfillment: É possível enviar apenas alguns itens - especifique line_items array.

Dica 4 - Multiple Fulfillments: Um pedido pode ter múltiplos fulfillments (envios parciais).

Dica 5 - Tracking URL: URL completo funciona melhor que tracking_company + tracking_number separados.

Dica 6 - Status: Após fulfillment, fulfillment_status do pedido muda para fulfilled.

Próximo Node

SHOPIFY ORDER GET - Verificar status antes de fulfillment → SHOPIFY ORDER LIST - Listar pedidos pendentes → SHOPIFY ORDER CANCEL - Cancelar pedido (alternativa)