Pular para conteúdo

SHOPIFY ORDER CANCEL - Cancelar Pedido do Shopify

O que é este Node?

O SHOPIFY ORDER CANCEL é o node responsável por cancelar pedidos no Shopify, devolvendo estoque e marcando o pedido como cancelado.

Por que este Node existe?

Cancelar pedidos é necessário para gestão de vendas. O SHOPIFY ORDER CANCEL existe para:

  1. Solicitação de cliente: Cancelar quando cliente desiste da compra
  2. Pagamento recusado: Cancelar pedidos com pagamento não aprovado
  3. Falta de estoque: Cancelar quando produto não está disponível
  4. Fraude: Cancelar pedidos suspeitos
  5. Erro de cadastro: Cancelar pedidos duplicados ou incorretos

Como funciona internamente?

Quando o SHOPIFY ORDER CANCEL é executado, o sistema:

  1. Valida credenciais e orderId
  2. Envia requisição POST para /admin/api/{version}/orders/{orderId}/cancel.json
  3. Shopify cancela o pedido e restaura estoque
  4. Retorna pedido atualizado com status cancelled
  5. Salva resultado na variável especificada
  6. Continua flow para próximo node

Código interno (shopify.executor.ts:72-76):

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

Quando você DEVE usar este Node?

Use SHOPIFY ORDER CANCEL quando precisar cancelar pedidos:

Casos de uso:

  1. Cliente desistiu: "Cliente solicitou cancelamento antes do envio"
  2. Pagamento negado: "Cartão recusado, cancelar pedido"
  3. Sem estoque: "Produto esgotou, cancelar pedido"
  4. Erro: "Pedido duplicado, cancelar um deles"
  5. Fraude: "Pedido suspeito, cancelar por segurança"

Quando NÃO usar:

  • Pedido já enviado: Não cancele, faça devolução/reembolso separadamente
  • Reembolso parcial: Use API de Refunds para devolver parte do valor
  • Apenas marcar: Use UPDATE para mudar tags/notas sem cancelar

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 cancelar
responseVariable string Não Nome da variável (padrão: shopifyResult)

Exemplo 1: Cancelar Pedido com Confirmação

Objetivo: Permitir cliente cancelar pedido antes do envio.

JSON para Importar

{
  "name": "Shopify - Cancelar Pedido Cliente",
  "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 que deseja cancelar:",
          "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": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Pode Cancelar?",
        "parameters": {
          "conditions": [
            {
              "variable": "order.order.fulfillment_status",
              "operator": "==",
              "value": "null"
            }
          ],
          "operator": "AND"
        }
      }
    },
    {
      "id": "input_2",
      "type": "input",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Pedido #{{order.order.order_number}}\nValor: R$ {{order.order.total_price}}\nStatus: Não enviado\n\n⚠️ Deseja realmente CANCELAR este pedido?\nDigite 'SIM' para confirmar:",
          "variable": "confirmation"
        }
      }
    },
    {
      "id": "condition_2",
      "type": "condition",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Confirmou?",
        "parameters": {
          "conditions": [
            {
              "variable": "confirmation",
              "operator": "==",
              "value": "SIM"
            }
          ],
          "operator": "AND"
        }
      }
    },
    {
      "id": "shopify_2",
      "type": "shopify",
      "position": { "x": 1300, "y": 25 },
      "data": {
        "label": "Cancelar",
        "operation": "cancel",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "orderId": "{{orderId}}",
        "responseVariable": "cancelled"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1500, "y": 25 },
      "data": {
        "label": "Cancelado",
        "parameters": {
          "message": "✅ Pedido cancelado com sucesso!\n\nPedido #{{order.order.order_number}}\nValor: R$ {{order.order.total_price}}\n\nO estoque foi restaurado e você receberá reembolso em até 5 dias úteis."
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1300, "y": 75 },
      "data": {
        "label": "Não Confirmou",
        "parameters": {
          "message": "❌ Cancelamento não confirmado.\n\nO pedido permanece ativo."
        }
      }
    },
    {
      "id": "message_3",
      "type": "message",
      "position": { "x": 900, "y": 150 },
      "data": {
        "label": "Já Enviado",
        "parameters": {
          "message": "⚠️ Este pedido já foi enviado!\n\nPedido #{{order.order.order_number}}\nStatus: {{order.order.fulfillment_status}}\n\nNão é possível cancelar. Entre em contato para devolução."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "shopify_1" },
    { "source": "shopify_1", "target": "condition_1" },
    { "source": "condition_1", "target": "input_2", "label": "true" },
    { "source": "condition_1", "target": "message_3", "label": "false" },
    { "source": "input_2", "target": "condition_2" },
    { "source": "condition_2", "target": "shopify_2", "label": "true" },
    { "source": "condition_2", "target": "message_2", "label": "false" },
    { "source": "shopify_2", "target": "message_1" },
    { "source": "message_1", "target": "end_1" },
    { "source": "message_2", "target": "end_1" },
    { "source": "message_3", "target": "end_1" }
  ]
}

Saída esperada (cancelado):

Sistema: Digite o número do pedido que deseja cancelar:
Usuário: 5234567890123
Sistema: Pedido #1234
Valor: R$ 349.80
Status: Não enviado

⚠️ Deseja realmente CANCELAR este pedido?
Digite 'SIM' para confirmar:
Usuário: SIM
Sistema: ✅ Pedido cancelado com sucesso!

Pedido #1234
Valor: R$ 349.80

O estoque foi restaurado e você receberá reembolso em até 5 dias úteis.

Saída esperada (já enviado):

Sistema: Digite o número do pedido que deseja cancelar:
Usuário: 5234567890456
Sistema: ⚠️ Este pedido já foi enviado!

Pedido #1235
Status: fulfilled

Não é possível cancelar. Entre em contato para devolução.

Exemplo 2: Cancelar Pedidos com Pagamento Pendente

Objetivo: Cancelar automaticamente pedidos com pagamento não aprovado após 24h.

JSON para Importar

{
  "name": "Shopify - Cancelar Pagamentos Pendentes",
  "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 Pedidos",
        "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": "Pagamento Pending?",
        "parameters": {
          "conditions": [
            {
              "variable": "order.financial_status",
              "operator": "==",
              "value": "pending"
            }
          ],
          "operator": "AND"
        }
      }
    },
    {
      "id": "shopify_2",
      "type": "shopify",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Cancelar Pedido",
        "operation": "cancel",
        "resource": "orders",
        "config": {
          "shopName": "minhaloja",
          "accessToken": "shpat_xxxxxxxxxxxxx",
          "apiVersion": "2025-01"
        },
        "orderId": "{{order.id}}",
        "responseVariable": "cancelResult"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Log Cancelamento",
        "parameters": {
          "message": "❌ Pedido #{{order.order_number}} cancelado\nMotivo: Pagamento não confirmado\nCliente: {{order.customer.first_name}}\nValor: R$ {{order.total_price}}"
        }
      }
    },
    {
      "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": "✅ Limpeza concluída!\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 cancelado
Motivo: Pagamento não confirmado
Cliente: João
Valor: R$ 349.80

Sistema: ❌ Pedido #1237 cancelado
Motivo: Pagamento não confirmado
Cliente: Maria
Valor: R$ 199.90

Sistema: ✅ Limpeza concluída!

Pedidos processados: 50

Resposta do Node

{
  "order": {
    "id": 5234567890123,
    "order_number": 1234,
    "email": "joao@example.com",
    "cancelled_at": "2025-01-15T10:30:00-03:00",
    "cancel_reason": "customer",
    "financial_status": "voided",
    "fulfillment_status": null,
    "total_price": "349.80"
  }
}

Boas Práticas

SIM: - Sempre verifique se pedido não foi enviado antes de cancelar - Implemente confirmação dupla para evitar cancelamentos acidentais - Informe cliente sobre cancelamento e reembolso - Verifique financial_status antes de cancelar - Use delays entre múltiplos cancelamentos (rate limiting) - Registre motivo do cancelamento em logs

NÃO: - NUNCA cancele pedidos já enviados (use devolução) - Não cancele sem verificar status atual - Não ignore erros de cancelamento - Não cancele pedidos pagos sem processar reembolso - Não faça cancelamentos em massa sem rate limiting

Dicas

Dica 1 - Irreversível: Cancelamento marca pedido como cancelado permanentemente - não há "descancelar".

Dica 2 - Estoque: Shopify restaura estoque automaticamente ao cancelar pedido.

Dica 3 - Reembolso: Cancelamento NÃO processa reembolso automaticamente - use Refund API separadamente.

Dica 4 - Status: Após cancelar, cancelled_at é preenchido e financial_status vira voided.

Dica 5 - Notificação: Shopify envia email automático ao cliente informando cancelamento.

Dica 6 - Motivo: Shopify registra cancel_reason automaticamente (customer, fraud, inventory, etc.).

Próximo Node

SHOPIFY ORDER GET - Verificar status antes de cancelar → SHOPIFY ORDER LIST - Listar pedidos para cancelar → SHOPIFY ORDER FULFILL - Marcar como enviado (alternativa)