線上課程只能買一次:臺北講師用 WooCommerce 防止學員重複購買

線上課程只能買一次:臺北講師用 WooCommerce 防止學員重複購買

最後更新:2026/10/13

賣實體商品,客人買兩次是好事;賣線上課程,學員買兩次多半是不小心。忘了自己買過、換了一支手機登入、看到廣告又點進來結帳,結果是一筆要退的款、一封要解釋的信,金流手續費還不一定退得回來。

在臺北開課的講師、做線上課程網站的工作室,常會遇到這個問題。WooCommerce 有一部分可以在後台設定,另一部分要加一小段程式碼。下面先分清楚「每筆訂單限一件」和「每個人限買一次」,再一步一步設定。

不想自己改?把這篇交給 AI

把這篇的網址(或全文)連同下面這段話貼給 AI:

我的網站是 WordPress,有裝 WooCommerce。我想照下面這篇文章,讓每個人的線上課程只能買一次,買過的人不能再結帳。
請先問我:課程是一般商品還是有不同方案、我允不允許訪客不註冊就結帳。
問清楚之後,再一步一步告訴我:要用哪一段程式碼、貼在哪裡、哪些地方要換成我自己的資料,以及改完怎麼測試。
如果文章的做法不適合我的網站,請直接告訴我原因和替代做法。
文章:(貼上這篇的網址,或整篇內容)

改之前先備份,密碼不要貼給 AI。

「限購一件」只管同一筆訂單

在商品編輯頁的「庫存」分頁,有一個「限購一件」的勾選,說明寫著「限制每筆訂單購買一項商品」。勾了之後,購物車裡這門課的數量只能是 1,避免有人把數量點成 2。

它擋不住的是「下一筆訂單再買一次」。同一個學員今天買一次、下週再買一次,「限購一件」都不會阻止。要做到每個人只能買一次,就需要知道「這個人買過沒有」,而這需要學員登入。

已經買過的人,不能再買

WooCommerce 內建一個函式,可以查某個會員有沒有買過某件商品。下面這段程式碼用它來判斷:登入的會員如果已經買過「線上課程」分類的商品,這件商品就變成不能購買,課程頁也會告訴他去哪裡看。分類代稱 course 請換成你的課程分類:

// 哪些商品只能買一次:這裡用「線上課程」分類(代稱 course)
function mimi_only_once($product_id) {
    return has_term('course', 'product_cat', $product_id);
}

// 已經買過的會員,這個商品變成「不能購買」
add_filter('woocommerce_is_purchasable', function ($ok, $product) {
    $id = $product->get_parent_id() ?: $product->get_id();
    if ($ok && is_user_logged_in() && mimi_only_once($id)
        && wc_customer_bought_product('', get_current_user_id(), $id)) {
        return false;
    }
    return $ok;
}, 10, 2);

// 課程頁提醒他已經買過
add_action('woocommerce_single_product_summary', function () {
    global $product;
    $id = $product->get_id();
    if (is_user_logged_in() && mimi_only_once($id)
        && wc_customer_bought_product('', get_current_user_id(), $id)) {
        echo '<p class="mimi-bought">你已經買過這門課,'
           . '可以到「我的帳戶 → 訂單」查看。</p>';
    }
}, 31);

我們在測試站用一個學員帳號買了課程,訂單改成「完成」後回到課程頁,「加入購物車」按鈕消失了,換成「你已經買過這門課」的提醒;就算直接用加入購物車的網址硬加,也只會看到「抱歉,不能選購此一商品」。

程式碼放在 Code Snippets 這類外掛或子主題,放法和備份方式見〈WooCommerce 結帳頁改成台灣習慣〉。

訪客要先有帳號才能買

上面的判斷靠的是會員帳號。如果允許訪客結帳,同一個人換一個 Email 就能再買一次,系統也不會知道他買過。所以課程類商品,要規定結帳時一定要有帳號:

// 購物車有「只能買一次」的商品時,一定要登入或註冊才能結帳
add_filter('woocommerce_checkout_registration_required', function ($req) {
    if (WC()->cart) {
        foreach (WC()->cart->get_cart() as $item) {
            if (mimi_only_once($item['product_id'])) {
                return true;
            }
        }
    }
    return $req;
});

加了這段之後,記得到「WooCommerce → 設定 → 帳號及隱私權」,在「建立帳號」勾選「結帳期間」,讓新學員可以在結帳時直接建立帳號。沒勾的話,訪客走到結帳頁只會看到「您必須登入才可結帳」,還得自己去找註冊的地方,很容易就走掉了。我們兩種情況都測過:勾了「結帳期間」之後,訪客在結帳頁就能填資料下單,帳號會用他的 Email 自動建立。

實體商品的訪客結帳不受影響。這段只在購物車裡有課程時才要求帳號,買手作商品的客人仍然可以用訪客身分結帳。

這些狀況仍然擋不住

內建的「買過沒有」只看已付款的訂單,也就是狀態是「處理中」和「完成」的訂單。選銀行轉帳、還沒匯款的訂單是「保留」狀態,不算買過;學員在匯款前又下一張單,兩張都會成立。如果你的課程主要收轉帳,可以在付款說明寫清楚「同一門課只需下單一次」,對帳時多留意同一個帳號的重複訂單。

反過來,整筆退款的訂單會變成「已退費」,也不算買過,學員之後要重新購買是可以的,這通常也是你想要的結果。

另一件要想清楚的事是「哪些商品算同一門課」。如果同一門課有「單買」和「含講義」兩個商品,系統會當成兩件不同的商品。這種情況可以改用可變商品,把兩種方案做成同一門課的兩個選項;上面的程式碼會用主商品來判斷,買過任何一個方案,其他方案也不能再買,這點我們也測過。

課程網站的流程,比商品頁更重要

學員買課之後要能登入、找到課程、看到訂單;沒買的人要知道怎麼買、買了會得到什麼。這些流程設計好,客服訊息會少很多。會員和訂閱這類收費方式怎麼規劃,可以看〈會員制、訂閱制怎麼做?〉。

課程放在別人的平台上,規則由平台決定;放在自己的網站,才能照你的教學方式設計,這也是〈IG 帳號不是你的資產〉想說的事。MIMI 專做客製化網頁設計,線上課程網站可以從課程頁、購買到學員登入一起規劃。MIMI 提供臺北網頁設計服務,臺北的講師可以用電話、Email 直接和設計師討論;費用可以先看首頁的製作費用參考,歡迎聯絡 MIMI。

WooCommerce 優惠券進階用法:點連結就折扣、活動頁輸入優惠碼、學員專屬價
WooCommerce PDF 發票、出貨單中文變方塊:新北網店的中文字型設定

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

我的車
願望清單
最近瀏覽過的
類別