WooCommerce 缺貨時「貨到通知我」:客人留 Email,補貨自動寄信

WooCommerce 缺貨時「貨到通知我」:客人留 Email,補貨自動寄信

最後更新:2026/10/25

在新北經營網店,最可惜的情況之一是:熱賣的商品賣完了,商品頁只剩下一行「已售完」。客人看到這行字,通常就關掉頁面去別家找;等你一週後補好貨,他早就忘了你的店。

很多購物平台都有「貨到通知我」:客人留下 Email,補貨時收到一封信,點進來就能買。WooCommerce 本身沒有這個功能,外掛可以做,但只為了一個按鈕裝外掛,不一定划算。這篇用一段程式碼做出來:缺貨時商品頁出現表單,客人留下 Email,商品一補貨就自動寄信,寄完就把名單刪掉。

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

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

我的網站是 WordPress,有裝 WooCommerce。我想照下面這篇文章,在缺貨的商品頁加上「到貨通知我」:客人留 Email,補貨時自動寄信。
請先問我:我的商品是一般商品還是有規格(顏色、尺寸)、網站有沒有整頁快取、通知信想寫什麼、同意用途的那句話要怎麼寫。
問清楚之後,再一步一步告訴我:要用哪一段程式碼、貼在哪裡、哪些地方要換成我自己的資料,以及改完怎麼測試。
如果文章的做法不適合我的網站,請直接告訴我原因和替代做法。
文章:(貼上這篇的網址,或整篇內容)

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

完整程式碼

// 第 113 篇:WooCommerce 缺貨時「貨到通知我」,客人留 Email,補貨自動寄信

// 1. 缺貨的商品頁,在價格下面放「到貨通知我」表單(一般商品;有規格的商品見文章最後)
add_action('woocommerce_single_product_summary', function () {
    global $product;
    if (!$product || !$product->is_type('simple') || $product->is_in_stock()) {
        return;
    }
    $email = is_user_logged_in() ? wp_get_current_user()->user_email : '';
    ?>
    <form class="mimi-notify" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
        <?php if (isset($_GET['mimi_notify'])) : ?>
            <p class="mimi-notify-ok">收到了!到貨的時候,我們會寄一封信通知你。</p>
        <?php else : ?>
            <p><strong>目前缺貨,到貨時寄信通知我</strong></p>
            <p><input type="email" name="mimi_email" value="<?php echo esc_attr($email); ?>" placeholder="你的 Email" required></p>
            <p><label><input type="checkbox" name="mimi_agree" value="1" required> 我同意這個 Email 只用來寄這次的到貨通知</label></p>
            <input type="hidden" name="action" value="mimi_notify">
            <input type="hidden" name="product_id" value="<?php echo esc_attr($product->get_id()); ?>">
            <?php wp_nonce_field('mimi_notify'); ?>
            <p><button type="submit" class="button wp-element-button">到貨通知我</button></p>
        <?php endif; ?>
    </form>
    <?php
}, 31);

// 2. 收下 Email,存在這個商品的資料裡(同一個 Email 只存一次)
function mimi_notify_save() {
    $pid   = absint($_POST['product_id'] ?? 0);
    $email = sanitize_email(wp_unslash($_POST['mimi_email'] ?? ''));
    $back  = $pid ? get_permalink($pid) : home_url('/');
    $ok    = $pid && get_post_type($pid) === 'product' && is_email($email) && !empty($_POST['mimi_agree'])
        && wp_verify_nonce($_POST['_wpnonce'] ?? '', 'mimi_notify');
    if ($ok) {
        $list = get_post_meta($pid, '_mimi_notify', true);
        $list = is_array($list) ? $list : [];
        $list[strtolower($email)] = current_time('mysql');
        update_post_meta($pid, '_mimi_notify', $list);
        $back = add_query_arg('mimi_notify', 'ok', $back);
    }
    wp_safe_redirect($back);
    exit;
}
add_action('admin_post_mimi_notify', 'mimi_notify_save');
add_action('admin_post_nopriv_mimi_notify', 'mimi_notify_save');

// 3. 商品從缺貨變成「有庫存」時,寄信給登記的人,寄完把名單清掉
add_action('woocommerce_product_set_stock_status', function ($product_id, $status, $product) {
    $list = get_post_meta($product_id, '_mimi_notify', true);
    if ($status !== 'instock' || !is_array($list) || !$list) {
        return;
    }
    $mailer  = WC()->mailer();
    $name    = $product->get_name();
    $url     = $product->get_permalink();
    $subject = sprintf('你等的「%s」到貨了', $name);
    $body    = sprintf(
        '<p>你好,你登記到貨通知的「%s」已經補貨了。數量有限,想要的話可以回來看看:</p><p><a href="%s">%s</a></p><p>這封信只寄這一次,你的 Email 已經從通知名單刪除。</p>',
        esc_html($name),
        esc_url($url),
        esc_html($name)
    );
    $html = $mailer->wrap_message($subject, $body);
    foreach (array_keys($list) as $email) {
        $mailer->send($email, $subject, $html);
    }
    delete_post_meta($product_id, '_mimi_notify');
}, 10, 3);

// 4. 後台編輯商品的「庫存」分頁,顯示目前有幾個人在等
add_action('woocommerce_product_options_stock_status', function () {
    global $post;
    $list  = get_post_meta($post->ID, '_mimi_notify', true);
    $count = is_array($list) ? count($list) : 0;
    echo '<p class="form-field"><label>到貨通知</label>' . esc_html($count ? "目前有 {$count} 人登記" : '目前沒有人登記') . '</p>';
});

// 5. 表單的樣子(框線、輸入框寬度,可以照網站的風格改)
add_action('wp_head', function () {
    if (function_exists('is_product') && is_product()) {
        echo '<style>.mimi-notify{margin:1em 0;padding:1em 1.2em;border:1px solid #ddd;border-radius:8px}'
            . '.mimi-notify input[type=email]{width:100%;max-width:320px;padding:.5em}.mimi-notify p{margin:.5em 0}</style>';
    }
});

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

五段各做了什麼

第 1 段只在「一般商品、而且已經缺貨」的商品頁出現,位置在價格下面。表單有三樣東西:Email 欄位(已經登入的會員會自動帶入他的 Email)、一個同意用途的勾選框、送出按鈕。客人送出後會回到同一頁,表單換成「收到了!到貨的時候,我們會寄一封信通知你。」

勾選框寫的是「我同意這個 Email 只用來寄這次的到貨通知」。收集客人的 Email,要讓客人知道你拿去做什麼;這裡寫明只用在這一次,寄完就刪,之後也照這樣做。沒有勾選的話,資料不會存下來。

第 2 段負責收資料。它檢查商品真的存在、Email 格式正確、客人有勾同意,再確認表單裡的安全碼(防止別的網站假冒送出),才把 Email 存進這件商品的資料裡。同一個 Email 只存一次,大小寫不同也算同一個。

第 3 段是重點。WooCommerce 在商品的庫存狀態改變時,會觸發 woocommerce_product_set_stock_status 這個 hook;狀態變成「尚有庫存」的那一刻,程式把名單上的每個人各寄一封信,信裡有商品名稱和連結,寄完就把整份名單刪掉。不管你是直接把庫存狀態改成「尚有庫存」,還是有管理庫存、把數量從 0 改成 5,都會觸發。

第 4 段在後台編輯商品的「庫存」分頁,多一行「到貨通知:目前有 3 人登記」,補貨前就知道有多少人在等,也可以當作要不要再進貨的參考。

第 5 段是表單的樣子:加一圈框線、讓輸入框寬一點。顏色和圓角可以照你網站的風格改。

測試結果

我們在本機測試站(WordPress 7.1.3、WooCommerce 11.2.1)用「手工皂禮盒」測試,Storefront 和 Twenty Twenty-Five 兩種佈景主題都看得到表單:

  • 有庫存時,商品頁沒有表單;把庫存狀態改成「已售完」,價格下面出現「目前缺貨,到貨時寄信通知我」。
  • 訪客用 [email protected] 登記,再用 [email protected] 登記一次,名單裡只有一筆;再加一位 [email protected],名單有兩筆。
  • 沒有勾同意就送出,名單沒有增加。
  • 把庫存狀態改回「尚有庫存」,兩人各收到一封標題「你等的「手工皂禮盒」到貨了」的信,寄完後名單清空。
  • 另一件商品開啟庫存管理,數量設 0(自動變成已售完)讓一位客人登記,再把數量改成 5,同樣寄出通知信。

使用前要注意的事

這段只處理一般商品。有顏色、尺寸這類規格的商品,每一種規格各自有庫存,表單要讓客人選規格、補貨時也要看是哪一種規格補了貨,寫法比較複雜,需要的話請工程師依同樣的思路擴充。

表單裡的安全碼有使用期限,大約一天左右。網站如果有整頁快取,快取的時間要短於這個期限,不然快取久了,客人送出時會因為安全碼過期而沒有成功。網站加速的做法可以看〈WordPress 網站變快,自己能做的事〉。

通知信是用網站寄出的,網站寄信容易進垃圾信件匣的話,先把寄信設定好,做法見〈WordPress 寄信進垃圾信件匣?用 SMTP 寄信〉。名單很長(例如幾百人)時,一次寄完可能讓存檔變慢,可以改成分批寄。

讓缺貨也變成一次留住客人的機會

商品賣完時,客人原本會直接離開;多了一個「到貨通知我」,他就留下了聯絡方式,等你補貨時再回來。登記的人數,也告訴你哪些商品值得多進一點貨。商品頁上還有哪些地方值得調整,可以看〈WooCommerce 商品太多客人找不到?〉。

MIMI 專做客製化網頁設計,購物車電商網站的商品頁、庫存和通知信,都可以依你的商品和進貨方式一起規劃。MIMI 提供新北網頁設計服務,新北、臺北到全台灣的店家,都可以用電話、Email 直接和設計師討論;費用可以先看首頁的製作費用參考,歡迎聯絡 MIMI。

WooCommerce 加價購:買了指定商品,就能用優惠價加購另一件
WooCommerce 結帳頁加發票欄位:個人、公司統編、捐贈碼,統編自動檢查

發佈留言

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

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