到貨通知功能是電商網(wǎng)站中留住用戶的一種手段,在文本中,我將向您展示如何在 WooCommerce 產(chǎn)品頁(yè)面中添加 “到貨時(shí)通知我 “表單,這樣您就可以收集客戶的電子郵件,并在產(chǎn)品到貨時(shí)時(shí)自動(dòng)向之前訂閱的顧客發(fā)送通知。
下圖是我們要實(shí)現(xiàn)的效果示例:

產(chǎn)品頁(yè)面上的 “缺貨時(shí)通知我 “表單
首先,讓我們把表單添加到產(chǎn)品頁(yè)面。
我們只需要為具有 “缺貨 “outofstock或 “延期交貨 “onbackorder狀態(tài)(或兩種狀態(tài)都有)的產(chǎn)品和變體添加表單–哪種選擇對(duì)您來(lái)說(shuō)更方便。
或者,您也可以自定義產(chǎn)品庫(kù)存狀態(tài)–完全沒(méi)問(wèn)題!
缺貨 “和 “滯銷 “庫(kù)存狀態(tài)的區(qū)別
讓我來(lái)解釋一下兩者的區(qū)別:
- “缺貨 “
outofstock– 客戶不能購(gòu)買此類產(chǎn)品,但可以使用我們的 “到貨時(shí)通知我 “表單。 - “延期交貨”
onbackorder–客戶可以購(gòu)買這種庫(kù)存狀態(tài)的產(chǎn)品,但不能立即購(gòu)買,只能在將來(lái)有貨的時(shí)候購(gòu)買(只是普通的預(yù)購(gòu)功能)。如果客戶不愿意購(gòu)買目前沒(méi)有庫(kù)存的產(chǎn)品,就需要填寫該表單。
在本教程中,我將使用 “缺貨 “狀態(tài)。
顯示表單
好了,我們已經(jīng)了解了庫(kù)存狀態(tài),現(xiàn)在我們的目標(biāo)是在產(chǎn)品頁(yè)面的 “缺貨 “文本后顯示 “到貨時(shí)通知我 “表單,為此我們需要選擇一個(gè)合適的 WooCommerce 鉤子。
在 WooCommerce 產(chǎn)品頁(yè)面上有很多鉤子可用,選擇一個(gè)合適的鉤子可能比較棘手,因?yàn)橛行┿^子無(wú)法使用,例如,對(duì)于缺貨產(chǎn)品,動(dòng)作鉤子woocommerce_after_add_to_cart_button永遠(yuǎn)不會(huì)觸發(fā)。
在我的例子中,我決定使用woocommerce_product_meta_start。
<?php
add_action( 'woocommerce_product_meta_start', 'wprs_notify_when_back_in_stock_form' );
function wprs_notify_when_back_in_stock_form() {
global $product;
// 我們不需要收集有庫(kù)存產(chǎn)品的補(bǔ)貨通知電子郵件
if( $product->is_in_stock() ) {
return;
}
?>
<form id="back-in-stock-notification" data-product_id="<?php echo $product->get_id() ?>">
<input type="email" name="email" class="input-text" placeholder="Your email address" />
<button class="wp-element-button">Join waitlist</button>
</form>
<?php
}
在這段代碼中,我想強(qiáng)調(diào)一下$product->is_in_stock()條件,你也可以使用$product->get_stock_status()檢查產(chǎn)品是否缺貨,但這兩種方法完全相同。唯一不同的是,如果使用第一種方法,則會(huì)應(yīng)用過(guò)濾器鉤子woocommerce_product_is_in_stock。
我還決定將產(chǎn)品 ID 作為數(shù)據(jù)屬性放入表單 HTML 中。
這就是我們的表單:

到目前為止,表單看起來(lái)還不錯(cuò),但為了讓它更美觀,我們可以添加一個(gè)標(biāo)題 “到貨時(shí)通知我”,或者更好的辦法是將此文本作為可用性文本的一部分。讓我們?cè)诒窘坛痰?a href="#change-availability-text">下一章中實(shí)現(xiàn)這一點(diǎn)。
更改 “缺貨 “狀態(tài)下的可用性文本
正如我之前所說(shuō),如果能為客戶提供更多信息,讓他們了解這個(gè)表單的內(nèi)容就更好了。我們可以在表單中添加一個(gè)標(biāo)題,或者只稍微修改一下 “缺貨 “狀態(tài)下的可用性文本。
add_filter( 'woocommerce_get_availability_text', 'wprs_out_of_stock_text', 25, 2 );
function wprs_out_of_stock_text( $text, $product ) {
if( is_product() && ! $product->is_in_stock() ) {
$text = '當(dāng)前缺貨 – 加入等候名單,當(dāng)該產(chǎn)品到貨時(shí),您會(huì)收到電子郵件';
}
return $text;
}
我在這里還使用了is_product()條件,因?yàn)檎l(shuí)知道呢,也許在你的主題中,庫(kù)存狀態(tài)文本會(huì)顯示在商店頁(yè)面或其他地方。
我們開(kāi)始吧:

異步處理表單(通過(guò) AJAX)
首先,我想問(wèn)大家一個(gè)最主要的問(wèn)題–“為什么要使用 jQuery?主要有兩個(gè)原因:
- WooCommerce 仍然在商店前端使用 jQuery。因此,只要包含了 jQuery,就沒(méi)什么好擔(dān)心的。
- 我一直在努力讓我的教程通俗易懂,而我的很多讀者還在為 JavaScript 而苦惱。
但是,如果我為此創(chuàng)建了一個(gè)插件,我會(huì)盡可能避免使用 jQuery。
jQuery( function( $ ) {
$( '#back-in-stock-notification' ).submit( function() {
const emailField = $(this).find( 'input[type="email"]' )
const submitButton = $(this).find( 'button' )
const productId = $(this).data( 'product_id' )
$.ajax( {
url : woocommerce_params.ajax_url,
type : 'POST',
data : {
email : emailField.val(),
product_id : productId,
action : 'back_in_stock_notification',
},
beforeSend : function( xhr ) {
// 修改按鈕文字
submitButton.text( 'One moment...' )
// 清理通知
$( '.woocommerce-notices-wrapper' ).find( '#my-notice' ).remove()
},
success : function( response ) {
// 改回按鈕文本
submitButton.text( 'Join waitlist' )
if( response.success ) {
// 清空電子郵件字段
emailField.val( '' )
// 顯示通知
$( '.woocommerce-notices-wrapper' ).append( '<div id="my-notice" class="wc-block-components-notice-banner is-success" role="alert"><div class="wc-block-components-notice-banner__content">' + response.data + '</div>' )
}
}
} )
return false
} )
} )
現(xiàn)在,我們需要處理我們的 AJAX 請(qǐng)求,使用wp_ajax_和wp_ajax_nopriv_動(dòng)作鉤子可以很容易地在 WordPress 中完成。
add_action( 'wp_ajax_back_in_stock_notification', 'wprs_create_notification' );
add_action( 'wp_ajax_nopriv_back_in_stock_notification', 'wprs_create_notification' );
function wprs_create_notification() {
// 這里我們需要處理用戶電子郵件并將其添加到我們的數(shù)據(jù)庫(kù)中
$success_notice_text = 'You will be notified!';
wp_send_json_success( $success_notice_text );
}
這樣,我們就有了一個(gè)漂亮的 AJAX 返回庫(kù)存通知表單:

很好,表單已準(zhǔn)備就緒,但事實(shí)上它并沒(méi)有收集電子郵件,因此我們現(xiàn)在無(wú)法發(fā)送庫(kù)存通知 – 是時(shí)候進(jìn)入教程的下一部分了。
決定如何在數(shù)據(jù)庫(kù)中存儲(chǔ)電子郵件
我認(rèn)為有三種方法可以做到這一點(diǎn):
| 方法 | 描述 |
|---|---|
| 產(chǎn)品元數(shù)據(jù) | 這是最簡(jiǎn)單的方法,但如果您想在一個(gè)地方管理所有的缺貨通知,那就不太方便了。 |
| 自定義數(shù)據(jù)庫(kù)表 | 最好的方法!開(kāi)發(fā)起來(lái)可能要復(fù)雜得多,尤其是與管理用戶界面相關(guān)的部分,但如果您的店鋪產(chǎn)品很多,每種產(chǎn)品都可能有數(shù)百封缺貨通知郵件,那么我想說(shuō)的是,這種方法是您唯一的選擇。 |
| 自定義文章類型 | 許多插件開(kāi)發(fā)人員通常會(huì)使用這種方法。因此,如果你發(fā)現(xiàn)有某種適用于 WooCommerce 的缺貨通知插件,請(qǐng)務(wù)必小心,因?yàn)橄嘈盼?,為此目的使用自定義文章類型是最糟糕的主意。 |
在本教程中,我將使用第一種方法。
首先,讓我們?yōu)楫a(chǎn)品創(chuàng)建一個(gè)自定義字段。我認(rèn)為在 “庫(kù)存 “選項(xiàng)卡中創(chuàng)建一個(gè)簡(jiǎn)單的文本框字段會(huì)比較好,就像下面這樣:

用以下代碼就可以輕松完成:
add_action( 'woocommerce_product_options_stock_status', function(){
$list = ( $list = get_post_meta( get_the_ID(), 'email_list', true ) ) ? $list : array();
echo '<div class="option_group">';
woocommerce_wp_textarea_input(
array(
'id' => 'email_list',
'value' => join( "\n", $list ),
'label' => 'Waitlist',
'description' => 'Emails for back in stock notifications',
'desc_tip' => true,
)
);
echo '</div>';
} );
add_action( 'woocommerce_process_product_meta', function( $product_id ) {
// 我們將電子郵件作為序列化數(shù)組存儲(chǔ)在數(shù)據(jù)庫(kù)中
$list = isset( $_POST[ 'email_list' ] ) ? explode( "\n", $_POST[ 'email_list' ] ) : array();
// 在這里,我們也可以使用 $product->update_meta_data() 方法
update_post_meta( $product_id, 'email_list', $list );
} );
然后,我們只需在AJAX 處理中添加缺少的內(nèi)容:
function wprs_create_notification() {
$product_id = absint( $_POST[ 'product_id' ] );
$product = wc_get_product( $product_id );
// 最好檢查一下該產(chǎn)品是否存在
if( ! $product ) {
wp_send_json_error();
}
// 檢查產(chǎn)品狀態(tài)是否缺貨也很有用
if( $product->is_in_stock() ) {
wp_send_json_error();
}
// 不要忘記檢查電子郵件是否正確
$email = $_POST[ 'email' ];
if( ! is_email( $email ) ) {
wp_send_json_error();
}
$list = ( $list = $product->get_meta( 'email_list' ) ) ? $list : array();
$list[] = $email;
$product->update_meta_data( 'email_list', $list );
$product->save();
...
發(fā)送到貨通知
首先,我們需要決定使用哪個(gè) WooCommerce 鉤子。
例如,當(dāng)您處理 WooCommerce 訂單時(shí),有一個(gè)非常好的鉤子 woocommerce_order_status_changed,它允許將新訂單和舊訂單狀態(tài)傳遞給回調(diào)函數(shù),這樣我們就可以檢查之前的訂單狀態(tài)。產(chǎn)品庫(kù)存狀態(tài)沒(méi)有這樣的鉤子,因此要獲得以前和新的產(chǎn)品庫(kù)存狀態(tài)并不容易,但還有另外兩個(gè)非常不錯(cuò)的鉤子。
woocommerce_product_set_stock_status– 當(dāng)產(chǎn)品庫(kù)存狀態(tài)發(fā)生變化時(shí),就會(huì)觸發(fā)這個(gè)鉤子。這意味著,如果您的產(chǎn)品原本缺貨,但您更新了價(jià)格,例如,產(chǎn)品仍然缺貨,則不會(huì)觸發(fā)該鉤子。woocommerce_product_set_stock– 相同,但適用于產(chǎn)品庫(kù)存數(shù)量。
看來(lái),woocommerce_product_set_stock_status正是我們需要的!
add_action( 'woocommerce_product_set_stock_status', 'wprs_back_in_stock', 25, 3 );
function wprs_back_in_stock( $product_id, $stock_status, $product ) {
// 產(chǎn)品已到貨,我們現(xiàn)在可以發(fā)送通知
if( 'instock' === $stock_status ) {
$emails = $product->get_meta( 'email_list' );
if( $emails ) {
// 發(fā)送郵件就非常簡(jiǎn)單了
wp_mail(
$emails,
'The product is back in stock!',
sprintf(
'The product %s is back in stock! Check it out %s!',
$product->get_name(),
$product->add_to_cart_url()
)
);
$product->delete_meta_data( 'email_list' );
$product->save();
}
}
}
還有一件事…
有時(shí),一個(gè)看似簡(jiǎn)單的功能實(shí)際上可能會(huì)有很多陷阱和一些特殊情況,我們?cè)陂_(kāi)發(fā)時(shí)應(yīng)牢記這一點(diǎn)。
這里也是一樣–如果您已經(jīng)看完了本教程,您可能會(huì)認(rèn)為在 WooCommerce 中自己創(chuàng)建缺貨通知并不是什么大不了的事情,但讓我提醒您幾件事:
- 電子郵件確認(rèn)和一些基本的反垃圾郵件保護(hù)、
- 當(dāng)我們需要同時(shí)發(fā)送大量缺貨通知時(shí),可以使用操作調(diào)度程序或 WP Cron。
- 當(dāng)然,最好使用自定義數(shù)據(jù)庫(kù)表。
也許還有更多需要考慮的事項(xiàng),這些只是我想到的第一批。


