我在 WooCommerce 商店中销售有形产品和虚拟产品,当来自美国以外的人尝试订购有形产品时,我很难弄清楚该怎么做。我环顾四周,发现大多数解决方案要么全有,要么全无。我会将我的虚拟产品出售给任何地方的任何人,但我需要阻止美国以外的人检查他们的购物车中是否有有形产品。
目前,如果来自美国以外的人尝试结账有形产品,他们只会在运输部分收到一条消息,显示“没有可用的运输选项。请确保您输入的地址正确,或者在以下情况下联系我们:您需要任何帮助。”但除此之外他们还可以结帐。有人有什么想法或建议吗?谢谢
基于 在 Woocommerce 中根据国家/地区禁用特定产品的送货,以下代码可避免将实体产品添加到购物车,或者如果客户送货地址位于美国境外,则将删除实体购物车商品:
// Avoid Add to cart for non virtual products on countries outside USA
add_filter( 'woocommerce_add_to_cart_validation', 'filter_add_to_cart_validation', 10, 4 );
function filter_add_to_cart_validation( $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
add_action('woocommerce_before_calculate_totals', 'set_new_cart_item_updated_price');
function set_new_cart_item_updated_price($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 文件中(或插件中)。已测试并有效。