How to Show Installment Payments on WooCommerce Product Pages

If you’re looking to add custom functionality to your WooCommerce store, such as creating a new submenu and installment settings, you can either use the Code Snippets plugin or add the code directly to your theme’s functions.php file. Below is a step-by-step guide on both methods.

Video: Quick fix #15 – #How to Show Installment Payments on WooCommerce Product Pages

Step 1: Install Code Snippets Plugin

Adding custom code through the Code Snippets plugin is recommended for a few reasons:

1. Safety: Code Snippets makes it easy to manage your code in one place and keeps you from editing core theme files like functions.php, which could break your site if done incorrectly.

2. Error Handling: If your custom code causes an error, Code Snippets allows you to safely disable the snippet through the WordPress dashboard, preventing your entire site from crashing.

3. Portability: Since snippets are independent of your theme, you won’t lose them when switching themes, which could happen if you add them directly to functions.php.

Step 2: Using the Code Snippets Plugin

1. Install the Plugin:

• Go to your WordPress dashboard and navigate to Plugins > Add New.

• Search for Code Snippets.

• Install and activate the plugin.

2. Add Your Custom Code:

• Once the plugin is installed, go to Snippets > Add New.

• Give your snippet a name (e.g., “WooCommerce Installment Settings”).

• Copy and paste the code

// Add submenu under WooCommerce
add_action('admin_menu', 'custom_add_woocommerce_submenu', 99);
function custom_add_woocommerce_submenu() {
    add_submenu_page(
        'woocommerce', // parent slug
        'Installment Settings', // page title
        'Installments', // menu title
        'manage_options', // capability
        'monthly-payment-settings', // menu slug
        'custom_monthly_payment_settings_page' // callback function
    );
}

// Settings page content
function custom_monthly_payment_settings_page() {
    if (!current_user_can('manage_options')) {
        wp_die(__('You do not have sufficient permissions to access this page.'));
    }

    $error_message = '';

    // Save settings if form is submitted
    if (isset($_POST['custom_interest_rate']) && isset($_POST['custom_duration_months'])) {
        check_admin_referer('custom_save_settings');

        $interest_rate = sanitize_text_field($_POST['custom_interest_rate']);
        $duration_months = sanitize_text_field($_POST['custom_duration_months']);
        
        $interest_rate = floatval($interest_rate);
        $duration_months = intval($duration_months);

        if ($interest_rate <= 0) {
            $error_message .= '<p>Please set an interest rate greater than zero.</p>';
        }
        if ($duration_months <= 0) {
            $error_message .= '<p>Please set a duration greater than zero.</p>';
        }

        if (!$error_message) {
            update_option('custom_interest_rate', $interest_rate);
            update_option('custom_duration_months', $duration_months);
            echo '<div class="updated"><p>Settings saved.</p></div>';
        } else {
            echo '<div class="error">' . $error_message . '</div>';
        }
    }

    // Get current values
    $interest_rate = get_option('custom_interest_rate', '5');
    $duration_months = get_option('custom_duration_months', '12');
    ?>
    <div class="wrap">
        <h1>Installment Settings</h1>
        <form method="post" action="">
            <?php wp_nonce_field('custom_save_settings'); ?>
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">Interest Rate (% per year)</th>
                    <td><input type="number" step="0.01" min="0.01" name="custom_interest_rate" value="<?php echo esc_attr($interest_rate); ?>" required /></td>
                </tr>
                <tr valign="top">
                    <th scope="row">Duration (months)</th>
                    <td><input type="number" min="1" name="custom_duration_months" value="<?php echo esc_attr($duration_months); ?>" required /></td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

// Display the monthly payment on the single product page
function custom_display_monthly_payment() {
    if (!is_product()) {
        return; // Only run on single product pages
    }

    global $product;

    $interest_rate = floatval(get_option('custom_interest_rate', '5'));
    $duration_months = intval(get_option('custom_duration_months', '12'));

    if ($interest_rate <= 0 || $duration_months <= 0) {
        return; // Don't display if invalid settings
    }

    if ($product->is_type('variable')) {
        add_action('woocommerce_single_variation', 'custom_variable_product_monthly_payment', 10);
    } else {
        $price = floatval($product->get_price());
        $monthly_payment = custom_calculate_monthly_payment($price, $interest_rate, $duration_months);

        // Get currency details
        $currency_symbol = get_woocommerce_currency_symbol();
        $currency_position = get_option('woocommerce_currency_pos');
        $decimal_separator = wc_get_price_decimal_separator();
        $thousand_separator = wc_get_price_thousand_separator();
        $number_of_decimals = wc_get_price_decimals();

        // Format the amount
        $formatted_amount = number_format($monthly_payment, $number_of_decimals, $decimal_separator, $thousand_separator);

        // Build the price with currency symbol and proper spacing
        switch ($currency_position) {
            case 'left':
                $price_with_symbol = $currency_symbol . $formatted_amount;
                break;
            case 'right':
                $price_with_symbol = $formatted_amount . $currency_symbol;
                break;
            case 'left_space':
                $price_with_symbol = $currency_symbol . ' ' . $formatted_amount;
                break;
            case 'right_space':
                $price_with_symbol = $formatted_amount . ' ' . $currency_symbol;
                break;
            default:
                $price_with_symbol = $currency_symbol . $formatted_amount;
                break;
        }

        // Display the formatted monthly payment with a tooltip
        echo '<p class="monthly_payment">';
        echo '<span class="monthly_payment_tooltip" data-tooltip="The interest rate is ' . esc_attr($interest_rate) . '% for a duration of ' . esc_attr($duration_months) . ' months">';
        echo '<span class="tooltip_icon">';
        echo '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="24" height="24">';
        echo '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />';
        echo '</svg>';
        echo '</span></span> ';
        echo 'Installments: ' . $price_with_symbol . ' per month';
        echo '</p>';
    }
}
add_action('woocommerce_single_product_summary', 'custom_display_monthly_payment', 15);

function custom_calculate_monthly_payment($price, $interest_rate, $duration_months) {
    $annual_rate_decimal = $interest_rate / 100;
    $total_interest = $price * $annual_rate_decimal * ($duration_months / 12);
    $total_amount = $price + $total_interest;
    return round($total_amount / $duration_months, 2);
}

function custom_variable_product_monthly_payment() {
    echo '<p class="monthly_payment"></p>';
}

// Enqueue scripts and styles for monthly payment tooltip
add_action('wp_enqueue_scripts', 'custom_enqueue_inline_scripts');
function custom_enqueue_inline_scripts() {
    if (!is_product()) {
        return; // Only run scripts on single product pages
    }

    wp_register_script('custom-inline-script', '', array('jquery'), null, true);
    wp_enqueue_script('custom-inline-script');

    $params = array(
        'interest_rate' => floatval(get_option('custom_interest_rate', '5')),
        'duration_months' => intval(get_option('custom_duration_months', '12')),
        'currency_symbol' => get_woocommerce_currency_symbol(),
        'currency_position' => get_option('woocommerce_currency_pos')
    );
    wp_localize_script('custom-inline-script', 'custom_params', $params);

    wp_add_inline_script('custom-inline-script', custom_js_code());
    wp_register_style('custom-inline-style', false);
    wp_enqueue_style('custom-inline-style');
    wp_add_inline_style('custom-inline-style', custom_css());
}

function custom_js_code() {
    return <<<JS
jQuery(function($) {
    $('.variations_form').on('found_variation', function(event, variation) {
        var price = variation.display_price;
        var interest_rate = parseFloat(custom_params.interest_rate);
        var duration_months = parseInt(custom_params.duration_months);

        if (interest_rate <= 0 || duration_months <= 0) {
            $('.single_variation_wrap .monthly_payment').html('');
            return;
        }

        var total_interest = price * (interest_rate / 100) * (duration_months / 12);
        var total_amount = price + total_interest;
        var monthly_payment = (total_amount / duration_months).toFixed(2);
        var formatted_payment = wc_price_format(monthly_payment, custom_params.currency_symbol, custom_params.currency_position);

        var tooltip_html = '<span class="monthly_payment_tooltip" data-tooltip="The interest rate is ' + interest_rate + '% for a duration of ' + duration_months + ' months">';
        tooltip_html += '<span class="tooltip_icon">';
        tooltip_html += '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" width="24" height="24">';
        tooltip_html += '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />';
        tooltip_html += '</svg>';
        tooltip_html += '</span></span> ';

        $('.single_variation_wrap .monthly_payment').html(tooltip_html + 'Installments: ' + formatted_payment + ' per month');
    });
    $('.variations_form').on('reset_data', function() {
        $('.single_variation_wrap .monthly_payment').html('');
    });
});

function wc_price_format(price, symbol, position) {
    switch(position) {
        case 'left': return symbol + price;
        case 'right': return price + symbol;
        case 'left_space': return symbol + ' ' + price;
        case 'right_space': return price + ' ' + symbol;
        default: return symbol + price;
    }
}
JS;
}

function custom_css() {
    return '
    .monthly_payment {
        display: flex;
        font-size: 14px;
        align-items: center;
        margin-top: -1.5em;
    }
    .tooltip_icon {
        display: inline-block;
        width: 24px;
        height: 24px;
        padding: 2px;
        box-sizing: border-box;
        vertical-align: middle;
    }
    .tooltip_icon svg {
        width: 100%;
        height: 100%;
        stroke: currentColor;
        stroke-width: 1.5;
    }
    .monthly_payment_tooltip {
        position: relative;
        cursor: pointer;
        display: inline-block;
        vertical-align: middle;
        margin-right: 5px;
    }
    .monthly_payment_tooltip::after {
        content: attr(data-tooltip);
        position: absolute;
        left: 50%;
        bottom: 125%;
        transform: translateX(-50%);
        background: #333;
        color: #fff;
        padding: 5px;
        white-space: nowrap;
        z-index: 1000;
        border-radius: 5px;
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s;
        pointer-events: none;
    }
    .monthly_payment_tooltip::before {
        content: "";
        position: absolute;
        left: 50%;
        bottom: 115%;
        transform: translateX(-50%);
        border-width: 5px;
        border-style: solid;
        border-color: transparent transparent #333 transparent;
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.2s;
        pointer-events: none;
    }
    .monthly_payment_tooltip:hover::after,
    .monthly_payment_tooltip:hover::before {
        opacity: 1;
        visibility: visible;
    }';
}

• Choose Only run in the administration area for backend-related code or Run Everywhere if it applies to the frontend as well (in this case, you’ll need the code to run everywhere).

• Save and activate the snippet.

Alternative Step 2: Using the functions.php File

If you prefer, you can add the code directly to your theme’s functions.php file. However, this is less flexible and comes with some risks, so proceed cautiously.

1. Access the functions.php File:

• In your WordPress dashboard, go to Appearance > Theme File Editor.

• Select Theme Functions (functions.php) from the right-hand menu.

2. Add the Code:

• Scroll to the bottom of the file (but before the closing PHP tag if present) and paste the provided code.

Save your changes.

Note: Be careful when editing functions.php. If there’s a syntax error, it could bring down your entire site. Always back up your file before making any changes.

Code Explanation

The provided code adds a custom WooCommerce submenu labeled “Installments” under WooCommerce settings. Users can configure the interest rate and duration for installment plans through the settings page. The code also calculates and displays the monthly payment on the product page.

Using the Code Snippets plugin is a more reliable and easier way to manage custom functionality, especially if you’re unfamiliar with PHP or editing theme files.

Here are some of my favorite WordPress tools

Thanks for reading this article! I hope it's been useful as you work on your own websites and e-commerce sites. I wanted to share some tools I use as a WordPress developer, and I think you'll find them helpful too.

Just so you know, these are affiliate links. If you decide to use any of them, I'll earn a commission. This helps me create tutorials and YouTube videos. But honestly, I genuinely use and recommend these tools to my friends and family as well. Your support keeps me creating content that benefits everyone.

Themes: Over the past few years, I've consistently relied on two primary themes for all sorts of projects: the Blocksy theme and the Kadence Theme. If you explore this website and my YouTube channel, you'll come across numerous tutorials that delve into these themes. If you're interested in obtaining a 10% discount for both of these themes, then:

Code Snippets Manager: WPCodeBox allows you to add code snippets to your site. Not only that, but it also provides you with the capability to construct and oversee your WordPress Code Snippets library right in the cloud. You can grab it with the 20% discount here (SAVE 20% Coupon: WPSH20).

Contact forms: There are hundreds of contact forms out there but Fluent Forms is the one I like the most. If you need a 20% discount then use this link (save 20% coupon is WPSH20).

Gutenberg add-ons: If I need a good Gutenberg blocks add-on then Kadence Blocks is the one I have used the most. You’ll get a 10% discount with the coupon SIMPLEHACKS here.

Website migration: While building a website you probably need a good plugin that can help you with the migration, backups, restoration, and staging sites. Well, WpVivid is the one I have used for the last couple of years. If you use this link along with the WPSH20 coupon you’ll get a 20% discount.

Woocommerce extensions: There are a bunch of Woocommerce extensions that I like but the one that stands out is Advanced Dynamic Pricing. Once again, you’ll get a 20% discount if you use this link here (save 20% coupon is WPSH20)

Web Hosting: If you would like to have a really fast and easy-to-use managed cloud hosting, then I recommend Verpex Hosting (see my review here). By the way, this site is hosted in Verpex.)

To see all my most up-to-date recommendations, check out this resource that I made for you!

Do you want to thank me and buy me a beer?

Every donation is entirely welcome but NEVER required. Enjoy my work for free but if you would like to thank me and buy me a beer or two then you can use this form here below.

Donation Form (#2)

Janek T.
Janek T.

Improve this text: {CLIPBOARD}

- I have been passionate about Wordpress since 2011, creating websites and sharing valuable tips on using Wordpress and Woocommerce on my site.
- Be the first to receive notifications about new tutorials by subscribing to my Youtube channel .
- Follow me on Twitter here

Articles: 119