fbpx

Calculadora de envío en productos de WooCommerce

Si los usuarios de tu tienda online se han llevado algún ‘susto’ con el importe de los envíos antes de finalizar la compra… quizá debas incluir la calculadora de envíos en la ficha de producto.

Cuando tienes un ecommerce, tus productos, tu logística o la experiencia de compra que quieres brindar a tus clientes puede requerir incorporar funcionalidades que no encontrarás de inicio en WooCommerce. Recientemente, un cliente necesitaba mostrar la calculadora de envíos en la ficha de productos de WooCommerce para mejorar el embudo de conversión en su ecommerce.

Si tú también quieres aplicar este cambio en instalación de WooCommerce, no tienes más que seguir los siguientes pasos.

¿Cómo insertar la calculadora de envío en la ficha de producto?

Para activar esta funcionalidad en tu instalación de WooCommerce sólo tienes que añadir el siguiente código en tu plugin de funciones:

// Shortcode calculadora de envíos

global $shortcode_times;
add_action( 'wp', 'mk_woo_shipping_calculator_ajax' );

function mk_woo_shipping_calculator_ajax() {

    if( $_POST["action"] != "mk_woo_shipping_calculator")
        return false;

    $result = array();

    try {

        WC()->shipping->load_shipping_methods();
        WC()->shipping->reset_shipping();
        $country  = wc_clean( $_POST['country'] );
        $state    = wc_clean( isset( $_POST['state'] ) ? $_POST['state'] : '' );
        $postcode = apply_filters( 'woocommerce_shipping_calculator_enable_postcode', true ) ? wc_clean( $_POST['postcode'] ) : '';
        $city     = apply_filters( 'woocommerce_shipping_calculator_enable_city', false ) ? wc_clean( $_POST['city'] ) : '';

        if ( $postcode && ! WC_Validation::is_postcode( $postcode, $country ) ) {
            throw new Exception( __( 'Please enter a valid postcode / ZIP.', 'woocommerce' ) );
        } elseif ( $postcode ) {
            $postcode = wc_format_postcode( $postcode, $country );
        }

        if ( $country ) {

            WC()->customer->set_location( $country, $state, $postcode, $city );
            WC()->customer->set_shipping_location( $country, $state, $postcode, $city );
        } else {
            WC()->customer->set_to_base();
            WC()->customer->set_shipping_to_base();
        }

        WC()->customer->set_calculated_shipping( true );
        WC()->customer->save();

        do_action( 'woocommerce_calculated_shipping' );

        $cu = get_woocommerce_currency_symbol();
        WC()->shipping->calculate_shipping( WC()->cart->get_shipping_packages() );
	$packages = WC()->shipping->get_packages();

        if(count($packages ) > 0){
            $result["result"] = 1;
            $message = "<ul>";
            foreach ( $packages as $i => $package ) {
                if(count($package['rates']) > 0){
                    foreach($package['rates'] as $k => $v){
                        $message .= "<center><h4><strong>".$v->label." - ".$v->cost." ".$cu."</strong></h4></center>";
                    }
                }
            }
            $result["message"] = $message ;
        }
    } catch ( Exception $e ) {

        $result["result"] = 0;
        $result["message"] = $e->getMessage() ;
    }

    echo json_encode($result);
    die();
}

function mk_woo_shipping_calculator_shortcode() {
    global $shortcode_times;
    $shortcode_times++;

    if($shortcode_times > 1){
        return "";
    }

    wp_enqueue_script(  'wc-cart' );
    ob_start();

    do_action( 'woocommerce_before_shipping_calculator' );
?>

<form>

	<section class="shipping-calculator-form-shortcode" >

		<p class="form-row form-row-wide" id="calc_shipping_country_field">
			<select name="calc_shipping_country" id="calc_shipping_country" class="country_to_state" rel="calc_shipping_state">
				<option value=""><?php _e( 'Select a country…', 'woocommerce' ); ?></option>
				<?php
					foreach ( WC()->countries->get_shipping_countries() as $key => $value )
						echo '<option value="' . esc_attr( $key ) . '"' . selected( WC()->customer->get_shipping_country(), esc_attr( $key ), false ) . '>' . esc_html( $value ) . '</option>';
				?>
			</select>
		</p>

		<p class="form-row form-row-wide" id="calc_shipping_state_field">
			<?php
				$current_cc = WC()->customer->get_shipping_country();
				$current_r  = WC()->customer->get_shipping_state();
				$states     = WC()->countries->get_states( $current_cc );
				// Hidden Input
				if ( is_array( $states ) && empty( $states ) ) {
					?><input type="hidden" name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" /><?php
				// Dropdown Input
				} elseif ( is_array( $states ) ) {
					?><span>
						<select name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>">
							<option value=""><?php esc_html_e( 'Select a state…', 'woocommerce' ); ?></option>
							<?php
								foreach ( $states as $ckey => $cvalue )
									echo '<option value="' . esc_attr( $ckey ) . '" ' . selected( $current_r, $ckey, false ) . '>' . esc_html( $cvalue ) . '</option>';
							?>
						</select>
					</span><?php
				// Standard Input
				} else {
					?><input type="text" class="input-text" value="<?php echo esc_attr( $current_r ); ?>" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" name="calc_shipping_state" id="calc_shipping_state" /><?php
				}
			?>
		</p>

		<?php if ( apply_filters( 'woocommerce_shipping_calculator_enable_city', false ) ) : ?>

			<p class="form-row form-row-wide" id="calc_shipping_city_field">
				<input type="text" class="input-text" value="<?php echo esc_attr( WC()->customer->get_shipping_city() ); ?>" placeholder="<?php esc_attr_e( 'City', 'woocommerce' ); ?>" name="calc_shipping_city" id="calc_shipping_city" />
			</p>

		<?php endif; ?>

		<?php if ( apply_filters( 'woocommerce_shipping_calculator_enable_postcode', true ) ) : ?>

			<p class="form-row form-row-wide" id="calc_shipping_postcode_field">
				<input type="text" class="input-text" value="<?php echo esc_attr( WC()->customer->get_shipping_postcode() ); ?>" placeholder="<?php esc_attr_e( 'Postcode / ZIP', 'woocommerce' ); ?>" name="calc_shipping_postcode" id="calc_shipping_postcode" />
			</p>

		<?php endif; ?>

		<p><button  value="1" class="button mk-woo-shipping-calculator"><?php _e( 'Update totals', 'woocommerce' ); ?></button><span id="mk-woo-shipping-calculator-loading" style="display:none"><img src='<?php echo plugins_url( '/files/default.gif', __FILE__ ) ?>' /></span></p>

		<?php wp_nonce_field( 'woocommerce-cart' ); ?>
                <div id="mk-woo-shipping-result">

                </div>
	</section>
</form>
<script type="text/javascript">
var $s = jQuery.noConflict();
$s(document).ready(function($) {
    $(".mk-woo-shipping-calculator").click(function(){
        var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
        var country = $(this).parent().parent().find("#calc_shipping_country").val();
        var state = $(this).parent().parent().find("#calc_shipping_state").val();
        var city = $(this).parent().parent().find("#calc_shipping_city").val();
        var postcode = $(this).parent().parent().find("#calc_shipping_postcode").val();
        $("#mk-woo-shipping-calculator-loading").show();
        var data = {'action': 'mk_woo_shipping_calculator','country': country,'state': state,'city': city,'postcode': postcode};
        $.post("<?php echo get_home_url(); ?>", data, function(response) {
            $("#mk-woo-shipping-calculator-loading").hide();
            response = JSON.parse(response);
            if(response.result == 1){
                $("#mk-woo-shipping-result").html(response.message);
            }else{
                alert(response.message);
                $("#mk-woo-shipping-result").html("");
            }

            return false;
        });
        return false;
    });
});
</script>
<?php
do_action( 'woocommerce_after_shipping_calculator' ); 

$out = ob_get_contents();
ob_end_clean();

return $out;

}
add_shortcode('calculadora-envio', 'mk_woo_shipping_calculator_shortcode');

Este snippet de código como tal, sólo crea el shortcode [calculadora-envio] para incrustar la calculadora de envío haya donde la necesites. Pero para incluirla en la ficha de producto, puedes seguir dos aproximaciones distintas:

La primera, incluir el shortcode de forma manual en la ficha de cada producto

Si tienes pocos productos en tu catálogo esta puede ser una solución rápida y sencilla. No tiene más complicación que insertar el shortcode [calculadora-envio] en el lugar de la ficha de producto que quieres que aparezca. ¡Fácil y simple!

La segunda, insertar el shortcode en la ficha de producto a través de Booster

La segunda aproximación es la forma más rápida de aplicar el shortcode si quieres hacerlo condicionalmente. Quizá no quieres aplicar la calculadora de envíos en todos los productos, y sólo quieres que aparezca en una categoría concreta. O en todos los productos excepto algunos. Con Booster, la extensión que te permite personalizar WooCommerce sin tocar una línea de código, es sumamente sencillo.

Una vez instalado y activado el plugin, solo tienes que dirigirte a WooCommerce > Ajustes del Booster > Productos > Product info > Ajustes. Una vez que estés en el panel de Product info, sólo tienes que:

  • Activar el módulo
  • Dentro de páginas de producto, establece el campo Total blocks en 1
  • Dentro del Contenido inserta el shortcode [calculadora-envio]
  • Selecciona la posición en la que quieres insertar el bloque
  • Y guarda los cambios
calculadora-de-envio-en-productos-de-woocommerce-booster-plus
Insertar contenidos en la ficha de productos con Booster es muy sencillo.

¡Así de simple y así de fácil!

Si te ha gustado este tutorial, recuerda que si te suscribes, tendrás acceso a todo el contenido premium.

Y como siempre, si tienes cualquier problema, no dudes en contactar conmigo. Nos vemos en la próxima entrega, con un nuevo tutorial. 😉

Author avatar
Ángel Martín
Ayudo a emprendedores y empresas a digitalizar su negocio y sus procesos optimizando sus costes.