What the plugin review team made me rebuild, and why every round of their feedback was worth listening to.
The approval email arrived late Friday afternoon. I was with family, spending time with my son, and I don’t usually read email before I go to bed. This time I did. I almost got up and went straight back to the desk. Instead, I closed the laptop and got a good night’s sleep. This morning, coffee first. Then the listing went live.
MemberMagix is now on the WordPress.org plugin directory. Version 4.0.4.
A year ago I walked into a room in Lisbon
About a year ago, I spent a Saturday inside a university auditorium in Lisbon at WordCamp Lisboa 2025. Sporting CP was celebrating outside. I was inside with a room full of people who turned out to be the WordPress community I’d been using the software from for over a decade without knowing existed. I wrote that story already in “Lisboa Had Two Champions Last Weekend”, so I won’t retell it here.
I’m not a WordPress evangelist. I dip between many waters. I like it that way. Part of why this launch was harder than it should have been is that I showed up to the plugin review with the instincts of a freelance builder, not a WordPress insider.
This post is about what happened between clicking submit on version 1.0.0 and reading the email on Friday. It’s the story the previous two MemberMagix posts didn’t tell, because when I wrote them the plugin wasn’t approved yet.
The clash nobody tells you about
When I build software for clients, I optimize for user experience. Everything in the admin panel. One install, one activation, full functionality. No documentation required, no second plugin to find, no decisions the user has to make just to get started. That is how I think about quality.
WordPress.org optimizes for something different. They optimize for user freedom. Nothing in the free plugin may be locked. Nothing visible may be out of reach. No teasers, no coming-soon badges, no disabled buttons. The free plugin must be a complete, standalone product with no shadows of a future upgrade falling across the screen.
These two design goals fight each other. I learned that the hard way, across four major versions and several rounds of review.
Round one: the sheer length of the list
The first feedback email didn’t sting because of any single comment. It stung because of the length.
Escaping. Sanitization. Translator comments on every string with a placeholder. register_setting calls missing their sanitize callback. Google Fonts loaded from a CDN instead of the system font stack. Third-party services not disclosed in the right place in readme.txt. A long page of items, each one small on its own, collectively a statement: you did not read the handbook closely enough.
I spent the next few days fixing every single item. Each version bump an act of contrition. The plugin came out cleaner. And then I made the mistake that cost me the next month.
The mistake: building during the wait
The review queue is slow. I should have waited. Written documentation, built a landing page, talked to people. Instead I stayed in flow, because that’s what builders do. When I’m in the zone, stopping feels like a kind of dying.
So I kept coding. I migrated plugin licensing from Lemon Squeezy to a self-hosted Keygen CE server. I built in-plugin Stripe Embedded Checkout so users could upgrade without ever leaving the admin. I added premium content, three-tier pricing, reusable magic link tokens, single-session enforcement, a fully branded email template. Every version made the plugin better from a user-experience point of view. Every version also pushed it further from what WordPress.org’s directory allows in a free plugin. I didn’t see that second graph until much later.
Round two: the rupture, and version 4.0
The next round of feedback was gentler in tone and heavier in content. The message was simple: the free plugin you’re proposing has too much commercial machinery attached to it. You can’t ship Stripe here. You can’t ship an in-plugin checkout here. You can’t ship a licensing layer here. Those belong in a separate paid plugin that hooks in from outside. The free plugin must stand on its own.
I remember sitting with that email and understanding what it meant. I had to take the version I was proudest of, the one where everything lived in a single admin panel, and break it in half.
Version 4.0.0 was that break. The internal prefix renamed from mmx_ to mmax_ because mmx wasn’t unique enough on WordPress.org. Every commercial feature extracted into a separate add-on called MemberMagix Pro. Eighteen extension points added to the free plugin so that Pro could reach back in through standard WordPress filters. All inline JavaScript and CSS moved to enqueued files. GPL headers on every PHP file. The kind of refactor you don’t see coming the night before you submit version 1.0.0.
There is no medium-sized way to cut a plugin in half.
Round three: trialware
“Trialware” is the WordPress.org term for anything in a free plugin that looks like a premium feature hiding behind a curtain. A locked button. A greyed-out tab. A feature the user can see but not use. The review team reads that as bait, and bait is forbidden.
MemberMagix got flagged for it twice.
The first flag was about custom overlays. MemberMagix overlays are implemented as a custom post type, because they need to be editable in Gutenberg like anything else. Only admins can create them, which is how WordPress custom post types work. The review team looked at that and read “hidden feature.” They weren’t wrong about what they saw. They were wrong about the intent. Instead of arguing, I surfaced the overlay custom post type in the admin menu and documented it clearly.
The second flag was about the content protection meta box, which I’d restricted to posts and pages. I’d done that to keep the free plugin focused. The review team read it as “protection for other post types is a paid upgrade.” Also a fair read, given their rules. I opened the meta box up to every public post type in v4.0.4.
I didn’t argue. I fixed both. You don’t argue with the review team the way you don’t argue with a lifeguard. They’re watching something you can’t fully see, and they’re right more often than they’re wrong.
The catch I’m actually grateful for
The same round of review brought something I didn’t expect: a real security finding.
There was a REST endpoint in my plugin called check-email. It existed so the signup form could tell whether a submitted email already had an account and route the form into “sign up” or “log in” mode. Elegant from a user-experience angle. Broken from a security angle. The endpoint leaked account existence. Anyone could query it and find out whether a given email had a profile on the site. That’s textbook user enumeration, and it was sitting inside a plugin I had positioned as secure.
The WordPress.org security audit caught it. I hadn’t. That is exactly what a real review team is for.
I removed the endpoint, collapsed the two-step form into a single step, and made terms acceptance required on every request so the flow can’t leak anything by accident. Version 4.0.4 shipped with the fix and went into review one last time.
I appreciated the catch. This is the kind of find that pays for the whole ordeal by itself.
The email, again
So the approval arrived late Friday afternoon. I was with family, spending time with my son. I don’t usually read email before I go to bed. This time I did. I was so excited I almost got up and went straight back to work.
Instead I closed the laptop and slept.
This morning, coffee first. Then the listing.
What’s free, what’s Pro
The free version of MemberMagix is exactly what the review team asked for: a complete, standalone content protection plugin. Passwordless magic-link login. Server-side protection, which means the protected content never leaves the server for a visitor who isn’t allowed to see it. A blur overlay with a signup form where the content would have been. Member management, CSV export, brand customization for the form and overlay. You install it, you activate it, it does the job. Nothing is held back. Nothing grey.
MemberMagix Pro is the separate add-on for people who want to take it further. The heart of Pro is an inline Stripe checkout that is, honestly, one of the smoothest I’ve built. PayPal support is coming next. Bulk content protection across your archive. Custom overlay design. Pro is not a demo of features hidden from free. It’s a set of commercial capabilities that exist because some creators genuinely need them.
Pro ships in the coming days. I’ll write about that separately when the listing is live.
Three rules for anyone about to submit their first plugin
Run Plugin Check locally before you send anything. It runs the same rules the review team runs. Every issue you fix before submission is a round you don’t have to sit through.
Budget for more than one review round. The honest number for a non-trivial plugin is three or four. Plan accordingly.
And do not put commercial machinery in your free plugin. Not Stripe, not licensing, not premium tiers. Build the free version as if the paid version does not exist yet, and then build the paid version as a separate add-on that hooks in through filters. Your future self, sitting with a “you have to split this in half” email at six in the morning, will thank you.
The horizon
MemberMagix is live in the WordPress.org plugin directory today. The free version is already the thing I wish had existed a year ago, when I was trying to put a simple email gate on a CRM knowledge base. Pro is next.
And the review team? They do a hard job, mostly without thanks. I’m grateful they made me rebuild the plugin. I’m grateful they caught the bug. I’m grateful they told me no when I needed to hear it. The plugin I would have shipped without them would have been slower, riskier, and less useful to the community it’s meant to serve.
A year ago I walked into a room in Lisbon as a WordPress user.
Today my code runs on wordpress.org.

Leave a Reply