DEV Community

Cover image for Building a SaaS Licensing System With WooCommerce – No Custom Tables, No License Keys
Joshua
Joshua

Posted on • Originally published at hafenpixel.de

Building a SaaS Licensing System With WooCommerce – No Custom Tables, No License Keys

You can run a SaaS product on WooCommerce. Not a huge one – but for a niche tool with a few hundred users, it works surprisingly well. No custom database tables, no license key management, no Stripe integration. Just WooCommerce Subscriptions, a custom plugin, and WordPress User Meta.

I built this for a client who runs a price calculation tool for hair salons in Germany. The tool helps salon owners calculate their service prices based on employee count, material costs, and time. Over 100 salons pay annual subscriptions to use it. The entire licensing, payment, and access control system runs on WooCommerce.

Here's how it works technically – and why I chose this approach over a traditional SaaS stack.

The Setup

The client had a working tool but needed a way to sell access to it. The requirements:

  • Annual subscriptions with automatic renewal
  • 6 license tiers based on salon size (0, 2, 5, 10, 15, 30 employees)
  • Self-service purchase and renewal
  • The client (non-technical) should be able to manage everything himself

The obvious choice would have been a custom SaaS stack: Stripe Billing for payments, a custom backend for license management, a separate admin panel. That would have cost €15,000–20,000 and taken 8–12 weeks.

Instead, I built it on the existing WordPress installation where the tool already lived.

The Key Insight: User Meta Instead of License Keys

Traditional license systems generate keys, store them in a database, validate them on every request. Keys can leak, need rotation, and require a custom management UI.

I skipped all of that. The license is tied to the WordPress user account. When someone buys a subscription, four values are written to wp_usermeta:

// That's the entire "license"
update_user_meta($user_id, 'sve_license_active', 'yes');
update_user_meta($user_id, 'sve_license_expiry', $expiry_timestamp);
update_user_meta($user_id, 'sve_license_level', $level);
update_user_meta($user_id, 'sve_license_sku', $product_sku);
Enter fullscreen mode Exit fullscreen mode

No custom tables. No license keys. No keys that can leak or be shared. The license is bound to the WordPress account – the user logs in and has access. That's it.

This works because the tool runs as a WordPress plugin on the same installation. It's not an external SaaS that needs API authentication. It's a page on the same site, protected by standard WordPress login.

Access Control

A single function checks access and returns one of three states:

function check_access($user_id) {
    $active = get_user_meta($user_id, 'sve_license_active', true);
    $expiry = get_user_meta($user_id, 'sve_license_expiry', true);

    if ($active !== 'yes') return 'none';
    if ($expiry < time()) return 'readonly';
    return 'full';
}
Enter fullscreen mode Exit fullscreen mode

Three states, not two. This is the part I'm most happy with:

  • full: Active license – create new calculations, full access
  • readonly: License expired – can still view all old data, but can't create new calculations
  • none: No license at all

The readonly state is deliberate. When a subscription expires, the user doesn't lose access to their data. They can still log in, see all their calculations, export their data. They just can't create new ones. That's a much better experience than a hard lockout – and it's a strong incentive to renew, because they see exactly what they're missing.

WooCommerce Does the Hard Part

Payment processing, subscription management, renewal reminders, failed payment handling – WooCommerce Subscriptions handles all of it. I just hook into the lifecycle events:

// Activate on purchase
add_action('woocommerce_order_status_completed', 'activate_license');

// Extend on renewal
add_action('woocommerce_subscription_renewal_payment_complete', 'extend_license');

// Deactivate on cancellation
add_action('woocommerce_order_status_cancelled', 'deactivate_license');
add_action('woocommerce_order_status_refunded', 'deactivate_license');
Enter fullscreen mode Exit fullscreen mode

The activate_license function reads the product SKU to determine the license level, calculates the expiry date, and writes the four User Meta values. That's ~30 lines of PHP for the entire activation logic.

PayPal Commerce Platform handles payments. The activation is gateway-agnostic – it triggers on order_status_completed, regardless of whether the customer paid via PayPal, credit card, or bank transfer.

What the Client Can Manage Himself

This was a hard requirement: the client is not technical. He needed to manage everything through the WordPress backend without calling me. He can:

  • Create and modify license tiers (just WooCommerce products)
  • Edit all text content on the tool pages
  • Configure email intervals and content for expiry reminders
  • Create coupons and upgrade discounts
  • View all active licenses (it's just a user list with meta fields)

No custom admin panel needed. The WordPress backend is the admin panel.

The Cost Comparison

WooCommerce Approach Traditional SaaS Stack
Development time ~4 weeks part-time 8–12 weeks (estimate)
Development cost Low four figures €15,000–20,000 (estimate)
Hosting/month Standard shared hosting €50–200/month (cloud)
Payment processing WooCommerce + PayPal Stripe Billing integration
Admin interface WordPress backend Custom-built
License management User Meta (4 fields) Custom database + API

The WooCommerce approach was faster, cheaper, and gave the client full control from day one. The tradeoff: it doesn't scale to thousands of concurrent users. But for a niche B2B tool with 100+ licenses, it doesn't need to.

When This Approach Works – and When It Doesn't

WooCommerce as SaaS backend makes sense when:

  • Your tool already runs on WordPress (or can run as a plugin)
  • You have hundreds, not thousands of users
  • Annual or monthly subscriptions with simple tiers
  • The operator wants self-service management
  • Budget is limited and time-to-market matters

Use a proper SaaS stack when:

  • You need real-time features or websockets
  • Thousands of concurrent users are expected
  • You need fine-grained API rate limiting
  • Multi-tenancy with data isolation is required
  • The product will eventually need its own mobile app

The key question is: does your use case actually need the complexity of a custom stack? For a niche B2B tool with a few hundred users, the answer is often no. WooCommerce gives you payments, subscriptions, user management, and an admin panel out of the box. Adding license control on top is a few hundred lines of PHP.

Anonymous Analytics Bonus

One unexpected benefit: since all calculations run through the WordPress plugin, I was able to add anonymous aggregated analytics. The client can see average calculation values, pricing patterns, and employee planning trends across all salons – without seeing individual data.

This gives him benchmark data for product improvement and a potential value-add for users: "See how your prices compare to the average salon in your region."


I'm Joshua, freelance web developer from Hamburg. I build WordPress plugins, Shopify themes and custom web tools. More case studies on hafenpixel.de.

Top comments (0)