I’ve been asked many times how to remove specific fields on the checkout page when the cart contains virtual (downloadable) products only. By default if the cart contains virtual products only, the shipping fields are automatically removed, but some users want to remove some of the billing fields too. That’s understandable, there’s no need to collect the billing address or the billing zipcode in most cases. The snippet i wrote below, checks the number of products in the cart, and compare the result to the number of virtual products in the cart. If all products are virtual, then checkout fields are removed, if the cart contains one virtual product and at least one physical product, checkout fields are kept. Does that make sense?
The code below has a function called woo_cart_has_virtual_product(). That’s the one checking for the virtual products in the cart. It returns true if all products in the cart are virtual, and false, if none of them are virtual or if there’s at least one non virtual product in the cart. Then the second function, woo_remove_billing_checkout_fields(), is hooked to woocommerce_checkout_fields and delete the unwanted checkout fields.
Here is the result when your cart contains virtual products only: