We use WooCommerce Subscriptions to setup payment plans for our products. Deposits was our first choice but it only sent “Invoices” for future payments and did not auto charge the credit card used at initial purchase. Not ok as our products are very expensive and people tended to ignore those invoices.
We also need to limit these purchase to one per customer. Easier said than done. I found a WooCommerce extension that would do the trick but we already pay so much a year for extensions we need I try to avoid that for simple functionality.
This won’t work for my needs. The option on a subscription product only limits users from having multiple subscriptions to that particular product. We only want one subscript for ANY product.
My solution works for one shopping cart session. I’m working on preventing others which shouldn’t be too hard by just checking the database at checkout time for active subscriptions to that user.
The Hook & Function
I went with woocommerce_add_to_cart_validation after going through quite a few other hooks and filters. The hardest thing about finding a solution is finding what all hooks and filters are available. Takes some serious google-fu to find the right one quickly.
This filter allows you to run a function before an item is validated and sent to the cart. We tell our add_filter that we need two of the parameters so we can get the product id as well as the validity of the admission. This is done with the 4th parameter we set to “2.”
Detect Variations Too
If you are using variable Subscriptions you will need to plan ahead that some items in the cart may be variations. These have a separate class. We must first detect if the product being added is an instance of WC_Product_Subscription which is a “Simple Subscription” in WooCommerce. Or is an instance of WC_Product_Variable_Subscription which is like it says a version of a subscription product with variations.
The odd part that caught me off guard is when we are checking items already in the cart. We check for WC_Product_Subscription like normal but once in the cart the product is of the WC_Product_Subscription_Variation class meaning it’s just a variation of a product and not the full product variable class.