سبد خرید ۰
سبد خرید خالی است

افزودن گزینه‌های اضافی (Addons) به محصولات ووکامرس

افزودن به علاقه مندی

شاید براتون پیش اومده باشه که بخواید برای یک محصول در ووکامرس چند گزینه اضافی (مثل نصب و راه‌اندازی، پشتیبانی، آموزش و…) تعریف کنید و قیمت این گزینه‌ها رو به صورت داینامیک به قیمت محصول اضافه کنید.

در این آموزش، یه کد حرفه‌ای براتون آماده کردم که:

✅ گزینه‌های اضافی رو به صورت داینامیک برای هر محصول ایجاد می‌کنید.
✅ امکان تعیین تخفیف درصدی برای هر گزینه وجود داره.
✅ موقع تیک زدن گزینه‌ها، قیمت محصول به صورت زنده (Ajax) تغییر می‌کنه.
✅ قیمت نهایی محصول به همراه گزینه‌ها در سبد خرید و پرداخت درست جمع‌بندی می‌شه.

کاربرد این قابلیت

  • فروش خدمات جانبی مثل نصب و آموزش
  • ارائه پشتیبانی‌های خاص
  • فروش ماژول‌ها یا لایسنس‌های اضافی به همراه محصول

آموزش قدم‌به‌قدم

  1. قرار دادن کد

کد زیر رو توی فایل functions.php قالب فرزندتون یا افزونه اختصاصی بذارید:

PHP
// ✅ متاباکس مدیریت محصول
add_action('woocommerce_product_options_general_product_data', 'custom_product_addons_fields');
function custom_product_addons_fields() {
    global $post;
    echo '<div class="options_group">';
    echo '<p><strong>گزینه‌های اضافی محصول (تخفیف‌دار)</strong></p>';

    $addons = get_post_meta($post->ID, '_custom_product_addons', true);
    if (!is_array($addons)) {
        $addons = array(array('title' => '', 'price' => '', 'discount' => ''));
    }

    echo '<div id="custom-addons-wrapper">';
    foreach ($addons as $index => $addon) {
        ?>
        <div class="custom-addon" style="margin-bottom:15px; padding:10px; border:1px solid #ddd;">
            <p>
                <label>عنوان گزینه:</label>
                <input type="text" name="custom_addons[<?php echo $index; ?>][title]" value="<?php echo esc_attr($addon['title']); ?>" style="width:25%;" placeholder="مثال: نصب و راه‌اندازی" />
                 
                <label>قیمت:</label>
                <input type="number" name="custom_addons[<?php echo $index; ?>][price]" value="<?php echo esc_attr($addon['price']); ?>" style="width:15%;" placeholder="مثال: 100000" />
                 
                <label>درصد تخفیف (اختیاری):</label>
                <input type="number" name="custom_addons[<?php echo $index; ?>][discount]" value="<?php echo isset($addon['discount']) ? esc_attr($addon['discount']) : ''; ?>" style="width:15%;" placeholder="مثال: 10 (برای 10٪)" />
                <button type="button" class="remove-addon button">حذف</button>
            </p>
            <small style="color: #555;">🔹 درصد تخفیف اختیاری است؛ اگر خالی بگذارید تخفیف اعمال نمی‌شود.</small>
        </div>
        <?php
    }
    echo '</div>';
    echo '<p><button type="button" class="add-addon button">+ گزینه جدید</button></p>';
    ?>
    <script>
    jQuery(function($){
        var wrapper = $('#custom-addons-wrapper');
        var index = <?php echo count($addons); ?>;
        $('.add-addon').on('click', function(e){
            e.preventDefault();
            var html = '<div class="custom-addon" style="margin-bottom:15px; padding:10px; border:1px solid #ddd;">' +
                '<p>' +
                '<label>عنوان گزینه:</label> ' +
                '<input type="text" name="custom_addons['+index+'][title]" style="width:25%;" placeholder="مثال: نصب و راه‌اندازی" /> ' +
                '  <label>قیمت:</label> ' +
                '<input type="number" name="custom_addons['+index+'][price]" style="width:15%;" placeholder="مثال: 100000" /> ' +
                '  <label>درصد تخفیف (اختیاری):</label> ' +
                '<input type="number" name="custom_addons['+index+'][discount]" style="width:15%;" placeholder="مثال: 10 (برای 10٪)" /> ' +
                '<button type="button" class="remove-addon button">حذف</button>' +
                '</p>' +
                '<small style="color: #555;">🔹 درصد تخفیف اختیاری است؛ اگر خالی بگذارید تخفیف اعمال نمی‌شود.</small>' +
                '</div>';
            wrapper.append(html);
            index++;
        });
        wrapper.on('click', '.remove-addon', function(e){
            e.preventDefault();
            $(this).closest('.custom-addon').remove();
        });
    });
    </script>
    <?php
    echo '</div>';
}

// ✅ ذخیره متا
add_action('woocommerce_process_product_meta', 'custom_product_addons_fields_save');
function custom_product_addons_fields_save($post_id) {
    if (isset($_POST['custom_addons'])) {
        $addons = array();
        foreach ($_POST['custom_addons'] as $addon) {
            if (!empty($addon['title']) && isset($addon['price'])) {
                $addons[] = array(
                    'title' => sanitize_text_field($addon['title']),
                    'price' => floatval($addon['price']),
                    'discount' => isset($addon['discount']) ? intval($addon['discount']) : 0
                );
            }
        }
        update_post_meta($post_id, '_custom_product_addons', $addons);
    } else {
        delete_post_meta($post_id, '_custom_product_addons');
    }
}

// ✅ نمایش گزینه‌ها + آپدیت زنده قیمت
add_action('woocommerce_before_add_to_cart_button', 'custom_product_addons_display');
function custom_product_addons_display() {
    global $product;
    $addons = get_post_meta($product->get_id(), '_custom_product_addons', true);
    if (!is_array($addons) || empty($addons)) return;

    echo '<div class="custom-product-addons" style="margin-top:15px;">';
    foreach ($addons as $index => $addon) {
        $original_price = $addon['price'];
        $discount = isset($addon['discount']) ? $addon['discount'] : 0;
        $final_price = $original_price;

        if ($discount > 0 && $discount < 100) {
            $final_price = $original_price - ($original_price * $discount / 100);
        }

        echo '<div class="custom-addon-option" style="margin-bottom:10px; display:flex; align-items:center; gap:10px;">';
        echo '<label style="cursor:pointer; display:flex; align-items:center; gap:10px;">';
        echo '<input type="checkbox" name="addon_option['.$index.']" value="'.esc_attr($final_price).'" data-price="'.esc_attr($final_price).'" class="addon-checkbox"> ';
        echo esc_html($addon['title']);
        echo '</label>';

        // ✅ فقط کلاس‌ها - بدون استایل اینلاین
        echo '<div class="custom-addon-price-wrap">';
        if ($discount > 0) {
            echo '<span class="discount-badge">'.$discount.'%</span>';
            echo '<span class="original-price">'.wc_price($original_price).'</span>';
        }
        echo '<span class="final-price">+'.wc_price($final_price).'</span>';
        echo '</div>';

        echo '</div>';
    }
    echo '</div>';

    // ✅ جاوااسکریپت برای تغییر زنده قیمت
    ?>
    <script>
    jQuery(function($){
        var basePrice = <?php echo floatval($product->get_price()); ?>;
        var priceDisplay = $('.my-pricesj').first(); // 👈 مطمئن شو این کلاس توی قالب هست
        var bdi = priceDisplay.find('bdi');

        $('.addon-checkbox').on('change', function(){
            var totalExtra = 0;
            $('.addon-checkbox:checked').each(function(){
                totalExtra += parseFloat($(this).data('price'));
            });
            var newTotal = basePrice + totalExtra;
            if(bdi.length) {
                bdi.text(newTotal.toLocaleString() + ' تومان');
            } else {
                priceDisplay.html('<bdi>' + newTotal.toLocaleString() + ' تومان</bdi>');
            }
        });
    });
    </script>
    <?php
}

2. استایل (CSS)

حتما این CSS رو هم بذارید که استایل شیک باشه:

CSS
.custom-addon-price-wrap {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    text-align: left;
}

.custom-addon-price-wrap .original-price {
    font-size: 11px;
    color: #a0a0a0;
    text-decoration: line-through;
    opacity: 0.8;
}

.custom-addon-price-wrap .discount-line {
    display: flex;
    align-items: center;
    gap: 6px;
}

.custom-addon-price-wrap .discount-badge {
    background: #ffb700;
    color: #fff;
    font-size: 11px;
    padding: 2px 6px;
    border-radius: 4px;
    font-weight: bold;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 20px;
    min-width: 30px;
    text-align: center;
    line-height: 1;
}

.custom-addon-price-wrap .final-price {
    font-weight: bold;
    font-size: 14px;
    color: #555;
}

نکته مهم

  • برای تغییر قیمت به صورت زنده، یه کلاس به قیمت اصلی محصول بدید (مثلاً .my-pricesj) تا جاوااسکریپت راحت بتونه آپدیت کنه.
  • اگر قالب خاصی دارید و استایل متفاوت خواستید، می‌تونید CSS رو به سلیقه خودتون ویرایش کنید.

نمونه

Screenshot 2025 05 25 150706

Screenshot 2025 05 25 150638

این روش یک راه ساده و قوی برای فروش گزینه‌های جانبی همراه محصولاته، بدون اینکه نیاز به افزونه‌های سنگین باشه.
امیدوارم براتون مفید باشه 💙 اگر سوالی داشتید توی کامنت‌ها بپرسید.

اشتراک گذاری این مطلب
گفت‌وگو و پرسش‌ها

1 دیدگاه

دیدگاه خود را بنویسید

پرسش یا تجربه خود را بنویسید. پاسخ شما پس از بررسی منتشر می‌شود.