In the new block styles, it is missing a percentage discount block that you can put on some places on the schema of a page or a query loop.
Also, it is important to have one in the upsells and crossells loops.
I have created a shortcode for that:
add_shortcode( ‘scuento’, function( $atts ) {
global $product;
if ( ! is_a( $product, ‘WC_Product’ ) || ! $product->is_on_sale() ) {
return ”;
}
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
if ( $product->is_type( ‘variable’ ) ) {
$regular_price = (float) $product->get_variation_regular_price( ‘min’ );
$sale_price = (float) $product->get_variation_sale_price( ‘min’ );
}
if ( $regular_price ”,
‘sufijo’ => ‘% OFF’,
‘color’ => ‘#ffffff’,
‘fondo’ => ‘red’,
‘padding’ => ‘4px 8px’,
‘radius’ => ‘4px’,
‘size’ => ’12px’,
‘weight’ => ‘700’,
], $atts );
$style = sprintf(
‘display:inline-block;background:%s;color:%s;padding:%s;border-radius:%s;font-size:%s;font-weight:%s;line-height:1;vertical-align:middle;margin:5px 0;’,
esc_attr( $atts[‘fondo’] ),
esc_attr( $atts[‘color’] ),
esc_attr( $atts[‘padding’] ),
esc_attr( $atts[‘radius’] ),
esc_attr( $atts[‘size’] ),
esc_attr( $atts[‘weight’] )
);
return sprintf(
‘%s-%d%s’,
$style,
esc_html( $atts[‘prefijo’] ),
$percent,
esc_html( $atts[‘sufijo’] )
);
});
And another for upsells:
add_filter( ‘woocommerce_get_price_html’, ‘agregar_porcentaje_solo_en_upsells’, 100, 2 );
function agregar_porcentaje_solo_en_upsells( $price, $product ) {
// 1. Si estamos en el admin, no hacer nada
if ( is_admin() ) {
return $price;
}
// 2. OBTENER EL ID DEL PRODUCTO PRINCIPAL (EL QUE EL USUARIO ESTÁ VISITANDO)
$queried_object = get_queried_object();
$current_page_product_id = ( is_product() && $queried_object ) ? $queried_object->ID : 0;
// 3. VALIDACIÓN CRÍTICA:
// Solo procedemos si el ID del producto actual del loop NO ES el ID de la página que estamos viendo.
// Esto hace que se salte el producto “Padre” y solo actúe en los productos de las listas de abajo (Upsells).
if ( $product->get_id() === $current_page_product_id ) {
return $price;
}
// 4. Si el producto no está en oferta, no hacer nada
if ( ! $product->is_on_sale() ) {
return $price;
}
// Calcular precios (Simples y Variables)
if ( $product->is_type( ‘variable’ ) ) {
$prices = $product->get_variation_prices();
$regular_price = max( $prices[‘regular_price’] );
$sale_price = min( $prices[‘sale_price’] );
} else {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
}
if ( $regular_price > 0 ) {
$percentage = round( ( ( floatval($regular_price) – floatval($sale_price) ) / floatval($regular_price) ) * 100 );
// Estilos Inline
$container_style = ‘display: block; margin-top: 8px; line-height: 1;’;
$badge_style = ‘background-color: #e20000; color: #ffffff; font-weight: bold; padding: 4px 8px; border-radius: 4px; font-size: 13px; display: inline-block; text-transform: uppercase;’;
$percentage_html = ”;
$percentage_html .= ‘-‘ . $percentage . ‘% OFF’;
$percentage_html .= ”;
return $price . $percentage_html;
}
return $price;
}
But this should be in the native woocommerce blocks imho.
I commented this in a thread: https://wordpress.org/support/topic/percentage-of-discount/?view=all#post-18901247
Open
Last updated: May 8, 2026
0 comments
Log in to comment on this feature request.