feat(billing): give Business a 3-seat floor and its own annual variant - #21
Merged
Merged
Conversation
Business had no seat minimum, so one seat at $30 undercut the cheapest Teams plan at three seats for $54 while including everything Teams has. Both per-seat plans now share a 3-seat floor, which keeps the ladder monotonic: Teams starts at $54/month, Business at $90. The owner occupies a seat, so three seats means the owner plus two. Business also resolved a single monthly variant for both intervals. It now has LS_VARIANT_BUSINESS_YEARLY of its own, priced at $25/user/month against $30 monthly — the same 17% annual discount Teams carries. Pro and Teams already discounted annually and Business did not, which was the odd one out. Neither variant exists in LemonSqueezy yet, so the plan stays unsellable until both environment variables are set.
compose.prod.yml enumerates every environment variable explicitly, so adding LS_VARIANT_BUSINESS_MONTHLY and _YEARLY to .env.dockhand alone would not reach the server: variant_id_for would read an unset variable, return None, and the checkout handler would answer 503 for a plan the site was advertising.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pricing decisions for Business, implemented.
3-seat floor on every per-seat plan
Business had no seat minimum, so one seat at $30/month undercut the cheapest Teams plan — three seats at $54 — while including everything Teams has plus custom roles and the commercial licence.
PER_SEAT_PLANSnow covers both plans and they shareMIN_SEATS = 3:Monotonic: every Business plan costs more than every Teams plan. The owner occupies a seat (
owner_seats_usedcountsteam_members, which includes them), so three seats means owner plus two.Pro stays single-seat and sends no quantity at all.
Business gets its own annual variant
It previously resolved
LS_VARIANT_BUSINESS_MONTHLYfor both intervals. It now hasLS_VARIANT_BUSINESS_YEARLY, at $25/user/month against $30 monthly — the same 17% Teams carries. Pro discounts 22% annually and Teams 17%, so a flat Business price was the outlier.Testing
business_resolves_both_intervals_once_configuredreplaces the earlier monthly-only assertion, andevery_per_seat_plan_shares_the_three_seat_floorpins the rule that stops Business undercutting Teams.Deployment
Neither variant exists in LemonSqueezy yet, so Business stays unsellable regardless of this PR —
variant_id_forreturnsNoneand the handler answers 503. Going live needs both variables set and a redeploy.Decided alongside this, needing no code: no free trial on the Business variants. Its headline value is the commercial licence, and a free trial of a licence grants AGPL relief for nothing; the functionality is already demonstrable through a Teams trial, and pilots for this tier are better comped per-deal via
admin_override. Relevant too:require_business_tierreadsusers.subscription_tierdirectly rather than going througheffective_tier_for_user, so an expired Business trial would retain custom-role access until the next daily sweep — up to 24 hours. Worth fixing on its own, but it only becomes reachable if Business trials exist.