Atikullah Header

WooCommerce-এ ফেক অর্ডার কিভাবে বন্ধ করবেন প্লাগইন ছাড়াই (সম্পূর্ণ গাইড)

Atikullah Owner
Published September 9, 2026 Updated September 10, 2026 6 min read


বর্তমানে WooCommerce ওয়েবসাইট চালালে একটা সমস্যা প্রায় সবাই ফেস করে—ফেক অর্ডার। আপনি যতই ভালো প্রোডাক্ট বা মার্কেটিং করেন না কেন, যদি ভুয়া অর্ডার আসতেই থাকে, তাহলে ব্যবসার অনেক ক্ষতি হয়ে যায়।

আমি আপনাকে আজ এমন একটা সহজ সমাধান দেখাবো, যেটা ব্যবহার করলে আপনি প্লাগইন ছাড়াই ফেক অর্ডার অনেকটাই নিয়ন্ত্রণ করতে পারবেন—শুধু একটা PHP কোড ব্যবহার করে।


কেন ফেক অর্ডার আপনার জন্য ক্ষতিকর?

প্রথমেই বুঝে নেওয়া দরকার, এই সমস্যা এত সিরিয়াস কেন।

  • বারবার ভুয়া অর্ডার আসলে আপনার ড্যাশবোর্ড অগোছালো হয়ে যায়
  • COD (Cash on Delivery) একদম মিসইউজ হয়
  • একই নাম্বার বা ইমেইল দিয়ে স্প্যাম অর্ডার করা হয়
  • স্টক রিজার্ভ হয়ে থাকে, কিন্তু সেল কনভার্ট হয় না
  • আসল কাস্টমার প্রোডাক্ট পায় না

এক কথায়, আপনার পুরো সেলস সিস্টেমটাই নষ্ট হয়ে যেতে পারে।


কীভাবে এই সমস্যার সমাধান করবেন?

এখানে যে সিস্টেমটা আপনি ব্যবহার করবেন, সেটা আসলে কয়েকটা স্মার্ট চেকের উপর কাজ করে। আপনি ইউজারকে সরাসরি ব্লক না করে, তার অর্ডার আচরণ (behavior) অনুযায়ী নিয়ন্ত্রণ করবেন।


১. একই ডিভাইস থেকে একাধিক অর্ডার বন্ধ করুন

অনেক সময় একজন ইউজার একই ডিভাইস থেকে বারবার অর্ডার দেয়।
আপনি চাইলে সেটি এমনভাবে সেট করতে পারেন, যাতে আগের অর্ডার কমপ্লিট না হলে নতুন অর্ডার নিতে না পারে।

এতে করে স্প্যামিং অনেক কমে যাবে।


২. ইমেইল ও ফোন নাম্বার দিয়ে ব্লক

একই ফোন নাম্বার বা ইমেইল দিয়ে বারবার অর্ডার দেওয়া—এটা খুব কমন একটা সমস্যা।

আপনি সহজেই এমন রুল বসাতে পারেন:

  • যদি এই নাম্বার/ইমেইল দিয়ে কোনো পেন্ডিং অর্ডার থাকে তাহলে নতুন অর্ডার ব্লক করে দিবে।

৩. IP অ্যাড্রেস দিয়ে কন্ট্রোল

কিছু ইউজার ভিন্ন ভিন্ন নাম ব্যবহার করলেও একই IP ব্যবহার করে।

এই ক্ষেত্রে:

একই IP থেকে যদি আগের অর্ডার পেন্ডিং থাকে
নতুন অর্ডার বন্ধ করে দিবে।


৪. অর্ডার স্ট্যাটাস ভিত্তিক কন্ট্রোল

এটাই সবচেয়ে গুরুত্বপূর্ণ অংশ।

আপনি এমনভাবে সিস্টেম সেট করবেন:

যদি আগের অর্ডার “Completed” না হয়

  • নতুন অর্ডার Allow হবে না
  • এতে করে কাস্টমারকে বাধ্য করা যায় আগের অর্ডার সম্পন্ন করতে।

৫. ইউজারকে সুন্দরভাবে জানানো (Popup Message)

শুধু ব্লক করলেই হবে না—কাস্টমারকে বুঝাতেও হবে।

যখন অর্ডার ব্লক হবে:

  • একটা সুন্দর popup দেখান
  • পরিষ্কারভাবে লিখুন কেন অর্ডার নেওয়া হচ্ছে না

এতে করে ইউজার বিরক্ত না হয়ে বিষয়টা বুঝতে পারবে।


৬. Call ও WhatsApp অপশন দিন

অনেক সময় কাস্টমার সত্যিই অর্ডার করতে চায়, কিন্তু কোনো কারণে ব্লক হয়ে যায়।

তাই popup-এর মধ্যে দিন:

  • “Call Now” বাটন
  • “WhatsApp” বাটন

এতে করে কাস্টমার সরাসরি আপনার সাথে যোগাযোগ করতে পারবে।


৭. CartFlows ব্যবহার করলেও কাজ করবে

আপনি যদি CartFlows দিয়ে কাস্টম checkout বানিয়ে থাকেন, তবুও এই সিস্টেম কাজ করবে।
মানে আপনার existing funnel-এ কোনো সমস্যা হবে না।


কোড কোথায় বসাবেন?

এই সিস্টেম চালু করতে আপনাকে শুধু PHP কোড বসাতে হবে।

আপনি তিনভাবে এটা করতে পারেন:

  • থিমের functions.php ফাইলে
  • Code Snippets প্লাগইন দিয়ে
  • অথবা কাস্টম প্লাগইন বানিয়ে

নতুনদের জন্য Code Snippets সবচেয়ে safe অপশন।


কিছু গুরুত্বপূর্ণ কাস্টমাইজেশন টিপস

  • আপনার নিজের ফোন নাম্বার বসান (Call/WhatsApp-এর জন্য)
  • WhatsApp link নিজের মতো করে দিন
  • Popup-এর ডিজাইন আপনার ব্র্যান্ড কালারে সাজান

যেমন: আপনার ব্র্যান্ড যদি ডার্ক + পিংক/ব্লু হয়, তাহলে সেই অনুযায়ী CSS দিন।


শেষ কথা

দেখুন, ফেক অর্ডার পুরোপুরি বন্ধ করা কঠিন, কিন্তু সঠিক নিয়ম বসাতে পারলে ৮০–৯০% কমিয়ে ফেলা সম্ভব।

আপনি যদি সত্যি সিরিয়াসলি WooCommerce দিয়ে ব্যবসা করেন, তাহলে এই ধরনের control system থাকা বাধ্যতামূলক।

কারণ এটা শুধু আপনার সময়ই বাঁচাবে না—আপনার profit-ও বাড়াবে।

ছোট একটা কোড, কিন্তু impact বিশাল



**
 * Plugin Name: WooCommerce Multi-Factor Order Blocker with Stylish Popup + CartFlows Support
 * Description: Block multiple orders from same device, phone or IP until previous order completes. Supports normal WooCommerce checkout & CartFlows Ajax checkout. Shows a true mobile-friendly modal popup with Call & WhatsApp buttons.
 * Version: 1.2
 * Author: Your Business Name
 */

// === ১. সাধারণ WooCommerce Checkout Process এ ব্লক চেক করা ===
add_action('woocommerce_checkout_process', 'custom_block_multiple_orders_check');
function custom_block_multiple_orders_check() {
    $email = sanitize_email($_POST['billing_email'] ?? '');
    $phone = sanitize_text_field($_POST['billing_phone'] ?? '');
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown_ip';
    $device_id = $_COOKIE['device_id'] ?? '';

    $args = [
        'limit' => -1,
        'status' => ['pending', 'processing', 'on-hold'],
        'billing_email' => $email,
    ];

    $orders = wc_get_orders($args);
    $block_order = false;

    foreach ($orders as $order) {
        $order_phone = $order->get_billing_phone();
        $order_ip = get_post_meta($order->get_id(), '_user_ip', true);
        $order_device = get_post_meta($order->get_id(), '_device_id', true);

        if (
            ($phone && $phone === $order_phone) ||
            ($ip && $ip === $order_ip) ||
            ($device_id && $device_id === $order_device)
        ) {
            $block_order = true;
            break;
        }
    }

    if ($block_order) {
        $phone_number = '01850';
        $whatsapp_number = '+880185';

        // এখন raw HTML notice এর বদলে data-attribute সহ একটা marker notice দিচ্ছি,
        // JS এইটা ধরে modal বানাবে
        $msg = 'ORDER_BLOCK_POPUP::' . esc_attr($phone_number) . '::' . esc_attr($whatsapp_number);
        wc_add_notice($msg, 'error');
    }

    if (!$device_id) {
        $device_id_new = bin2hex(random_bytes(10));
        setcookie('device_id', $device_id_new, time() + (86400 * 30), "/");
    }
}

// === ২. CartFlows Ajax Checkout Submit এও ব্লক চেক করা ===
add_action('wp_ajax_wc_cartflows_submit_checkout', 'custom_cartflows_ajax_checkout_check');
add_action('wp_ajax_nopriv_wc_cartflows_submit_checkout', 'custom_cartflows_ajax_checkout_check');

function custom_cartflows_ajax_checkout_check() {
    $email = sanitize_email($_POST['billing_email'] ?? '');
    $phone = sanitize_text_field($_POST['billing_phone'] ?? '');
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown_ip';
    $device_id = $_COOKIE['device_id'] ?? '';

    $args = [
        'limit' => -1,
        'status' => ['pending', 'processing', 'on-hold'],
        'billing_email' => $email,
    ];

    $orders = wc_get_orders($args);

    foreach ($orders as $order) {
        $order_phone = $order->get_billing_phone();
        $order_ip = get_post_meta($order->get_id(), '_user_ip', true);
        $order_device = get_post_meta($order->get_id(), '_device_id', true);

        if (
            ($phone && $phone === $order_phone) ||
            ($ip && $ip === $order_ip) ||
            ($device_id && $device_id === $order_device)
        ) {
            $phone_number = '018504';
            $whatsapp_number = '88001850';

            wp_send_json_error([
                'messages' => 'ORDER_BLOCK_POPUP::' . esc_attr($phone_number) . '::' . esc_attr($whatsapp_number),
            ]);
        }
    }

    wp_send_json_success();
}

// === ৩. অর্ডার তৈরি হলে IP ও Device ID মেটাডেটা সেভ করা ===
add_action('woocommerce_checkout_update_order_meta', function ($order_id) {
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown_ip';
    $device_id = $_COOKIE['device_id'] ?? 'unknown_device_id';

    update_post_meta($order_id, '_user_ip', sanitize_text_field($ip));
    update_post_meta($order_id, '_device_id', sanitize_text_field($device_id));
});

// === ৪. Modal Popup Styling (Mobile-friendly, true overlay) ===
add_action('wp_footer', function () {
    if (!is_checkout() && !function_exists('cartflows')) {
        return;
    }
    ?>
    <style>
        #order-block-modal-overlay {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0,0,0,0.55);
            z-index: 999999;
            align-items: center;
            justify-content: center;
            padding: 16px;
        }
        #order-block-modal-overlay.active {
            display: flex;
        }
        .custom-popup-error {
            background: #fff0f0;
            border: 2px solid #ff4d4d;
            padding: 22px 20px;
            border-radius: 12px;
            color: #b30000;
            font-size: 16px;
            font-weight: 600;
            text-align: center;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            animation: popupFadeIn 0.3s ease forwards;
            max-width: 380px;
            width: 100%;
            position: relative;
        }
        .custom-popup-error .popup-close {
            position: absolute;
            top: 8px;
            right: 12px;
            font-size: 20px;
            color: #b30000;
            cursor: pointer;
            line-height: 1;
        }
        .custom-popup-error .btn-group {
            margin-top: 16px;
            display: flex;
            justify-content: center;
            gap: 12px;
            flex-wrap: wrap;
        }
        .custom-popup-error .btn-call,
        .custom-popup-error .btn-whatsapp {
            flex: 1 1 130px;
            display: inline-block;
            padding: 12px 16px;
            border-radius: 30px;
            font-weight: 700;
            color: white !important;
            text-decoration: none;
            box-shadow: 0 4px 10px rgba(0,0,0,0.15);
            transition: background-color 0.3s ease;
        }
        .custom-popup-error .btn-call {
            background-color: #e60000;
        }
        .custom-popup-error .btn-call:hover {
            background-color: #b30000;
        }
        .custom-popup-error .btn-whatsapp {
            background-color: #25D366;
        }
        .custom-popup-error .btn-whatsapp:hover {
            background-color: #1DA851;
        }
        @keyframes popupFadeIn {
            0% {opacity: 0; transform: scale(0.9) translateY(-10px);}
            100% {opacity: 1; transform: scale(1) translateY(0);}
        }
        /* Mobile tweak */
        @media (max-width: 480px) {
            .custom-popup-error {
                padding: 18px 14px;
                font-size: 15px;
            }
            .custom-popup-error .btn-call,
            .custom-popup-error .btn-whatsapp {
                flex: 1 1 100%;
                padding: 13px 16px;
            }
        }
    </style>

    <div id="order-block-modal-overlay">
        <div class="custom-popup-error" id="order-block-modal-body">
            <span class="popup-close" id="order-block-modal-close">&times;</span>
            <div id="order-block-modal-content"></div>
        </div>
    </div>

    <script>
    (function () {
        function buildModalHTML(phone, whatsapp) {
            return '<p>⚠️ আপনি অলরেডি একটি অর্ডার করেছেন। নতুন অর্ডার করতে নিচের নম্বরগুলোতে যোগাযোগ করুন।</p>' +
                '<div class="btn-group">' +
                '<a href="tel:' + phone + '" class="btn-call">📞 Call Now</a>' +
                '<a href="https://wa.me/' + whatsapp.replace('+', '') + '" class="btn-whatsapp" target="_blank">💬 WhatsApp</a>' +
                '</div>';
        }

        function showModal(phone, whatsapp) {
            document.getElementById('order-block-modal-content').innerHTML = buildModalHTML(phone, whatsapp);
            document.getElementById('order-block-modal-overlay').classList.add('active');
        }

        function hideModal() {
            document.getElementById('order-block-modal-overlay').classList.remove('active');
        }

        document.addEventListener('DOMContentLoaded', function () {
            document.getElementById('order-block-modal-close').addEventListener('click', hideModal);
            document.getElementById('order-block-modal-overlay').addEventListener('click', function (e) {
                if (e.target === this) hideModal();
            });

            // Case 1: normal WooCommerce checkout — notice text render হয়ে আছে DOM এ
            var noticeBoxes = document.querySelectorAll('.woocommerce-error li, .woocommerce-error');
            noticeBoxes.forEach(function (box) {
                var text = box.textContent.trim();
                if (text.indexOf('ORDER_BLOCK_POPUP::') === 0) {
                    var parts = text.split('::');
                    showModal(parts[1], parts[2]);
                    box.style.display = 'none'; // আসল ugly notice hide, modal ই দেখাবে
                }
            });

            // Case 2: CartFlows ajax — checkout_error event এ ধরা
            document.body.addEventListener('checkout_error', function () {
                setTimeout(function () {
                    var boxes = document.querySelectorAll('.woocommerce-error, .woocommerce-error li');
                    boxes.forEach(function (box) {
                        var text = box.textContent.trim();
                        if (text.indexOf('ORDER_BLOCK_POPUP::') === 0) {
                            var parts = text.split('::');
                            showModal(parts[1], parts[2]);
                            box.style.display = 'none';
                        }
                    });
                }, 100);
            });

            // Case 3: raw jQuery ajaxComplete fallback (কিছু CartFlows version এ checkout_error trigger নাও হতে পারে)
            if (window.jQuery) {
                jQuery(document).ajaxComplete(function (event, xhr, settings) {
                    if (settings.url && settings.url.indexOf('wc-ajax=') !== -1) {
                        setTimeout(function () {
                            var boxes = document.querySelectorAll('.woocommerce-error, .woocommerce-error li');
                            boxes.forEach(function (box) {
                                var text = box.textContent.trim();
                                if (text.indexOf('ORDER_BLOCK_POPUP::') === 0) {
                                    var parts = text.split('::');
                                    showModal(parts[1], parts[2]);
                                    box.style.display = 'none';
                                }
                            });
                        }, 150);
                    }
                });
            }
        });
    })();
    </script>
    <?php
});
Atikullah
About the author: Atikullah

Owner