我在 WooCommerce 商店中销售有形产品和虚拟产品,当来自美国以外的人尝试订购有形产品时,我是否很难弄清楚该怎么做。我环顾四周,发现大多数解决方案要么全有,要么全无。我会将我的虚拟产品出售给任何人和任何地方,但我需要阻止美国以外的人检查他们的购物车中是否有有形产品。
目前,如果美国境外的人尝试使用有形产品结帐,他们只会在运输部分收到一条消息,显示“没有可用的运输选项。请确保您输入的地址正确,或联系我们”如果你需要任何帮助的话。”但除此之外他们还可以结帐。大家有什么想法或建议吗?
基于 在 Woocommerce 中根据国家/地区禁用特定产品的送货,以下代码将避免添加到实体产品的购物车,或者如果客户送货地址位于特定国家/地区(此处为美国)之外,则将删除实体购物车商品:
// Avoid Add to cart for non virtual products on countries outside USA
add_filter( 'woocommerce_add_to_cart_validation', 'check_physical_products_for_country', 10, 4 );
function check_physical_products_for_country( $passed, $product_id, $quantity, $variation_id = null ) {
$product = wc_get_product( $variation_id > 0 ? $variation_id : $product_id );
if ( WC()->customer->get_shipping_country() !== 'US' && ! $product->is_virtual() ) {
wc_add_notice( __( "Only virtual products are purchasable outside United States of America.", "woocommerce" ), "error" );
return false;
}
return $passed;
}
// Remove non virtual products from cart for countries outside USA (to be sure)
add_action('woocommerce_before_calculate_totals', 'check_physical_cart_items_for_country');
function check_physical_cart_items_for_country( $cart ) {
if ((is_admin() && !defined('DOING_AJAX')))
return;
if (did_action('woocommerce_before_calculate_totals') >= 2)
return;
if ( ! ( is_cart() || is_checkout() ) )
return;
$country = WC()->customer->get_shipping_country();
$found_items = []; // initializing
// Loop through cart items checking for non virtual products outside USA
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data']; // Get the product object
if ( $country !== 'US' && ! $product->is_virtual() ) {
$found_items[$cart_item_key] = $product->get_name();
}
}
if( count($found_items) > 0 ) {
// Removing non virtual items found for customer outside USA
foreach ( $found_items as $key => $name ) {
$cart->remove_cart_item($key);
}
wc_clear_notices();
wc_add_notice( sprintf(
__( 'Item(s) "%s" have been removed from cart as they are not shippable outside USA.', "woocommerce" ),
'<strong>' . implode(', ', $found_items) ) . '</strong>', "error" );
}
}
代码位于子主题的functions.php 文件中(或插件中)。已测试并有效。