How to Disable the Resubscribe feature in Woocommerce Subscriptions Plugin

This brief guide is aimed at developers familiar with WordPress who are looking to disable the Resubscribe feature in WooCommerce’s very own “Woocommerce Subscriptions” plugin.

Let’s dive right in.

Outline

  1. Solution(s).
  2. Show the Work.

At the time of this writing (2023-07-03), there is no option to turn off the “Resubscribe” functionality. If you’ve come into a scenario where that is becoming problematic (not unheard of – plus, I’m also having this issue), you might be searching for a solution.

…And probably didn’t find anything that helped.

Solution(s).

Well I dug through the code and found two quick solutions that you can drop in your child or custom theme’s functions.php file, a custom plugin, or a mu-plugin drop in. The first solution is my preferred method as it effectively disables the feature:

// This simply says "nobody has the authority to resubscribe a subscription ever"
add_filter( 'wcs_can_user_resubscribe_to_subscription', '__return_false' );

The alternative just removes the button from rendering, but if a customer knew how to mock up the url to do it, or was provided a link, could still purchase the resubscription. This might be a better solution for scenarios where you want to modify or tailor how customers get to “Resubscribe”, but still leave it as a functioning feature:

// This method simply removes action buttons like "reactiveate", "resubscribe", and "cancel" from being rendered.
add_filter( 'wcs_view_subscription_actions', function($subscription_actions){
    if ( !empty($subscription_actions['resubscribe']) ) {
        unset($subscription_actions['resubscribe']);
    }
    return $subscription_actions;
});

Both will remove the “Resubscribe” button from being rendered, but only the wcs_can_user_resubscribe_to_subscription filter denies the resubscribe functionality across the site.

Show the Work.

I’d like to show my work so you can A.) follow along, B.) be more informed in your decisions, and/or C.) trust the process coming to these solutions.

Let’s start in the Subscription Details template where the “Resubscribe” button gets rendered: ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/templates/myaccount/subscription-details.php. Inside that file (currently line 78), there’s a function called wcs_get_all_user_actions_for_subscription() who’s job is to get all the “Actions” that are contextually available for that subscription to that user.

We then look at that function’s definition in ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-user-functions.php and see that upon return, it has the second solution’s filter. Here we can remove any of the available options from rendering as an available action. Mind you, this *only* removes the “Resubscribe” button from rendering in the “view subscription” template. Placing a similar button anywhere else will still work!

However, if we’re specifically looking at disabling the “Resubscribe” feature altogether, we see in the middle of the wcs_get_all_user_actions_for_subscription() function, it leverages a function called wcs_can_user_resubscribe_to() – that sound promising! Finding its definitiong in ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-resubscribe-functions.php, we see in its return that it provides another filter wcs_can_user_resubscribe_to_subscription — and ultimately — this is the one I prefer to use.

Using WordPress’s predefined function __return_false for the wcs_can_user_resubscribe_to_subscription filter denies anyone from resubscribing, effectively disabling the feature. Or you could implement your own logic in place of __return_false – another conversation for another time.

Hit me up with any questions, improvements, and/or thoughts you have =]

Cheers,

Ryan

Adding a Page to your WooCommerce My Account Dashboard

So you’re writing a plugin and you want to add your own pages for your customers to use in their dashboards with its own integrated nav link. There’s just one problem: documentation for *how* to do this is…. lacking.

I just spent two hours chasing this one down; I gotchu.

There are three components (2 filters and 1 action, specifically) you’ll need to accomplish this:

  1. Add your menu item to the WooCommerce Nav (filter: woocommerce_account_menu_items )
  2. Add the Query Var to WooCommerce (filter: woocommerce_get_query_vars)
  3. Create a callback to render your content (action: woocommerce_account_{$variable_name}_endpoint)
  4. [Bonus] Detecting if the request is to your new Woocommerce Page

Step 1 puts our nav menu item into the WooCommerce nav on the left (along with dashboard, payment methods, addresses, etc). Step 2 tells Woo to register the endpoint in WordPress so that it’s a known/valid URL for our site. Lastly, step 3 tells Woo what to do when that url endpoint is requested – render stuff in the content area!

Doing it this way lets WooCommerce do the heavy lifting and should work no matter what you’ve modified your ‘my-account’ permalink to. Ultimately, it’s a pretty easy task; figuring this OUT however… Let’s just say that either I don’t know how to google, or docs are seemingly absent on this, so I’m glad you found me here =]

Honestly, this makes one wonder if it’s part of the business model for buying plugins for woo – but I digress…

For this Example

In this example, I’m going to add a page to the my-account dashboard area that allows my customers to see their spend ranking in the store. Other options might be if you want to create a wishlist feature for your e-commerce store, a shipping status monitor tab, or whatever – your reasons are your own, I’m just here to help you get there 😉

What is your account page endpoint going to be? I’m going to call mine “spend-rank” – you’ll see how it determines a lot of things after this (including the actual hook names).

Ok – without further adieu!

Step 1: Adding your Menu item to the WooCommerce Nav

This is done through a simple filter. If my nav item is called “spend-rank”, here’s how it’ll look for me:

/**
 * Add our "Spend Rank" nav menu item as the second to last item (just above logout).
 *
 * @param   array $nav_items    Dictionary of WooCommerce Nav Items for the my-account page.
 * @return  array               The nav items with our spend-rank menu item added.
 */
function spend_rank_set_up_nav_item($nav_items)
{
    // Splice logout off the back of the list and add our spend-rank in just before it.
    $tail_items = array_merge(
        // Notice slug part => Human Readable Menu Item
        ['spend-rank' => 'Spend Rank'],
        array_splice( $nav_items, -1, 1 ) // last item should be logout o.O
    );

    // Smash them back together and return the results
    return array_merge($nav_items, $tail_items);
}
add_filter( 'woocommerce_account_menu_items', 'spend_rank_set_up_nav_item' );

Fire up the my-account dashboard on your WooCommerce site and you should see your menu item there. If you don’t, double check that you’ve lined up your filter callback to the function name and hopefully that gets you squared away.

If you’re wondering about all the array_splice‘ing and array_merge‘ing going on, it’s to keep the keys in place. Dictionaries in PHP are ordered, so it matters!

Step 2: Add the Query Var to WooCommerce

Not to just WordPress… to WooCommerce. This is specific to WooCommerce, so we’re hotwiring it using default Woo filters. Here’s where we tell WooCommerce (and therefore WordPress) about our url path /my-account/spend-rank/ – check this out:

/**
 * Adds our spend-rank query var directly into WooCommerce so it can do all the heavy lifting for us.
 *
 * @param   array   $query_vars Dictionary of WooCommerce query vars.
 * @return  array               Same dictionary with our spend-rank endpoint added in.
 */
function spend_rank_add_query_var($query_vars)
{
    // The key should correlate to your endpoint and be unique(!!!), but ultimately...
    // it's unused AFAIK.
    $query_vars['spend-rank'] = 'spend-rank';
    return $query_vars;
}
add_filter( 'woocommerce_get_query_vars', 'spend_rank_add_query_var' );

In order for this to take effect, we’ll need to re-save our permalinks, but let’s hold off on that for now since WooCommerce won’t know what to do for this yet. Now let’s wire up the render callback.

Step 3: Create a callback to render your content

WooCommerce has done all the heavy lifting for us, and now that we’re done describing that “spend-rank” is a thing to WooCommerce, we just need to tell it what to do in that context. So let’s give it a callback to render our content!

function spend_rank_render_content()
{
    echo "<h1>GO SPEND RANK, GOOOO!</h1>"; // whatever that means to you ;)
}
// Notice how we've added a magical action with "spend-rank" in the action name:
add_action( 'woocommerce_account_spend-rank_endpoint', 'spend_rank_render_content' );

Still doesn’t work? Oh yeah – don’t forget to re-save your permalinks! From the /wp-admin/ area: Settings -> Permalinks -> Save (no edits) OR perhaps on plugin/feature activation, you could try a flush_rewrite_rules() so your customers don’t have to do that manually.

Bonus: Contextually detecting your new WooCommerce Page

Here’s a quick bonus: what if you need to enqueue a special script or style but you’d rather it only be for your new page. You can use the is_wc_endpoint_url function that comes out of the box with WooCommerce. Check it out:

// Can only be run during hook `parse_request` @ $prio > 10 or after
if ( is_wc_endpoint_url( 'spend-rank' ) ) {
    // enqueue a script? wp_die()? You decide! =D
}

That’s pretty much it, y’all! Integrating your plugin’s functionality into WooCommerce should be the easy part. Hopefully this gets you a little closer. Now go write the hard part 😉

Cheers,
Ryan

Rohjaynator::1719086066::26231914