DesenvolvedorWordPress WhatsApp

Hooks do WooCommerce: customizar a loja sem editar templates

O WooCommerce monta praticamente toda a sua interface por meio de hooks. Saber onde cada um dispara é o que separa uma customização que sobrevive às atualizações de uma gambiarra que quebra na próxima versão.

Precisa de desenvolvimento sob medida?

Atualizado em 19/06/2026

O WooCommerce é, antes de tudo, um plugin de WordPress — e por isso é construído sobre o mesmo sistema de actions e filters. A diferença é que o WooCommerce leva esse conceito ao extremo: as páginas de loja, produto, carrinho e checkout são montadas inteiramente por hooks. Em vez de escrever HTML fixo, os templates do plugin disparam do_action() em cada ponto e o próprio WooCommerce "se pendura" nesses pontos para imprimir o título, o preço, o botão de comprar e assim por diante. Para o desenvolvedor, isso é uma boa notícia: você customiza a loja se pendurando nos mesmos hooks, sem tocar em um único arquivo de template.

Por que NÃO sobrescrever templates

O WooCommerce permite copiar um arquivo de plugins/woocommerce/templates/ para seu-tema/woocommerce/ para sobrescrevê-lo. É um recurso legítimo, mas tem um custo alto: a sua cópia fica presa na versão atual do markup. Quando o plugin atualiza aquele template — e ele atualiza com frequência —, você não recebe as correções, e o WooCommerce passa a avisar que o seu override está desatualizado. Pior: mudanças estruturais podem quebrar o layout.

Por isso a recomendação oficial é clara: prefira hooks. Eles são a API pública e estável da loja. Você só deveria sobrescrever um template quando a mudança no markup for tão profunda que nenhum hook a permita — e, mesmo aí, mantendo o arquivo o mais enxuto possível.

Os hooks que montam a página de produto

A página de um produto é o exemplo mais didático. O template dispara, em ordem, woocommerce_before_main_content, depois entra no resumo do produto com woocommerce_single_product_summary (onde título, preço, resumo e botão são adicionados em prioridades diferentes) e, abaixo, woocommerce_after_single_product_summary (onde ficam as abas, produtos relacionados, etc.). Para inserir algo, basta escolher o hook e a prioridade correta:

<?php
/**
 * Plugin Name: Minhas Customizações WooCommerce
 */

// Sempre cheque se o WooCommerce está ativo antes de usar suas APIs.
if ( ! class_exists( 'WooCommerce' ) ) {
    return;
}

// 1) Aviso logo ABAIXO do preço (preço usa prioridade 10; usamos 15).
add_action( 'woocommerce_single_product_summary', 'dw_aviso_apos_preco', 15 );

function dw_aviso_apos_preco() {
    echo '<p class="dw-aviso">Frete grátis acima de R$ 199.</p>';
}

// 2) Selo de garantia DEPOIS do resumo do produto, como uma seção.
add_action( 'woocommerce_after_single_product_summary', 'dw_selo_garantia', 5 );

function dw_selo_garantia() {
    echo '<div class="dw-garantia">Garantia de 30 dias ou seu dinheiro de volta.</div>';
}

A tabela abaixo mostra as prioridades padrão dentro de woocommerce_single_product_summary. Escolher um número intermediário posiciona o seu conteúdo com precisão cirúrgica:

PrioridadeO que o WooCommerce adiciona
5Título do produto
10Preço e avaliação
20Resumo (excerpt)
30Formulário de compra (botão "Comprar")
40Metadados (SKU, categorias, tags)

Filtrando os campos do checkout

O checkout é outro território de hooks. Para adicionar, remover ou ajustar campos, use o filtro woocommerce_checkout_fields. Como todo filter, ele recebe um valor — o array de campos — e precisa devolvê-lo. A estrutura é agrupada por seção (billing, shipping, account, order):

<?php
add_filter( 'woocommerce_checkout_fields', 'dw_ajusta_checkout' );

function dw_ajusta_checkout( $fields ) {
    // Torna o telefone opcional e muda o rótulo.
    if ( isset( $fields['billing']['billing_phone'] ) ) {
        $fields['billing']['billing_phone']['required'] = false;
        $fields['billing']['billing_phone']['label']    = 'Celular (WhatsApp)';
    }

    // Adiciona um campo personalizado de CPF/CNPJ.
    $fields['billing']['billing_documento'] = array(
        'label'       => 'CPF/CNPJ',
        'placeholder' => 'Somente números',
        'required'    => true,
        'class'       => array( 'form-row-wide' ),
        'priority'    => 25,
    );

    return $fields; // OBRIGATÓRIO: filter sem return zera os campos.
}

Adicionar o campo no formulário não o salva sozinho. Para persistir o valor no pedido, use o action woocommerce_checkout_update_order_meta (lendo de $_POST com sanitização) e, se quiser exibi-lo no admin, woocommerce_admin_order_data_after_billing_address. Validar dados de entrada é parte do trabalho — veja segurança no código.

Adicionando uma taxa ou desconto no carrinho

Para alterar o total cobrado — uma taxa de embalagem, um desconto por região, um acréscimo de pagamento —, o hook é woocommerce_cart_calculate_fees. Ele dispara durante o cálculo do carrinho e te entrega o objeto do carrinho; você adiciona valores com $cart->add_fee() (um valor negativo funciona como desconto):

<?php
add_action( 'woocommerce_cart_calculate_fees', 'dw_taxa_e_desconto' );

function dw_taxa_e_desconto( $cart ) {
    // Evita rodar no admin (exceto em chamadas AJAX legítimas).
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    $subtotal = $cart->get_subtotal();

    // Desconto de 5% para carrinhos acima de R$ 500 (fee negativa).
    if ( $subtotal > 500 ) {
        $desconto = $subtotal * 0.05;
        $cart->add_fee( 'Desconto fidelidade', -$desconto );
    }

    // Taxa fixa de manuseio (o 3º parâmetro indica se é tributável).
    $cart->add_fee( 'Taxa de manuseio', 7.50, true );
}

Repare que esse callback roda a cada recálculo do carrinho — por isso evite consultas pesadas aqui e nunca chame $cart->add_fee() condicionalmente de forma instável, ou o valor "pisca" entre requisições AJAX.

Executando algo após a compra

Depois que o pedido é concluído e o cliente chega à página de obrigado, dispara o woocommerce_thankyou, que recebe o ID do pedido. É o ponto clássico para integrações: notificar um ERP, disparar um pixel de conversão, registrar uma assinatura. Como vimos no FAQ, trate-o como potencialmente repetível e proteja a ação com uma meta de controle:

<?php
add_action( 'woocommerce_thankyou', 'dw_apos_compra' );

function dw_apos_compra( $order_id ) {
    if ( ! $order_id ) {
        return;
    }

    $order = wc_get_order( $order_id ); // CRUD API, nunca get_post().
    if ( ! $order ) {
        return;
    }

    // Idempotência: só executa uma vez por pedido.
    if ( $order->get_meta( '_dw_integrado' ) === 'sim' ) {
        return;
    }

    // ... aqui vai a sua integração usando $order->get_total(), etc.

    $order->update_meta_data( '_dw_integrado', 'sim' );
    $order->save();
}

O acesso ao pedido aqui já usa a CRUD API do WooCommerce (wc_get_order()), e não get_post() — essencial para compatibilidade com o armazenamento moderno de pedidos.

Mapa rápido dos principais hooks

Hook do WooCommerceOnde dispara / para que serve
woocommerce_before_main_contentAbertura da área principal (loja, produto, arquivos). Abrir wrappers, breadcrumbs.
woocommerce_single_product_summaryColuna de resumo do produto. Inserir avisos, badges, campos entre preço e botão (via prioridade).
woocommerce_after_single_product_summaryAbaixo do resumo do produto. Abas, relacionados, seções extras.
woocommerce_checkout_fields (filter)Array de campos do checkout. Adicionar, remover ou reordenar campos. Sempre retornar.
woocommerce_cart_calculate_feesCálculo do carrinho. Adicionar taxas/descontos com $cart->add_fee().
woocommerce_thankyouPágina de obrigado, recebe o ID do pedido. Integrações pós-compra (idempotentes).
woocommerce_before_cart / woocommerce_after_cartTopo e rodapé da página do carrinho. Avisos, banners.

Boas práticas que evitam dor de cabeça

Dominar esses hooks resolve a maioria das customizações de uma loja sem nenhum override de template. Quando o assunto é manipular dados — ler e gravar produtos e pedidos por código —, o caminho correto é a CRUD API, tema do próximo artigo. Se a sua loja precisa de ajustes finos ou de uma integração sob medida, veja também os serviços de suporte e manutenção WooCommerce.

Precisa customizar sua loja WooCommerce sem quebrar nas atualizações?

Desenvolvo customizações via hooks, seguindo os padrões do WooCommerce e do WordPress. Me chame no WhatsApp e descreva o que a loja precisa.

WhatsApp: (43) 99932-9697

ou e-mail: [email protected]

Perguntas frequentes

Por que customizar por hooks em vez de sobrescrever o template?

Porque sobrescrever um arquivo de template (copiá-lo para seu-tema/woocommerce/) congela aquele arquivo na versão atual: quando o WooCommerce atualizar o template original — corrigindo um bug ou ajustando o markup —, a sua cópia continua a antiga e pode quebrar. Os hooks são a API pública e estável da loja; pendurar-se neles sobrevive às atualizações e mantém a customização isolada em um plugin próprio.

Como descubro qual hook usar em cada ponto da loja?

Os templates do WooCommerce (em plugins/woocommerce/templates/) são lateralmente legíveis: cada bloco de markup é cercado por chamadas do_action(). Abra, por exemplo, single-product.php e content-single-product.php e você verá hooks como woocommerce_before_main_content e woocommerce_single_product_summary. O nome do hook e a prioridade com que o conteúdo padrão é adicionado indicam exatamente onde o seu código vai aparecer.

O que a prioridade controla nos hooks do WooCommerce?

A posição. Dentro de um mesmo hook (por exemplo woocommerce_single_product_summary), o WooCommerce adiciona o título na prioridade 5, o preço na 10, o resumo na 20, o botão de compra na 30 e os metadados na 40. Escolhendo um número entre esses, o seu conteúdo aparece exatamente entre os elementos desejados. Menor roda (aparece) antes; maior, depois.

Por que meu callback de checkout não recebe os campos?

O filtro woocommerce_checkout_fields recebe o array completo de campos e exige que você o retorne. Se esquecer o return $fields;, o checkout fica sem campos. Outro erro comum é mexer numa chave que não existe (a estrutura é $fields['billing']['billing_phone'], etc.) sem checar antes com isset().

Preciso checar se o WooCommerce está ativo?

Sim. Se o seu código chama funções do WooCommerce (como WC() ou wc_get_product()) e o plugin for desativado, o site quebra com fatal error. Envolva o registro dos hooks (ou cada callback) em if ( class_exists( 'WooCommerce' ) ) ou registre-os no hook woocommerce_loaded, que só dispara quando o WooCommerce está presente.

O hook woocommerce_thankyou roda sempre após a compra?

Ele dispara ao exibir a página de obrigado (order-received), o que normalmente acontece uma vez. Mas o cliente pode recarregar essa URL, então não o trate como evento único e idempotente: se você precisa executar algo exatamente uma vez por pedido, registre uma meta no pedido (ex.: $order->update_meta_data()) e cheque-a antes de repetir a ação. Para reagir a mudanças de status com mais segurança, considere hooks como woocommerce_order_status_completed.

Referências oficiais

  1. WooCommerce — Developer Documentation
  2. WooCommerce — Documentation
  3. WordPress.org — Hooks (Plugin Handbook)
Tem alguma dúvida? Ficarei feliz em ajudar. Clique Aqui