Enabling staging mode for WooCommerce Subscriptions on a SiteGround staging server

To prevent duplicate payments, WooCommerce Subscriptions attempts to confirm it’s being run in the production environment prior to charging customers. The method it uses to detect non-production environments fails on SiteGround staging servers, leading Subscriptions to bill customers in staging environments as well.

When a client reached out saying they’d created a staging server and were now hearing from customers who’d been charged twice on the same day, I initially doubted Subscriptions as the cause of the issue since I’d seen it automatically switch to staging mode for other clients. While working to find the source of these duplicate payments, though, I examined the plugin’s approach to detecting non-production environments. As explained in its documentation, “Subscriptions stores a clone of WordPress’s siteurl value in an option with the name wc_subscriptions_siteurl. It compares this value with the siteurl value to see if it has changed.”

(Subscriptions also injects the string _[wc_subscriptions_siteurl]_ into the middle of wc_subscriptions_siteurl so that it isn’t modified by an automated process responsible for copying the production site to a staging environment—one that might replace all instances of the siteurl value with the staging URL.)

However, SiteGround doesn’t take a traditional approach to its siteurl on staging servers and instead uses the same value on staging and production. (It accomplishes this by modifying the value of HTTP_HOST in the staging environment to match that of the production environment.)

To overcome this issue, I first needed a way to detect SiteGround’s staging environment. With that taken care of, I filtered woocommerce_subscriptions_is_duplicate_site so it always returns true:

// Check whether SiteGround's staging environment has been detected.
if ( defined( 'SITEGROUND_STAGING' ) && SITEGROUND_STAGING ) {
	// Always flag the staging environment as a duplicate site.
	add_filter( 'woocommerce_subscriptions_is_duplicate_site', '__return_true' );
}

Added to a must-use plugin, the above snippet ensures that Subscriptions treats the SiteGround staging environment as a duplicate site, preventing customer charges on that instance of WordPress.

16 comments on “Enabling staging mode for WooCommerce Subscriptions on a SiteGround staging server”

  1. Hi, wow thank you so much!!
    I have been struggling with this for years and never found anything practical to either force staging mode in WC Subscriptions or any workaround. So I manually create my staging site ever since..
    Nevertheless I just tested it and it didn’t work. I created a must use plugin with your code in it. The MU plugin shows in WC Status page so it is detected.
    However, created a staging copy of this website in siteground and WC Subscriptions were still live.
    I am doing something wrong? Thanks!

  2. Hi Martin,

    No problem! Did you also follow the instructions in this post, making sure to add your username to the path?

    (The SITEGROUND_STAGING constant isn’t created by SiteGround; it’s something I added to detect a SiteGround staging server both so I could turn on WooCommerce Subscriptions’s staging mode and so I could activate or deactivate some plugins depending on whether or not a site was running in production.)

  3. Thank you so much for this – saved me so much headache today! Can confirm – still works with WP 5.3.2/ WooCommerce 3.9.3/ Subscriptions 3.0.1.

  4. Hey!

    Great solution, really saved me a headache (and I’m relieved I noticed the banners wasn’t there, eek). Thanks so much.

  5. Hey Greg,

    I’m wondering if you have any solutions for my issue. We have a staging website and I have made changes to errors on the staging website and want to push it live to our live domain.

    The issue is that since taking the copy of the ‘live’ site we have received orders and I don’t want to ‘overwrite’ the new members by deploying the staging website. Can you help?

  6. Hi Adam,

    Pantheon does a good job describing a workflow for staging sites and deployment here:

    https://pantheon.io/docs/pantheon-workflow#code-moves-up-content-moves-down

    The gist is that you only want to be pushing code from a staging server to your production server. If you try to selectively push content (posts, users, uploads and so on) from staging into production, it’s a lot easier to run into problems. In my experience, you can only really get away with pushing both content and code from a staging site into production if the site doesn’t allow visitors to perform any actions: ordering things, commenting, signing up for accounts, etc.

    Hope that helps!

  7. I couldn’t get this to work. I suspect I’m doing something wrong with my MU-Plugin. And yes, I saw your other post and changed the username in the path.

    It’s unfortunate because now I’m going the paid plugin route for staging and pushing to live.

  8. Hi David,

    Sorry this didn’t work for you! It looks like SiteGround has changed the paths they use for staging. I’ve updated my post on detecting SiteGround’s staging environment to take into account these changes.

  9. Well I mean, it’s Woocommerce’s fault really. Who ‘tries to detect’ a staging site lol, especially for something as critical as deciding whether or not to charge people! Put it as a variable in the config file (like any developer with half a brain would know to do), or second best, a setting somewhere in WP Admin. Just another ‘pleasure’ in the world of WordPress I guess.

  10. …. just to clarify, the sentence re “Put it as a variable in the config file (like any developer with half a brain would know to do)” was aimed at the developers at Woocommerce, not author of this article 🙂

  11. In any case, thank you for the tip re the filter we can use to force it to be in staging mode.

  12. Hi Dan—I think SiteGround’s decision to override the `HTTP_HOST` value is the real source of the problem, rather than something WordPress- or WooCommerce-specific. While detecting a staging server by noting the domain name has changed is a valid approach, it runs up against the issue of either hosting companies or developers not wanting to change the `siteurl` between environments.

    (I suppose if there were a criticism of WordPress here, it’s that environment URLs need to be manually changed when switching between environments. Drupal’s approach, as an example, does seem superior, in that the domain isn’t set within the database.)

  13. I think this is outdated.

    Woocommerce has a section regarding this on their official documentation: https://woo.com/document/subscriptions/subscriptions-handles-staging-sites/#section-6

    —-

    It is possible to switch a live site to staging by editing the wc_subscriptions_siteurl from within the _options table to anything different from the siteurl .

    If the web host allows it, the value for wc_subscriptions_siteurl can be changed from the WP Admin by viewing the options page from /wp-admin/options.php. To achieve this from within the WP Admin:

    Append the site URL to include https://YOUR-DOMAIN.com/wp-admin/options.php (replace YOUR-DOMAIN.com with the site’s domain URL)
    Search the options page for wc_subscriptions_siteurl
    Change the value of that option to anything other than the current site URL ( Suggestion: add a character to the end of that value. )

  14. Thanks for your comment! It’s definitely possible this is outdated, as I haven’t had to use it in years. That said, the code above is trying to solve a different problem from what you’re describing, as the goal is to automate the process of setting up a staging server and having it automatically be flagged as not being the production URL, rather than needing to update the option value manually.

Leave a Reply

Your email address will not be published. Required fields are marked *