How we started running BFCM sales and made an extra $150k

In the early years of @pmproplugin, we never ran sales.

In 2017, we ran our first Black Friday/Cyber Monday sale. Now we run 3 sales per year.

What were we worried about early on? What changed our mind?

If you want sweet BFCM ๐Ÿ’ฐ, but have concerns, this thread is for you.๐Ÿ‘‡๐Ÿงต

First, what kind of sweet cash are we talking about?

We’ve commonly heard that a BFCM sale can bring in 25-100% of your typical November revenue.

In software, where late November and December are slow times, that can be a nice bump.

Seasonal sites can do even better.

For us specifically, we make an additional 20-30% revenue any month we run a sale. At 3 sales per year, this is about 5% of our annual revenue or ~$150k over 4 years.

For reference, it cost us ~$150k to renovate our garage into a “sweet” home office.

In 2016 though, we were nervous about running sales. We were worried about:

(1) Confusing our customers.
(2) Looking cheap.
(3) Wasting time.

We’ve since made sales software for WordPress sites that addresses these concerns specifically.

I’ll include a link to that software at the bottom of this thread, but first let’s break things down and hear how we got over these fears and are now running successful sales 3x/year.

(1) We didn’t want to confuse our customers.

In 2016, we weren’t even sure if we had our standard pricing down. We were changing our plans and pricing every year or so already. We thought throwing a discount into the mix would confuse our customers.

We thought running sales would confuse ourselves too. Sales would muddy up the data we were tracking.

How could we tell if that price increase to $297 was really working if we sometimes were still selling things for $197?

BTW, consider running a sale when you’re about to raise prices. You’re set up for a natural experiment of sorts where you can honestly say something like:

“This is your last chance to purchase before we raise our prices. Lock in now.”

(2) We didn’t want to look cheap.

This is a big one and almost common knowledge for ecommerce stores.

We were concerned about how discounts, especially running sales too often, could hurt our brand image.

We were already fighting the image we had as “the free membership plugin” since all of our code was fully GPL and available for free.

Running a sale could send the message that our paid services weren’t worth the full price.

In reality, our service was the best and worth more.

We all know how jewelry stores at the mall are perpetually selling things for 50% off the list price, training us to take every price we see and cut it in half.

Even now, in mid Sep, if you visit the websites of traditional jewelry stores, they are littered with sales pricing.

Perpetual sales might work for some businesses, but we didn’t want to send the message that our PMPro Plus membership was “cheap”.

Our plugin was the best. Our service was the best. We should be charging the highest prices, not be “forced” to put our membership on sale.

(3) We didn’t want to waste our time running sales every month.

Each sale involves at least a few hours writing up sales copy and emails. At worst, it involves designing one-time landing pages and custom programming to handle the pricing logic.

What do you do if someone who purchased in July for $197/year is checking out in November for $147/year?

Here’s a small snippet of *some of* the pricing logic we used to have running on the site. The current pricing.php file is about 140 lines of code.

<?php
// This is an excerpt from *some of* the custom pricing logic we had running on our site to support legacy prices and sales.
// Our current custom pricing script is about 140 lines long.
/*
If purchasing PMPro Plus and they've had plus or core in the past,
calculate the appropriate price.
*/
if($level->id == 20 && is_user_logged_in()) {
// If the user has a current subscription, use the billing amount on file.
$user_level = pmpro_getMembershipLevelForUser();
if( pmpro_hasMembershipLevel( 20 ) && pmpro_isLevelRecurring( $user_level ) ) {
$level->initial_payment = $user_level->billing_amount;
$level->billing_amount = $user_level->billing_amount;
} else {
// Check if they had a discount in the past.
$paid_47 = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = {$current_user->ID} AND membership_id IN(6,20) AND total IN('47', '47.00') AND status NOT IN('refunded', 'token', 'error', 'review') AND timestamp < '2017-08-30 00:00:00' LIMIT 1");
if($paid_47) {
$level->initial_payment = '47.00';
$level->billing_amount = '47.00';
return $level;
}
$paid_97 = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = {$current_user->ID} AND membership_id IN(6,20) AND total IN('97', '97.00') AND status NOT IN('refunded', 'token', 'error', 'review') AND timestamp < '2014-08-30 00:00:00' LIMIT 1");
$paid_147 = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = {$current_user->ID} AND membership_id IN(6,20) AND total IN('147', '147.00') AND status NOT IN('refunded', 'token', 'error', 'review') AND timestamp < '2017-08-30 00:00:00' LIMIT 1");
$paid_197 = $wpdb->get_var("SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = {$current_user->ID} AND membership_id IN(6,20) AND total IN('197', '197.00') AND status NOT IN('refunded', 'token', 'error', 'review') AND timestamp < '2017-08-30 00:00:00' LIMIT 1");
if($paid_97 || $paid_147 || $paid_197) {
$level->initial_payment = '147.00';
$level->billing_amount = '147.00';
}
}
}
view raw gistfile1.php hosted with ❤ by GitHub

When we did client work, some clients were constantly looking for the right discount/invite scheme, and every month we’d have to update their pricing across the site.

And every month, we’d have to write code to handle all these new edge cases we were creating.

So what changed our mind? Mostly it was FOMO.

We had heard from friends (@scottbolinger, @learnwithmattc, @pippinsplugins, and others) who were making 25-100% of their typical Nov sales just over BFCM weekend.

Again, Thanksgiving week was one of our slowest periods. The whole month of December is usually our lowest-revenue month.

Getting an extra month’s worth of revenue during this time helps a lot of smooth things out.

It also gives us a nice bump when we are calculating bonuses.

Here are our November sales from 2016 and 2017 with the BFCM weekend highlighted.

2016 – no sale. 2017 – with sale.

Here is a shot of our revenue from last November, 2020. In addition to extra sales from our promotion that month, we benefit from all the recurring sales year after year.

November went from a slow month to our busiest month.

My friends who had run BFCM sales eased our concerns 1-3 as well.

Q: What about people asking for the discount after the sale is over?

A: It was just a few people the following week and no one after that.

We recommend giving these folks the discount.

Q: Do you think the sale hurt your brand or undermined your pricing?

A: No. People *expect* us to be running a sale over BFCM.

This is the one time of year you can rune a sale without it looking bad.

Q: Are you spending all your time running sales now?

A: Yes and no.

Some of those we talked to run sales almost every month now. Some just a few per year.

The latter appeals more to us, and after some experimenting, we have settled on 3 sales spread throughout the year.

For the past few years, every year, we run a Black Friday/Cyber Monday sale one week in November.

Then a Spring Sale one week in March-May.

Then a Summer Sale one week in June-August.

We experiment with content, pricing, and length, but also have templates we can reuse easily.

That’s our story of how we came to start running Black Friday/Cyber Monday sales, made a bunch of money, built a home office, and now are trying to help others do the same.

I’d love to hear from others who have had similar success, or better yet different struggles with sales.

Oh yeah. Here’s our pitch for Sitewide Sales, a complete BFCM and flash sale plugin for WordPress.

https://sitewidesales.com/

It works with WooCommerce, PMPro, EDD, and other ecommerce plugins.

I said that we address concerns 1-3 directly, and it really does.

Originally tweeted by Jason Coleman ๐Ÿค”๐Ÿ’ก๐Ÿ’ป๐Ÿ’พ (@jason_coleman) on September 13, 2021.