Receitas prontas pra os casos de customização mais comuns. Cole no functions.php do tema (filho) ou num mu-plugin.
Adicionar sobretaxa por vendedor
Cobrar 10% a mais no frete pra um vendedor específico (ex: cobrir custos extras de embalagem fragil):
add_filter( 'woocommerce_package_rates', function( $rates, $package ) {
$vendor_id = $package['wcsp_vendor_id'] ?? null;
if ( 42 !== $vendor_id ) {
return $rates;
}
foreach ( $rates as $rate ) {
$rate->cost *= 1.10;
}
return $rates;
}, 100, 2 );
Aplicar desconto progressivo no frete pra vendedores premium
Vendedores marcados com _premium_vendor = yes recebem 20% de desconto:
add_filter( 'woocommerce_package_rates', function( $rates, $package ) {
$vendor_id = $package['wcsp_vendor_id'] ?? 0;
if ( ! $vendor_id ) {
return $rates;
}
if ( 'yes' !== get_user_meta( $vendor_id, '_premium_vendor', true ) ) {
return $rates;
}
foreach ( $rates as $rate ) {
$rate->cost *= 0.80;
}
return $rates;
}, 100, 2 );
CEP de origem por filial do vendedor
Vendedor tem múltiplas filiais. Use uma filial diferente como origem dependendo do horário (filial A em horário comercial, filial B fora):
add_filter( 'wcsp_vendor_postcode', function( $postcode, $vendor_id ) {
if ( 99 !== $vendor_id ) {
return $postcode;
}
$hora_atual = (int) current_time( 'H' );
if ( $hora_atual >= 9 && $hora_atual < 18 ) {
return '01001-000'; // Filial A — horário comercial
}
return '04567-000'; // Filial B — fora do horário
}, 20, 2 );
Frete grátis pra todos os pacotes acima de R$ 200 (cumulativo)
Comportamento contrário ao default — em vez de avaliar mínimo por pacote, aplica frete grátis a todos os pacotes quando o total do carrinho passa de R$ 200:
add_filter( 'woocommerce_shipping_free_shipping_is_available', function( $is_available, $package ) {
if ( WC()->cart && WC()->cart->get_subtotal() >= 200 ) {
return true;
}
return $is_available;
}, 100, 2 );
Esse snippet "esquece" o split — todos os pacotes ganham frete grátis se o total bate. Útil em campanhas, mas conflita com a ideia de mínimo por vendedor. Use consciente.
Esconder pacote sem CEP de origem
Se o vendedor esqueceu de cadastrar CEP, esconda o pacote dele do checkout em vez de mostrar com erro:
add_filter( 'woocommerce_cart_shipping_packages', function( $packages ) {
foreach ( $packages as $key => $package ) {
if ( ! empty( $package['wcsp_vendor_id'] ) && empty( $package['wcsp_vendor_postcode'] ) ) {
unset( $packages[ $key ] );
}
}
return $packages;
}, 11 ); // Prioridade 11 — depois do plugin (que fecha em 10)
Se você esconder o pacote, o cliente continua tendo o produto no carrinho mas não vê opção de envio — pode confundir. Considere mostrar uma mensagem de erro em vez de esconder silenciosamente.
Logar todos os splits pra análise
Em desenvolvimento, gravar todo split em log custom:
add_filter( 'woocommerce_cart_shipping_packages', function( $packages ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return $packages;
}
foreach ( $packages as $i => $package ) {
$vendor = $package['wcsp_vendor_name'] ?? 'Loja matriz';
$cep = $package['wcsp_vendor_postcode'] ?? get_option( 'woocommerce_store_postcode' );
$count = count( $package['contents'] ?? array() );
error_log( sprintf( '[FM] Pacote %d: %s (CEP %s) — %d itens', $i + 1, $vendor, $cep, $count ) );
}
return $packages;
}, 999 );
Validar CEP do vendedor antes de salvar (WC Vendors)
Bloquear salvamento de CEP em formato inválido no painel do vendedor:
add_action( 'admin_init', function() {
if ( ! isset( $_POST['_wcv_store_postcode'] ) ) {
return;
}
$cep = preg_replace( '/\D/', '', sanitize_text_field( $_POST['_wcv_store_postcode'] ) );
if ( strlen( $cep ) !== 8 ) {
unset( $_POST['_wcv_store_postcode'] );
wp_die( 'CEP inválido. Use 8 dígitos.' );
}
}, 5 );
Filtros usados nos exemplos
wcsp_vendor_postcode— fonte do CEP por vendedor.- Filtros dos métodos de envio — Correios, Melhor Envio, Distance Rate, Frete Grátis.
wcsp_package_name— título do pacote no checkout.- Estrutura do pacote — campos
wcsp_*disponíveis em todos esses snippets.