Let’s say you want to help customers understand your shipping rates and benefits right on the WooCommerce Cart and Checkout pages, by adding a link to each shipping option (e.g. “View shipping FAQ“).
As you can see from the first and second screenshot below, if you enter any HTML within the WooCommerce shipping zone -> shipping method settings, this will be stripped out, and HTML tags such as hyperlinks won’t work.
So, how can we add a clickable text link to each shipping method, given that we can’t use the WooCommerce settings? Well, as usual, a quick PHP snippet can help us with that. Enjoy!
Continue reading WooCommerce: Add Hyperlink to Shipping Method Label @ Cart & Checkout
The WooCommerce settings allow you to define the default customer tax location (“Calculate tax based on” -> “Shop base address“). In this case, when a guest customer enters the checkout, tax will be calculated based on the store address.
The problem is that this option is unusual – businesses require the “Calculate tax based on” -> “Customer billing address” option in most cases.
So, today, we will be setting the default tax location when “Customer billing address” has been chosen AND the customer is either logged out (so, no billing address is set) or logged in but have no saved address (for example, a brand new customer). Enjoy!
Continue reading WooCommerce: Set Customer Default Tax Location
If you run WooCommerce store promotions, this little snippet will help you with that. For example, how to run a “Buy 2 products, get one half off” or a “Buy 3 products, get the cheapest one for free” campaign?
The trick behind this workaround is to find the cheapest item by looping through the cart, and then to set its price so that it’s lower than the regular price. Enjoy!
Continue reading WooCommerce: Apply Discount to Cheapest Cart Item
The amazing thing about WooCommerce is that you can override any setting with a few lines of code. In today’s example we will try to code a solution where the “New Order” WooCommerce email will be delivered to a custom recipient based on the billing country.
This could be helpful when the WooCommerce store is managed by multiple people, and you want to make sure that order notifications only go to the right manager. Enjoy!
Continue reading WooCommerce: “New Order” Email Recipient Based on Billing Country
We’ve already studied how to display the number of sales for a given product ID via a shortcode – however that solution won’t work for a variation ID, because WooCommerce only counts the “parent product” sales.
We need a different workaround in this case. This will require we either query the orders that contain such variation ID, and then calculate the sum – or that we install a snippet on day 0 so that we can count variation sales from that moment onwards, without having to query and calculate anything.
We will study the latter, and then display the result via a shortcode, so that you can use it anywhere, even inside the variation description.
Continue reading WooCommerce: Count Variation Sales (Shortcode)
Especially when you migrate from a different ecommerce platform to WooCommerce, you may end up placing or importing content in the wrong place.
A lot of confusion, for example, arises when a new WooCommerce store owner needs to understand the difference between the “Long” and the “Short” description. Well, the “Long description” is the one that displays inside the “Description” tab, below the product summary (that section that features the image on the left + add to cart on the right), usually in full width. The “Short description“, on the other hand, is the one that shows on the right hand side of the product image, and is usually… shorter.
Now, what if you don’t use the “Short description” in your WooCommerce store, and you wish to display the “Long description” on the right hand side of the featured image instead? Well, here’s a simple snippet for you. Enjoy!
Continue reading WooCommerce: Display Long Description Instead Of Short One @ Single Product Page
You’d think that this was a core WooCommerce setting – it’s not.
In fact, from the WordPress “Customizer“, you can set the product category page display to “Show products” only, “Show subcategories” only, or “Show subcategories and products” (see screenshot below). But these 3 options, in my opinion, could and should do much better.
For example, if you assign a product “ABC” to a parent category “X“, and a product “DEF” to a child category “X->Y“, and if you choose “Show products“, the parent category page will show both “ABC” and “DEF” products, while there should only be 1.
If you select “Show subcategories“, the same page will only have the link to the subcategory, but the product belonging to the parent category, “ABC“, won’t be visible, which doesn’t make sense.
If, even worse, you pick “Show subcategories and products“, the parent category page will display the subcategory link, as well as both products “ABC” and “DEF“, which once again is a bit weird.
Let’s fix this with a simple snippet – enjoy!
Continue reading WooCommerce: Hide SubCategory Products On Product Category Pages
Once again, I’m trying to find WooCommerce anti-spam workarounds to avoid manual admin work like receiving hundreds of emails, deleting hundreds of fake orders and fake WordPress users.
In today’s “episode” I will try to clean the WordPress User database table after a failed order, because I’m really angry when “17PmU3MmKZS9ZAy7 17PmU3MmKZS9ZAy7” manages to register an account on Business Bloomer after a carding attack!
Please test this snippet on a dev/staging environment and not directly on the live site. Deleting a WordPress user is never a good idea, so you need to make sure everything is working as it should. Enjoy!
Continue reading WooCommerce: Delete Customer After a Failed (Spam) Order
We could call this the “WooCommerce Anti-Spam Without a Plugin” series, while I attempt to fight against bad humans and very bad bots who love attacking the Business Bloomer checkout page with spam orders and fake user registrations.
My first attempts were (1) My Account registration anti-spam honeypot, (2) Checkout anti-carding-attack honeypot, and (3) Reducing the number of admin emails, but I can tell that (2) didn’t work, and I got another carding attack on a $9 product last weekend. Bots are smart.
Today, I’d like to share another anti-spam snippet that I’m currently testing on Business Bloomer. Most carding attacks, in fact, end up with the purchase of a single product in the $1-$9 range – which means that limiting the daily sales for specific, inexpensive, products may do the trick.
My code counts the times each product has been purchased during the day – and if a carding attack occurs, the product won’t be purchasable any longer until the end of the day. Because we’re talking about cheap products, it’s no problem for me to disallow legit sales as well for 24 hours. Use at your own risk, of course.
We already covered how to “Limit Sales Of A Product Per Day“, but this time I’d like to apply that to an array of products – and specifically all those that are under $10. Enjoy!
Continue reading WooCommerce: Limit Daily Sales For Cheap Products (Anti-Spam)
Here’s my second attempt to fight against WooCommerce spam, without installing a captcha plugin. A few posts ago I covered the My Account user registration spam, so today I want to tackle the WooCommerce Checkout, and try to “trick” spam bots.
Of course, this is a workaround and smart bots may understand you’re tricking them. So, feel free to test this first and let me know if it stops spam orders, card testing attacks, and tons of fake user registrations.
Same as the other post, I will be adding a custom hidden checkout field with an empty value. This won’t be visible to the customer, but will be to spam bots, which will try to post a value. My validation code will, however, generate an error if the custom field posts a value, and therefore should prevent most spam bots from going through.
Let me know if it works!
Continue reading WooCommerce: Checkout Anti-Spam Honeypot
The “Password Changed” email is – actually – a WordPress core notification. It goes to admins when a WordPress user changes their password, and the email body says something along the lines of “Password changed for user: XYZ“.
So, why are we saying this email notification can be stopped if you run a WooCommerce website? Well, because WooCommerce provides us developers with a handy filter, that we can use for this exact reason.
For what concerns my own experience, I use Sendgrid to deliver Business Bloomer WordPress/WooCommerce emails – and on the free plan I have a limit of 100 daily emails. Which means I needed to find a way to reduce the number of email notifications.
Today we’ll cover the “Password Changed” one – let’s see how to stop administrators from getting them!
Continue reading WooCommerce: Disable “Password Changed” Administrator Emails
The WooCommerce Single Product page, on top of letting you add to cart the current item, also displays a list of related products and up-sells (when defined).
But what if you ALSO want to show a grid of “related product categories”, so that the customer can easily navigate to a category page instead of a single (related) product?
In this experiment, we will first calculate the current product’s categories, and then use a WooCommerce shortcode to output them as a grid, right below the related products section. Enjoy!
Continue reading WooCommerce: Display “Related Product Categories” @ Single Product Page
We’ve already covered a similar customization on Business Bloomer: how to display Ajax quantity selectors on the WooCommerce Shop page. The problem there was that that only works for simple products, and only when Ajax add to cart is activated via the WooCommerce settings.
Today I’d like to experiment a little, and see what happens when we include the “add to cart template” (i.e. the one you see on the WooCommerce Single Product page) under each product on the WooCommerce Shop page.
This *should* work with all product types – especially variable products – because you will see the attribute dropdown selectors in such a case, as if you were on the single product page.
I haven’t tested this with grouped, bundle, and special product types, so feel free to share your findings in the comments below. Enjoy!
Continue reading WooCommerce: Add to Cart Form @ Shop Page
There is a native, handy way to get a WooCommerce customer’s last order: wc_get_customer_last_order( $customer_id )
This time, I want to write some custom code to get the second last order instead. We will indeed reuse most of the above function code and change it slightly. Enjoy!
Continue reading WooCommerce: Get Customer Second Last Order
Ever wondered if you could toggle payment gateways based on whether a given “product type” is in the WooCommerce Cart? For example, disable PayPal if there are simple subscription products, or enable Stripe only when there are variable products?
Well, with this simple code (and the 2 examples) you find below, you can manage to achieve just that. The second example regards the WooCommerce Subscriptions plugin, as this requires some plugin-specific functions to check for the product type. Enjoy!
Continue reading WooCommerce: Disable Payment Gateway By Product Type
Getting the list of cross-sells for a WooCommerce product is actually super easy (yes, it’s one line of PHP). But what if you need to “calculate” the list of cross-sells for an entire order, made of different products?
In this short tutorial for developers we’ll see both: how to get the cross-sell IDs for a product, and how to get the entire range of cross-sells based on what’s been purchased in a given order. Enjoy!
Continue reading WooCommerce: Get Product / Order Cross-Sells
Especially when you need to let other people (such as developers) log in to your WooCommerce website, you may want to protect the identity of your customers and your order details.
Of course, anonymizing your WooCommerce backend requires a complete database override – this change is 100% irreversible! Only run this code if you know what you’re doing.
The ideal workflow is the following: you give developers access to a staging/clone website version, you run this custom code to anonymize customers and orders, and have them do the changes. This is good for GDPR, CRPA and PIPEDA as well: third party people won’t see sensitive data.
One more note: I haven’t tested the code with thousands of customers and orders – feel free to leave a comment in case your (staging) website crashes. Enjoy!
Continue reading WooCommerce: Anonymize All Users & Orders
Grouped Products are part of WooCommerce core and let you “add similar (think materials, design, etc.) products to a single grouped product. This allows the customer to add products […] to their cart on one page instead of navigating to several different pages to do so” (WooCommerce docs).
It may happen during your coding career that you need to know whether a given Product ID is part of a Grouped Product (so, it’s a “child” of a Grouped Product) – the snippet below will help with that. Enjoy!
Continue reading WooCommerce: See If Product ID Belongs To a Grouped Product
Here’s my personal attempt to fight against the WooCommerce My Account Page registration spam, without installing yet another captcha plugin.
I’m pretty sure this solution is not perfect, because spam bots are very “smart”, but it can help prevent most fake registrations.
The way I built it, is by adding a custom input field to the My Account Register form with an empty value. Hidden via CSS, this is not visible to the user – but it is visible to spam bots, which will try to post a value. The trick here is the validation check; an error will be generated if the input has a value, and therefore should prevent most fake registration to go through.
Take a look at the code, test it, and enjoy!
Continue reading WooCommerce: My Account Registration Anti-Spam Honeypot
Ok, this is a little hacky and pretty manual, but it happened to me in the past that the inbuilt WooCommerce CSV product export was just not enough.
In other words, the default product export that you can find by clicking the “Export” button on the “Products” WordPress Dashboard screen, gives you the option to export all products to a CSV. You can also refine the list by product type and product category, so that you can export specific products only.
What’s missing there is a “product tag” filter, so this workaround will let you do just that – define a product tag slug in the snippet below, and your export list will be automatically filtered by that.
Of course, you could find a dynamic way of doing that, but for now we’ll keep this manual and hardcoded into the PHP function. Enjoy!
Continue reading WooCommerce: Allow CSV Product Export By Tag