All articles
By Carlos García Updated 4 min read

How to design per-property SaaS pricing, permissions, and usage limits

How to design per-property SaaS pricing, permissions, and usage limits

In 60 seconds: Separate billing, feature access, usage, and tenant authorization before building checkout. Stripe can tell you which subscription and entitlements are active. Your application still decides whether this user can access this property and whether the account has room for another one. Define upgrades, downgrades, failed payments, refunds, webhook delays, deleted properties, and support overrides. Test those states before charging the first customer.

A SaaS priced per property looks simple on a landing page: Analytics for one property, Operations as an add-on, and a combined plan with more competitor comparisons. The complexity appears when product rules meet accounts, roles, usage, and payment events.

If every feature checks a plan name directly, pricing changes spread through the code. If every request calls Stripe, availability and latency depend on an external API. If the tenant boundary is implicit, a billing feature can become a data-leak bug.

Separate four decisions

Billing answers what the customer purchased and whether the commercial relationship is active. Entitlements answer which features are enabled. Usage answers how many properties, competitors, reports, or automated checkouts have been consumed. Authorization answers whether the current person can perform this action on this tenant and property.

These decisions interact but should not collapse into one boolean such as isPremium.

Stripe Entitlements maps product features to active entitlements and can notify the application through entitlements.active_entitlement_summary.updated. Stripe’s usage-based pricing guide covers metered models. Neither service understands your full tenant and property permissions.

Model the product before checkout

Create a table with plan, billable unit, feature, limit, reset period, and downgrade behavior.

Plan ruleExample decision
Billable unitPer active property per month
Feature entitlementAnalytics enabled
QuotaTwo competitor comparisons per property
RoleOwner can manage billing, cleaner cannot
OverageBlock, charge, or request upgrade
DowngradePreserve data but disable new premium reports

Avoid hiding policy inside product IDs. Use stable feature keys such as analytics, operations, or competitor_slots. Map Stripe products and prices to those keys through configuration.

Decide whether archived properties count, whether transferring a property changes billing, and whether one subscription can cover multiple organizations. These questions are cheaper to answer in a document than after customers have paid.

Use local state for runtime decisions

Process subscription and entitlement webhooks idempotently. Store the provider event ID so a retry does not apply the same change twice. Update local subscription and entitlement records, then let requests read validated local state.

A typical authorization check combines:

  1. authenticated user
  2. tenant membership
  3. property ownership or assignment
  4. role permission
  5. active feature entitlement
  6. current quota and usage

The account could have Analytics enabled while a cleaner still lacks access to financial reports. A valid payment does not grant every user access to every property.

AWS’s multi-tenant authorization guidance discusses role and attribute-based controls with tenant context. The practical rule is simple: carry tenant and property identity through endpoints, background jobs, exports, search, and caches.

Enforce property limits without races

Suppose a plan allows five properties and two requests create the fifth at the same time. Reading the count and then writing can admit both. Use a transaction, lock, or atomic counter so the check and reservation happen together.

Show the user what happened. A limit response should identify the plan, current usage, allowed amount, and approved next step without exposing other tenants’ data. Do not delete or hide existing properties when a downgrade reduces the limit. Define a restricted state and let the customer choose which property remains active.

Usage is not always billing. A competitor slot may be a hard feature limit while an API operation is metered. Write down whether each number resets, accumulates, or follows the property.

Design payment transitions

Webhooks arrive eventually and can be retried or reordered. Decide how the product behaves during checkout completion, upgrade, downgrade, payment failure, cancellation, refund, trial expiry, and a temporary provider outage.

Support needs visible state. Show subscription status, last processed event, entitlements, usage, and any manual override with actor and expiry. A permanent undocumented override becomes a pricing bug.

Never use invoice.paid alone as authorization. An invoice event describes payment. The application still needs active product state and permission for the requested resource.

Test the boundary before launch

Test a user with two properties, a user in two organizations, a removed owner, duplicate webhooks, delayed events, concurrent property creation, downgrade below current usage, refund, and deleted property. Try changing a URL from one property ID to another. Verify background exports and notifications cannot cross tenants.

Also test the customer explanation. Pricing pages, checkout, account settings, and limit messages must describe the same rule. If “up to five properties” means five active properties, say so.

A product team should be able to change a price without rewriting authorization. It should be able to add an entitlement without creating a second billing system. Kiia can help model this boundary and its edge cases before payment integration makes the decisions expensive to reverse.

Frequently asked questions

Should Stripe decide whether a user can open a feature?

Stripe can report subscription and entitlement state, but the application should make authorization decisions from validated local state and tenant context.

Are entitlements and usage limits the same thing?

No. An entitlement answers whether a feature is active. A quota or meter tracks how much of a resource the customer has used.

What should happen when a customer reaches the property limit?

Block creation without damaging existing data, explain the limit, show current usage, and offer the approved upgrade path.

From insight to action

Want to turn this into an agent that works for your team?

Tell us which process you want to improve. In a free call, we will identify the first workflow worth building.

Book a free call