The point of this post is to help others that are having a problem dynamically adding a variation of a product (or subscription product in my case) to cart. I get to that at the bottom of this post if you want to skip the story.
The Problem
I have a pretty high up there client in the box subscription world. I’ve been brought in to do some WooCommerce functionality with WooSubscriptions and everything else involved.
The checkout process is pretty customized. We have a page that displays all the attributes available for the subscription variable product. There’s a bunch of fancy selection boxes and lists and gift inputs and so on. It’s front end heavy but communicates with a custom endpoint through the REST API that I wrote to add the item to cart. Problem is, the sub form doesn’t give me a variation id, only the variable subscription product id and all the selected attribute values.
Finding the Variation
The first step is to find which variation they’ve selected. Someone long before me went through the rigorous process of creating some 50-60 variations of this variable subscription product to match all the different options a user could select.
So I use a WP_Query search the for any post id that has all the meta_key/meta_value matches and select it. It was a bit of a pain to figure out the best process here but this works.
Adding the Variation to Cart
Took me a few to find the right parameters for adding a variation to cart. Now that I had the post id of that variation it looked pretty simple from what I found online:
$added = WC()->cart->add_to_cart( $query->post->post_parent, 1, $data['variation_id'] );
This did the trick. Since I used a WP_Query to get the post I could select the parent (which is the main subscription variable product) needed for first parameter. Then the quantity, then the variation id. Which was $query->post->ID but I assigned it to some data my API was returning.
The user checked out and the variation was in the order. A day after pushing this code the site owner asked where the order details went. Turns out it original showed the selected attributes in the admin order panel. I spent a couple hours figuring this out, which I feel dumb now, but going in blind what can you expect.
You have a fourth parameter you can for $variation_data. This gives it the attribute love it wants and adds it to the order. Why woo doesn’t just do this automatically if a variation is added? Beats me. But here’s how you do it using a nice woo provided function for variations.
$added = WC()->cart->add_to_cart( $query->post->post_parent, 1, $data['variation_id'], wc_get_product_variation_attributes( $data['variation_id'] ) );
This saved me a TON of hassle – I had no idea that function (`wc_get_product_variation_attributes`) existed. And I was wondering the exact same thing – if you’re already passing the variation ID, why doesn’t WooCommerce do this bit for you? My guess would be some legacy nonsense… but this totally works for me. Thanks!
Definitely legacy nonsense. Glad it helped!
Jeez, Chris, thank you for that post. I was going crazy since few days. That sneaky vicious fourth parameter…
Glad it helped! Yea, I went crazy trying to figure that out.
You have saved me so much investigatory work. Much appreciated!
Happy it helped!
Thanks Chris!
I knew that I had to add the attributes, but I couldn’t figure out how.
Thank you for sharing.
Glad it helped!
Thanks !!
Thanks to you I have managed to solve a problem with my theme.
Reggards.
Where do i put it ?