How to Add a Custom Price Break-Up in WooCommerce
Support for Making Charges, GST, and Extra Taxes for Simple and Variable Products.
Overview
By default, WooCommerce allows you to set a single price for a product. However, for industries like jewelry, electronics, or specialized manufacturing, you often need to show a clear Price Break-up. This includes manufacturing costs (Making Charges), government taxes (GST), and additional surcharges.
This tutorial provides a complete PHP solution to integrate these fields directly into your WooCommerce dashboard and display them automatically on the front end.
How It Works
- Admin Integration: New fields are added to both Simple and Variable product settings.
- Dynamic Logic: The GST field can be set as a Fixed Amount or a Percentage of the base price.
- Cart Recalculation: The plugin hooks into
woocommerce_before_calculate_totalsto ensure the cart total reflects the sum of the base price and all additional charges. - Checkout Transparency: All extra charges are listed as metadata in the cart and checkout pages so customers know exactly what they are paying for.
The Plugin Code
Copy the code below into a new file named woocommerce-price-breakup.php and upload it to your wp-content/plugins folder, or paste it into your theme's functions.php file.
<?php
/**
* Plugin Name: WooCommerce Price Break-Up
* Description: Adds Making Charge, GST (fixed or %), and Extra Tax with cart, checkout & variable product support.
* Version: 1.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/* ======================================================
* SIMPLE PRODUCT FIELDS
* ====================================================== */
add_action( 'woocommerce_product_options_pricing', 'prefix_add_simple_price_breakup_fields' );
function prefix_add_simple_price_breakup_fields() {
woocommerce_wp_text_input( array(
'id' => '_making_charge',
'label' => 'Making Charge',
'type' => 'number',
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
woocommerce_wp_select( array(
'id' => '_gst_type',
'label' => 'GST Type',
'options' => array(
'fixed' => 'Fixed',
'percent' => 'Percentage',
),
) );
woocommerce_wp_text_input( array(
'id' => '_gst_amount',
'label' => 'GST Value',
'type' => 'number',
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
woocommerce_wp_text_input( array(
'id' => '_extra_tax',
'label' => 'Extra Tax',
'type' => 'number',
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
}
/* ======================================================
* SAVE SIMPLE PRODUCT
* ====================================================== */
add_action( 'woocommerce_admin_process_product_object', 'prefix_save_simple_price_breakup_fields' );
function prefix_save_simple_price_breakup_fields( $product ) {
$product->update_meta_data( '_making_charge', wc_clean( $_POST['_making_charge'] ?? 0 ) );
$product->update_meta_data( '_gst_type', wc_clean( $_POST['_gst_type'] ?? 'fixed' ) );
$product->update_meta_data( '_gst_amount', wc_clean( $_POST['_gst_amount'] ?? 0 ) );
$product->update_meta_data( '_extra_tax', wc_clean( $_POST['_extra_tax'] ?? 0 ) );
}
/* ======================================================
* VARIATION FIELDS
* ====================================================== */
add_action( 'woocommerce_variation_options_pricing', 'prefix_add_variation_price_breakup_fields', 10, 3 );
function prefix_add_variation_price_breakup_fields( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input( array(
'id' => '_making_charge[' . $variation->ID . ']',
'label' => 'Making Charge',
'type' => 'number',
'value' => get_post_meta( $variation->ID, '_making_charge', true ),
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
woocommerce_wp_select( array(
'id' => '_gst_type[' . $variation->ID . ']',
'label' => 'GST Type',
'value' => get_post_meta( $variation->ID, '_gst_type', true ),
'options' => array(
'fixed' => 'Fixed',
'percent' => 'Percentage',
),
) );
woocommerce_wp_text_input( array(
'id' => '_gst_amount[' . $variation->ID . ']',
'label' => 'GST Value',
'type' => 'number',
'value' => get_post_meta( $variation->ID, '_gst_amount', true ),
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
woocommerce_wp_text_input( array(
'id' => '_extra_tax[' . $variation->ID . ']',
'label' => 'Extra Tax',
'type' => 'number',
'value' => get_post_meta( $variation->ID, '_extra_tax', true ),
'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
) );
}
/* ======================================================
* SAVE VARIATIONS
* ====================================================== */
add_action( 'woocommerce_save_product_variation', 'prefix_save_variation_price_breakup_fields', 10, 2 );
function prefix_save_variation_price_breakup_fields( $variation_id, $i ) {
update_post_meta( $variation_id, '_making_charge', wc_clean( $_POST['_making_charge'][ $variation_id ] ?? 0 ) );
update_post_meta( $variation_id, '_gst_type', wc_clean( $_POST['_gst_type'][ $variation_id ] ?? 'fixed' ) );
update_post_meta( $variation_id, '_gst_amount', wc_clean( $_POST['_gst_amount'][ $variation_id ] ?? 0 ) );
update_post_meta( $variation_id, '_extra_tax', wc_clean( $_POST['_extra_tax'][ $variation_id ] ?? 0 ) );
}
/* ======================================================
* PRICE CALCULATION (CART)
* ====================================================== */
add_action( 'woocommerce_before_calculate_totals', 'prefix_apply_price_breakup_cart', 20 );
function prefix_apply_price_breakup_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['breakup_done'] ) ) {
continue;
}
$product = $cart_item['data'];
$product_id = $product->get_id();
$base = (float) $product->get_price();
$making = (float) get_post_meta( $product_id, '_making_charge', true );
$gst_type = get_post_meta( $product_id, '_gst_type', true );
$gst_val = (float) get_post_meta( $product_id, '_gst_amount', true );
$extra = (float) get_post_meta( $product_id, '_extra_tax', true );
$gst = ( $gst_type === 'percent' ) ? ( $base * $gst_val / 100 ) : $gst_val;
$product->set_price( $base + $making + $gst + $extra );
$cart_item['breakup_done'] = true;
}
}
/* ======================================================
* SINGLE PRODUCT PAGE BREAKUP
* ====================================================== */
add_action( 'woocommerce_before_add_to_cart_form', 'prefix_show_price_breakup_single' );
function prefix_show_price_breakup_single() {
global $product;
$id = $product->get_id();
$base = (float) $product->get_price();
$making = (float) get_post_meta( $id, '_making_charge', true );
$gst_type = get_post_meta( $id, '_gst_type', true );
$gst_val = (float) get_post_meta( $id, '_gst_amount', true );
$extra = (float) get_post_meta( $id, '_extra_tax', true );
if ( ! $making && ! $gst_val && ! $extra ) {
return;
}
$gst = ( $gst_type === 'percent' ) ? ( $base * $gst_val / 100 ) : $gst_val;
?>
<div class="wc-price-breakup" style="margin: 20px 0; padding: 15px; border: 1px dashed #ccc; border-radius: 5px; background: #fafafa;">
<strong>Price Break-up</strong>
<ul style="list-style: none; padding: 0; margin: 10px 0 0 0;">
<?php if ( $making ) : ?><li>Making Charge: <?php echo wc_price( $making ); ?></li><?php endif; ?>
<?php if ( $gst ) : ?><li>GST: <?php echo wc_price( $gst ); ?></li><?php endif; ?>
<?php if ( $extra ) : ?><li>Extra Tax: <?php echo wc_price( $extra ); ?></li><?php endif; ?>
<li style="margin-top: 5px; border-top: 1px solid #ddd; padding-top: 5px;"><strong>Final Price: <?php echo wc_price( $base + $making + $gst + $extra ); ?></strong></li>
</ul>
</div>
<?php
}
/* ======================================================
* CART + CHECKOUT DISPLAY
* ====================================================== */
add_filter( 'woocommerce_get_item_data', 'prefix_show_breakup_cart_checkout', 10, 2 );
function prefix_show_breakup_cart_checkout( $data, $cart_item ) {
$id = $cart_item['data']->get_id();
$base = (float) $cart_item['data']->get_price();
$making = (float) get_post_meta( $id, '_making_charge', true );
$gst_type = get_post_meta( $id, '_gst_type', true );
$gst_val = (float) get_post_meta( $id, '_gst_amount', true );
$extra = (float) get_post_meta( $id, '_extra_tax', true );
$gst = ( $gst_type === 'percent' ) ? ( $base * $gst_val / 100 ) : $gst_val;
if ( $making ) $data[] = array( 'name' => 'Making Charge', 'value' => wc_price( $making ) );
if ( $gst ) $data[] = array( 'name' => 'GST', 'value' => wc_price( $gst ) );
if ( $extra ) $data[] = array( 'name' => 'Extra Tax', 'value' => wc_price( $extra ) );
return $data;
}
0 Comments