Woocommerce com frete grátis por produto

Veja como atribuir Frete Grátis a um ou mais produtos do Woocommerce, ocultando as demais opções de entrega/frete.

woocommerce_logo

Problema

Montando um loja virtual baseada em WordPress (Woocommerce), estava precisando oferecer frete grátis para um ou mais produtos especificamente. Tentei ativar a opção “Frete Grátis” própria do Woocommerce (Woocommerce > Configurações > Entrega > Frete Grátis), mas desta forma o frete grátis era exibido para qualquer compra, não sendo possível especificar os produtos que teriam ou não o frete grátis.

A seguir, irei apresentar duas soluções. Recomendo a solução 2, pois além de ser mais elegante, contará com as atualizações e suporte do desenvolvedor Claudio Sanches.

Solução 1

Notei, então, que havia uma opção “Tarifa Fixa” (Woocommerce > Configurações > Entrega > Tarifa Fixa), em que era possível criar “Classes de entrega” para posteriormente vinculá-la a um produto. O que fiz foi o seguinte:

(1) Criei uma Classe de entrega em Produtos > Classes de entrega, com o nome “Frete Grátis”.

(2) Acessei a Guia de Entrega e a opção Tarifa Fixa (Woocommerce > Configurações > Entrega > Tarifa Fixa), e lá em “Custos adicionais”, criei uma entrada clicando no botão “Adicionar custo”, onde selecionei a opção “Frete Grátis” (Classe de entrega), e custo e manuseio coloquei 0 (zero).

(3) Feito isto, criei e inseri o seguinte código no arquivo functions.php, disponível na raiz do seu tema:

Oculta opções de frete (entrega) quando a tarifa for zero

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Oculta opções de frete (entrega) quando a tarifa for zero
add_filter( 'woocommerce_available_shipping_methods', 'hide_standard_shipping_when_flat_rate_is_zero' , 10, 1 );
function hide_standard_shipping_when_flat_rate_is_zero( $available_methods ) {
  if(isset( $available_methods['flat_rate']) && $available_methods['flat_rate']->cost == 0 ) {
    global $woocommerce;
    $flag_flat_rate_is_zero = true;
    $exist_shipping_class = false;
    // Verifica se todos os produtos do carrinho são frete grátis, senão, aplica o frete para todos
    foreach ($woocommerce->cart->cart_contents as $product_content) {
      if (isset($product_content['data']->shipping_class)) {
        $exist_shipping_class = true;
        if ($product_content['data']->shipping_class == '') {
          $flag_flat_rate_is_zero = false;
          break;
        }        
      }
    }      
    if ($exist_shipping_class) {
      if ($flag_flat_rate_is_zero)
        $_SESSION['flag_flat_rate_is_zero_session'] = true;      
      else 
        $_SESSION['flag_flat_rate_is_zero_session'] = false; 
    }          
    if ($_SESSION['flag_flat_rate_is_zero_session']) {        
      // Aqui você coloca o ID dos métodos que serão ocultados
      unset( $available_methods['PAC'] );
      unset( $available_methods['SEDEX'] );
      unset( $available_methods['free_shipping'] );     
    }
    else {
      unset( $available_methods['flat_rate'] );
    }
  }
  return $available_methods;
}

(4) Por último, bastou vincular o produto à classe Frete Grátis. Para isto, abra um produto já cadastrado (Produtos > Produtos > [selecionar seu produto] > Entrega > Classe de Frete) e selecione “Frete Grátis”. Clique em Atualizar para gravar as alterações.

Faça um teste e veja que, agora, quando uma entrega de produto é marcada com frete grátis, o carrinho de compras omite os outros tipos de frete (PAC, Sedex, etc). Se todos os produtos do carrinho forem frete grátis, o frete da compra continua sendo grátis. Mas se no carrinho houver apenas um único produto que não seja frete grátis, então, neste caso, o sistema irá calcular o frete para todos os produtos. O certo seria cobrar o frete apenas do produto (ou produtos) que não tem frete grátis, mas não tive como fazer isto funcionar desta forma no momento.

É isso. Talvez esta não seja a melhor solução (nem a única) para fazer o pretendido. Mas funcionou, pelo menos pra mim. Neste Post, presume-se que estejam instalados o WordPress, Woocommerce e o plugin Correios para WooCommerce. Aliás, aproveito para agradecer aos maravilhosos plugins criados e compartilhados por “Claudio Sanches“; eles têm sido muito úteis.

Solução 2 (recomendado)

(1) Instale o plugin “woocommerce-correios-envelope” (o nome é provisório). Como o plugin ainda não tem um instalador, faça o seguinte: Crie uma pasta wp-content\plugins\woocommerce-correios-envelope e coloque dentro o arquivo “woocommerce-correios-envelope.php”

(2) Vá ao painel de controle > Plugins > Plugins Instalados e clique em “Ativar” para o plugin “WooCommerce Correios – Envelope”

(3) Crie uma Classe de entrega em Produtos > Classes de entrega, com o nome “Frete Grátis”.

(4) Acesse a Guia de Entrega e a opção Tarifa Fixa (Woocommerce > Configurações > Entrega > Tarifa Fixa), e lá em “Custos adicionais”, crie uma entrada clicando no botão “Adicionar custo” e selecione a opção “Frete Grátis” (Classe de entrega), e coloque 0 (zero) para custo e manuseio.

(5) Por último, basta vincular o produto à classe Frete Grátis. Para isto, abra um produto já cadastrado (Produtos > Produtos > [selecionar seu produto] > Entrega > Classe de Frete) e selecione “Frete Grátis”. Não esqueça de marcar o checkbox “Produto entregue utilizando envelope” (aparece em forma de widget na coluna da direita da tela de cadastro de produto). Clique em Atualizar para gravar as alterações.

Créditos: Claudio Sanches.

Boa sorte!

Frete Grátis a partir de determinado valor da compra

Um jeito de fazer isto, é configurando a opção “WooCommerce > Configurações > Entrega > Frete Grátis”, conforme imagem abaixo:

fretegratis

É isso aí!

Total de acessos: 17474

24 comentários sobre “Woocommerce com frete grátis por produto

  1. Acabei de lembrar.
    Se quiser eu fiz algo similar essas semanas atrás, no caso o cara precisava cobrar uma taxa ficha para produtos que seriam entregues via envelope, mas da para ser utilizado para frete grátis também.
    No caso criei um metabox para marcar dentro do produto que era para ser um envelope e mostrava o valor do Flat Rate no carrinho apenas quando tivesse os produtos marcados.
    Aqui como ficou: https://gist.github.com/claudiosmweb/6017766

    Vai virar um plugin em breve, só preciso escolher um nome para isso xD

    • Olá Claudio. É uma honra ter seus comentários aqui neste espaço. Fiz um teste com o seu futuro plugin “woocommerce-correios-envelope“. Ele se comporta praticamente igual ao método demonstrado neste Post. A única diferença é que utilizando o seu plugin, além de vincular o produto a classe de entrega (frete grátis), ainda é preciso marcar o checkbox “Produto entregue utilizando envelope”. O detalhe é que tanto o meu Post quanto o seu plugin tem um “problema” comum. Se o carrinho tiver vários produtos e um deles não for “frete grátis”, então, o frete é calculado para TODOS os produtos (incluindo os de frete grátis), tornando o frete mais caro. O correto seria cobrar o frete apenas do produto (ou produtos) que não tem frete grátis. De qualquer forma, me atende bem para o que preciso. Obrigado mais uma vez; abraços!

  2. Victor disse:

    Excelente post!
    Minha dúvida: Como faço para zerar o valor do frete caso o pedido seja entregue para a cidade de Belo Horizonte por exemplo? Frete gratis somente para esta cidade.

  3. José disse:

    Olá
    Gostaria de saber se existe algum plugin para poder ocultar o frete pelos correios. Estou montando uma loja onde irei utilizar como método de envio os correios e através de uma transportadora (Jamef que já possui um plugin) mas alguns produtos não podem seguir pelo correio. Como ocultar a opção de correios para estes produtos aparecendo apenas a opção da trasportadora ?

  4. Boa tarde Taylor Lopes, parabéns pelo post ótima dica! Gostaria que me orientasse, estou com um problema de Frete Fixo e Frete Grátis. Criei uma Classe de entrega em Produtos > Classes de entrega, com o nome “Pronta Entrega”. Acessei a Guia de Entrega e a opção Taxa Fixa (Woocommerce > Configurações > Entrega > Taxa Fixa) coloquei o Título do método ” Frete Padrão” em “Custos adicionais”, criei uma entrada clicando no botão “Adicionar custo”, onde selecionei a opção “Pronta Entrega” (Classe de entrega), e custo R$ 18,00 e manuseio coloquei 0 (zero). Até aí tudo bem, qualquer compra terá um frete fixo de R$ 18,00. Então criei a opção de Frete grátis com compras somente a partir de R$ 100,00. Acessei a Guia de Entrega e a opção Frete grátis (Woocommerce > Configurações > Entrega >Frete grátis) Título do método ” Frete Padrão” configurei “Frete grátis necessita…” selecionei ” Valor mínimo de pedido ou cupom” em “Valor mínimo do pedido” escrevi “100” e salvei as alterações. Feito isso realizei os testes: inseri produtos no valor abaixo de R$ 100,00 então aparece o frete R$ 18,00 no carrinho, até aí beleza.

    Total no carrinho
    Subtotal do carrinho R$ 94,00
    Shipping and Handling:
    Frete Padrão: R$ 18,00
    Imposto R$ 0,00
    Total de pedido R$ 112,00

    só que quando eu insiro mais produtos o carrinho e atualizo fica assim:

    Total no carrinho
    Subtotal do carrinho R$ 126,00
    Shipping and Handling:
    Frete Padrão: R$ 18,00
    Frete grátis
    Imposto R$ 0,00
    Total de pedido R$ 144,00

    Ou seja, aparece a opção do cliente a forma do frete com botões “radio” Frete Padrão: R$ 18,00 ou Frete grátis. Gostaria que quando houvesse a atualização do carrinho ficasse apenas uma opção de frete! Desde já agradeço!

  5. Não consegui o resultado esperado;

    Tenho que trabalhar com duas frentes no meu site: Produtos a pronta entrega (que utilizaria o método de entrega (plugin) do Correio que calcula o frete via PAC e SEDEX) e o Frete Grátis, que seriam os produtos importados. Mas se eu colocar um produto como frete grátis (com o módulo indicado no artigo do blog) na classe de entrega, ainda sim está aparecendo as opções do Correio no momento de finalizar a compra.

    Alguém tem uma ideia do que posso fazer?

    • @Taylor li melhor o final do artigo, e como você bem explica ” – Se todos os produtos do carrinho forem frete grátis, o frete da compra continua sendo grátis. Mas se no carrinho houver apenas um único produto que não seja frete grátis, então, neste caso, o sistema irá calcular o frete para todos os produtos. O certo seria cobrar o frete apenas do produto (ou produtos) que não tem frete grátis, mas não tive como fazer isto funcionar desta forma no momento.”

      Alguma outra ideologia para utilizar? Cobrar um valor maior do produto a Pronta Entrega, cobrando já o frete e ao cliente dar o frete grátis?

    • Opa, repare que no próprio post eu mostrei como ocultar as opções de frete (entrega pelo correio) quando a tarifa for zero (frete grátis). Repare a parte do código que consta:

      1
      2
      3
      4
      
            // Aqui você coloca o ID dos métodos que serão ocultados
            unset( $available_methods['PAC'] );
            unset( $available_methods['SEDEX'] );
            unset( $available_methods['free_shipping'] );
  6. Br4nd40 disse:

    Taylor adorei sua iniciativa parabens mas surgiram duvidas se pudesse me ajudar ficaria muito grato.

    minha estrategia é a seguinte eu instalei o plugin WooCommerce Discounts Per Payment Method para pagamentos com transferencia bancaria ter 10% de desconto mas ai me surgiu uma duvida.
    se coloco o seu codigo por exemplo acima de 100,00 frete grátis, mas se a pessoa pagar como transferencia bancaria ela vai receber 10% de desconto nesse caso não queria que ela recebesse o desconto de 10% quando o frete for gratis é possivel me ajudar?

  7. Nei Filipe Pacheco disse:

    Olá Taylor

    Estou tentando executar a Solução 1, pois na loja que estou desenvolvendo os produtos acima de R$ 99,00 tem Frete Grátis porém apenas em PAC. Consigo realizar o mesmo procedimento da Solução 1 colocando o código para ocultar apenas a opção de PAC que seria Grátis e as demais continuarem aparecendo? Pois caso o cliente queira receber o produto mais rápido, ele poderá escolher arcar com o custo do Sedex.

    Deveria aparecer assim:

    PAC (Entrega em 5 dias úteis): Frete Grátis
    SEDEX (Entrega em 3 dias úteis): R$ 15.64
    SEDEX 10 (Entrega em 3 dias úteis): R$ 23.86
    SEDEX Hoje (Entrega em 3 dias úteis): R$ 30.16

  8. Rafael disse:

    Fiz tudo acima, mas no carrinho quando tem um produto com frete grátis e outros com meios de pagamento o sistema coloca a opção frete grátis nas opções, sendo assim o comprador pode inserir vários produtos que possuem frete e um produto com frete grátis e terá frete grátis em todos os produtos (mesmo eles não sendo frete grátis)

    Alguém sabe como solucionar isso? (já coloquei o código acima mas não mudou nada)

  9. Roberto disse:

    Olá meu caros,
    Tenho a seguinte situação:

    (essa opção funciona perfeitamente porém os correios aparece como opção de pagamento, e gostaria de ocultar os correios quando essa opção funcionar em um determinado produto.)
    Peguei um código no youtube, que mostra frete grátis para alguns estados.
    Se selecionar SP, PR MT, MG, MS, por exemplo, ele da opção de frete gratis.

    (essa opção ainda não consegui fazer)
    Se selecionar outro estado, ele deve mostrar frete de taxa fixa, pois o produto não vai pelos correios.

    Porém, outros produtos no site, serão enviados pelo correios, e devem aparecer somente correios, nem frete gratis e nem taxa fixa.

    Alguém poderia me ajudar nessa questão, por gentileza?

  10. GUSTAVO JOSE SILVA MELO disse:

    Oi, estou com dois grandes problemas.

    O primeiro é o seguinte: Preciso vender um produto por variação de peso, por exemplo, o cliente pode comprar no mínimo 100g e no máximo 2000g de um mesmo produto (um cereal). Tentei utilizar atributos e variações para dividir em pacotes (100g, 500g, …), mas ai o cliente pode escolher vários pacotes do mesmo produto e isso não pode acontecer. :|

    O segundo problema problema é ocultar a opção “taxa fixa” (não venderemos pelos correios), quando a opção frete grátis estiver disponível e para um valor “X” foi predefinido.

    Alguém pode me ajudar?

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *