I've been writing WooCommerce plugins for client sites for years. Last week I submitted one to the WordPress.org plugin directory for the first time. It's currently "Awaiting Review", so this isn't a post about what the reviewer said — it's about everything I had to change just to submit honestly.
If you're planning your first submission, especially a freemium one, these are the four that cost me real time.
1. Your plugin name is probably wrong
Mine was "Quantity Manager & Tiered Pricing for WooCommerce". Two problems:
- Guideline 17 rejects generic names. A name that just lists two features is generic.
- You can't start a name with "WooCommerce" (trademark). "for WooCommerce" inside the description is fine; leading with it isn't.
I renamed it to "PlugStack Quantity Manager & Tiered Pricing". That fixed the generic problem and created a new one: names that begin with a company name can only be submitted by the verified owner, and verification is done through the email on your WordPress.org account. My account was on Gmail. So before submitting I had to set up hello@plugstack.dev (Cloudflare Email Routing → Gmail works fine) and change my profile email.
The slug is derived from the name, so the rename also touched the text domain, the folder, the Freemius product settings and every doc URL on my site. Do this on day one, not day 30.
2. "No locked features" is not a suggestion
The submission form asks you to confirm the plugin contains no artificial restrictions or license-gated functionality. I read that as "don't cripple it". It actually means: the free build must not contain the PRO code at all.
My 1.0.0 free build had the PRO features in the codebase, disabled with a helper:
if ( qmtp_is_pro() ) {
// role-based rules, decimal quantities, etc.
}
That's gating, even though nothing was visible. The fix was to move every PRO method into Freemius __premium_only methods and mark PRO-only files with @fs_premium_only, so the generated free build simply doesn't include that code. The only is_pro() calls left in the free build are three one-line "Also available in Pro →" notes, which is the accepted form of upsell.
No disabled inputs. No greyed-out tables. If it's not in free, it's not on the screen.
3. The build you submit is not the code you wrote
This one I didn't see coming. Freemius generates the free build by reprinting any PHP file that contains __premium_only through an AST round-trip. Two side effects:
- // translators: comments inside array literals get dropped
- end-of-line // phpcs:ignore comments move to the next line
My source passed Plugin Check with zero errors. The generated free zip had 7 errors and 6 warnings, all MissingTranslatorsComment and nonce sniffs. I spent an hour assuming I'd broken something.
Rules I now follow in any file that contains PRO code:
- /* translators: ... */ goes on its own line before the statement, never inside an array
- phpcs:ignore goes on its own line before the statement
- read request vars with filter_input() instead of $_GET/$_POST — the nonce sniff doesn't fire at all
And the real fix: always run Plugin Check on the generated zip, not on your source. I wrote a small script that simulates the Freemius split locally so I can catch this before uploading.
4. You will bump versions with zero users
1.0.0 → 1.0.1 (PRO split rewrite) → 1.0.2 (build-tool fixes). Nobody has installed it. That's fine. Don't try to keep 1.0.0 "clean" for the launch — the number doesn't matter, the changelog does.
What I'm still nervous about
Guideline 18 — "hundreds of similar plugins". There are about 275 min/max quantity plugins and ~170 tiered pricing plugins already in the directory. My argument is that most of them only enforce rules on the single product page, and mine enforces them on every add-to-cart path including the block cart/checkout and the Store API. Whether a reviewer agrees is out of my hands.
I'll write a follow-up when the review comes back. If you've been through this and there's something obvious I'm about to get caught on, I'd genuinely rather hear it now.