Debug WooCommerce without admin knowing (not in a bad way) - enable a payment gateway and redirect emails in code.
A friend contacted me asking for help on a client’s WooCommerce site. I needed a way to verify the changes by making test orders without triggering emails to the client. I also didn’t want to pay for the orders as the client could be slow to refund me.
Staging Site Testing
The client purchased the WooCommerce Extra Product Options plugin to provide product variations with images to help the customer choose the font and images to be printed onto the product. The order emails did not list the chosen options in an easy-to-read format. My friend asked me to sort this out.
I started out by creating a site on a multisite installation that I use for testing and development. I installed the required plugins and imported the products. I experimented with the plugin options and fixed the issues. Then I copied the changes back to the live site.
Secret Live Site Testing
The client liked the fixes but had a few questions. I wanted to confirm the fixes by making some test orders. As she only has one payment gateway, PayPal, and I knew that getting refunds will be slow, I decided that I would enable the Direct Bank Transfer gateway (internally called ‘BACS’ but it’s not obvious why) for my test orders. Obviously I wouldn’t want other customers to see this payment option so I started looking into enabling the gateway in code.
I didn’t want to enable the BACS gateway in the admin (and disable it in code) because I wanted the code to be self contained and the site to revert to normal when the plugin is disabled.
Enabling Payment Gateway For A Single User
I remembered seeing a post on Business Bloomer about disabling a payment gateway. The blog has quite a few posts mentioning ‘gateway’. I soon found the Disable Payment Gateway for a Specific User Role post.
The code uses the ‘woocommerce_available_payment_gateways‘ filter. The BACS gateway was enabled by default in this filter but then not shown on the checkout page (because it is disabled in the admin area). Obviously the BACS gateway was being disabled later in the process. I could not find any filter that would allow me to step in when the code was checking whether the gateway is enabled. I eventually decided that I would have to trap the call to get_option() (which was all the way in WC_Settings_API::init_settings()) – I used the ‘option_woocommerce_bacs_settings‘ and simply changed “‘enabled’ = yes”
Redirecting Admin Order Emails
I didn’t want to annoy the client with order emails so I had to redirect these to me. I picked one email (New Order) and followed the template file (templates/emails/admin-new-order.php) back to the class file (includes/emails/class-wc-email.php) and the get_recipient() function where I could use the filter to change the recipient. The filter tag changes for each email (it uses the email ID as set in the class for that email e.g. New Order is in includes/emails/class-wc-email-new-order.php and has an id of ‘new_order.’
Checking the User
The next step was to limit the code to only run when the a specified user is active.
I decided to do this check early on, for easier code maintenance and to minimise the amount of code run if the specified user is not active. UPDATE: I had to move the check into the called functions because get_current_user_id() does not return a valid value until after the ‘init‘ action is run, but the class is created (and the define_public_hooks() function executed) before this.
I converted my procedural code to a class (inspired by WordPress Plugin Boilerplate) – I am trying to make all my new code OOP.