markdown · 8611 bytes Raw Blame History

Billing and paid organizations

shithub's first paid surface is organization billing. The code does not ship billing yet; this document records the product and engineering contract that the PAYMENTS sprint series implements.

The current implementation already has the important shape for paid organizations: orgs.plan is an enum with free, team, and enterprise; organizations own repositories; organization members and teams exist; branch protection and PR review gates exist; Actions has schema for org/repo secrets, variables, and artifacts. Billing must turn that substrate into a fair hosted service without taxing public/open-source collaboration.

Product contract

As of 2026-05-12, GitHub's public pricing page presents Free at $0, Team at $4/user/month, and Enterprise starting at $21/user/month. shithub follows the same mental model but removes Copilot/AI promises from the paid-org offering.

Initial decisions:

  • Free organizations remain self-serve.
  • Team is $4 per active organization member per month.
  • Active organization members, including owners, count as paid seats.
  • Team has no launch trial.
  • Enterprise is a visible contact-sales stub, not self-serve.
  • Stripe Billing is the first payment processor.
  • PayPal, manual invoices, SAML, SCIM, LDAP, enterprise account hierarchy, and contracts are deferred.

The fairness rule is explicit: public/open-source collaboration should stay generous. Paid gates focus on private collaboration, hosted cost, advanced organization controls, and support expectations.

Pricing copy rules

Pricing and onboarding pages must describe only features shithub can actually deliver on the hosted service. Before changing pricing copy, refresh the official GitHub pricing source and the Stripe Billing docs because both are time-sensitive inputs.

Rules for paid-org copy:

  • Do not mention Copilot, AI agents, AI code review, or AI quotas.
  • Do not promise SAML, SCIM, LDAP, managed users, audit exports, data residency, compliance attestations, contracts, or custom support until the matching implementation sprint ships.
  • Do not advertise Packages, Pages, Wikis, Projects, Actions minutes, or storage quotas until those surfaces have enforcement and usage accounting.
  • Use upgrade language for unavailable Team features instead of hiding existing data. Downgrades preserve configuration and make gated settings read-only where possible.
  • Keep public/open-source collaboration generous in both copy and enforcement. Avoid copy that makes public repositories feel like a second-class Free tier.
  • Enterprise is a contact-sales stub in v1. It should collect interest without promising contractual features.

Entitlement matrix

Capability Free Team Enterprise stub
Public org repositories Included Included Contact sales
Basic private org repositories Included Included Contact sales
Org members and invitations Included Billed by active member Contact sales
Visible teams Included Included Contact sales
Secret teams Upgrade Included Contact sales
Basic branch protection Included Included Contact sales
Advanced private-repo branch protection Upgrade Included Contact sales
Required reviewers on private org repos Upgrade Included Contact sales
CODEOWNERS review Deferred Deferred Deferred
Org-level Actions secrets Upgrade Included Contact sales
Org-level Actions variables Upgrade Included Contact sales
Actions minutes Low quota once metered Higher quota once metered Contact sales
Actions artifacts/storage Low quota once metered Higher quota once metered Contact sales
Packages storage Deferred until Packages is active Deferred until Packages is active Deferred
Pages/Wikis/Projects Do not promise until shipped Do not promise until shipped Deferred
Audit log export Deferred Deferred Later Enterprise feature
SAML/SCIM/managed users Deferred Deferred Later Enterprise feature
Data residency/compliance Deferred Deferred Later Enterprise feature
Billing support Basic instance support Billing support after runbook exists Contact sales

Current capability audit

Already present and safe to gate:

  • Organizations with plan and billing_email.
  • Organization members, owner role, and invitations.
  • Teams, including privacy='secret'.
  • Branch protection rules and required review counts.
  • PR review and reviewer-request substrate.
  • Org/repo Actions secrets and variables schema.

Present but missing enforcement or metering:

  • Storage quota type exists, but quota persistence and enforcement are incomplete.
  • Actions minutes, artifacts, and object usage need accounting before paid limits can be promised.
  • Packages storage cannot be sold until the Packages sprint is active and quota enforcement exists.

Deferred:

  • SAML, SCIM, LDAP, enterprise account hierarchy, audit-log export, data residency, compliance promises, and custom support SLAs.
  • Copilot/AI features are intentionally outside shithub's paid-org product.

Billing architecture

Stripe is the payment source of truth. shithub is the entitlement source of truth.

The billing implementation should add a local billing domain that stores only Stripe IDs and payment summaries, never card data. Webhooks update local subscription state after signature verification. Policy and request handlers read local billing/entitlement state and must not call Stripe in hot paths.

Required local concepts:

  • Stripe customer per billable organization.
  • Subscription state per organization.
  • Subscription item ID for seat quantity sync.
  • Immutable webhook receipts with unique provider event IDs.
  • Invoice/payment summaries for UI.
  • Seat snapshots for auditability.
  • Billing grace/lock state derived from processed subscription events.

PAYMENTS SP02 adds these as local database tables:

  • org_billing_states stores the organization billing projection used by entitlement checks.
  • billing_seat_snapshots records active and billable seat counts over time.
  • billing_invoices stores invoice/payment summaries for billing UI.
  • billing_webhook_events stores immutable provider event receipts for idempotent webhook processing.

New organizations receive a Free billing state from a database trigger, and the migration backfills existing organizations as Free. Subscription snapshot writes also keep orgs.plan synchronized as the human-facing summary.

Entitlement architecture

Paid feature checks must live behind a central entitlement package, not as scattered orgs.plan checks in handlers.

make lint-org-plan enforces this boundary. Schema/sqlc plumbing may store and scan the plan value, but product behavior should ask the entitlement package whether a feature key is available.

Expected feature keys:

  • org.secret_teams
  • org.advanced_branch_protection
  • org.required_reviewers
  • org.actions_org_secrets
  • org.actions_org_variables
  • org.private_collaboration_limit
  • org.storage_quota
  • org.actions_minutes_quota

Authorization and entitlement are separate gates. A user must have both the policy permission and the paid entitlement for gated writes. Denials must preserve existing policy.Maybe404 behavior where existence leaks matter.

Downgrade behavior

Downgrades must preserve customer data. Moving from Team to Free should not delete teams, secrets, variables, branch rules, or review settings. Existing gated resources become read-only where possible. Users can remove gated configuration, but cannot create or expand it until the organization upgrades again.

Open questions for implementation

  • Whether Free should limit private org collaborators before usage metering exists, or whether the first paid gates are advanced controls only.
  • Whether required reviewers are gated only for private org repos. The current lean is private-org-only.
  • Whether org-level Actions secrets and variables should be Team-only even for public repositories. The current lean is yes for org scope.
  • Exact Free and Team quota numbers for Actions and storage. These must come from real host-cost estimates before SP08.

Source references

  • GitHub pricing: https://github.com/pricing
  • GitHub plans docs: https://docs.github.com/en/get-started/learning-about-github/githubs-plans
  • Stripe Billing: https://docs.stripe.com/billing
  • Stripe pricing models: https://docs.stripe.com/products-prices/pricing-models
View source
1 # Billing and paid organizations
2
3 shithub's first paid surface is organization billing. The code does not
4 ship billing yet; this document records the product and engineering
5 contract that the PAYMENTS sprint series implements.
6
7 The current implementation already has the important shape for paid
8 organizations: `orgs.plan` is an enum with `free`, `team`, and
9 `enterprise`; organizations own repositories; organization members and
10 teams exist; branch protection and PR review gates exist; Actions has
11 schema for org/repo secrets, variables, and artifacts. Billing must
12 turn that substrate into a fair hosted service without taxing
13 public/open-source collaboration.
14
15 ## Product contract
16
17 As of 2026-05-12, GitHub's public pricing page presents Free at
18 `$0`, Team at `$4/user/month`, and Enterprise starting at
19 `$21/user/month`. shithub follows the same mental model but removes
20 Copilot/AI promises from the paid-org offering.
21
22 Initial decisions:
23
24 - Free organizations remain self-serve.
25 - Team is `$4` per active organization member per month.
26 - Active organization members, including owners, count as paid seats.
27 - Team has no launch trial.
28 - Enterprise is a visible contact-sales stub, not self-serve.
29 - Stripe Billing is the first payment processor.
30 - PayPal, manual invoices, SAML, SCIM, LDAP, enterprise account
31 hierarchy, and contracts are deferred.
32
33 The fairness rule is explicit: public/open-source collaboration should
34 stay generous. Paid gates focus on private collaboration, hosted cost,
35 advanced organization controls, and support expectations.
36
37 ## Pricing copy rules
38
39 Pricing and onboarding pages must describe only features shithub can
40 actually deliver on the hosted service. Before changing pricing copy,
41 refresh the official GitHub pricing source and the Stripe Billing docs
42 because both are time-sensitive inputs.
43
44 Rules for paid-org copy:
45
46 - Do not mention Copilot, AI agents, AI code review, or AI quotas.
47 - Do not promise SAML, SCIM, LDAP, managed users, audit exports, data
48 residency, compliance attestations, contracts, or custom support
49 until the matching implementation sprint ships.
50 - Do not advertise Packages, Pages, Wikis, Projects, Actions minutes,
51 or storage quotas until those surfaces have enforcement and usage
52 accounting.
53 - Use upgrade language for unavailable Team features instead of hiding
54 existing data. Downgrades preserve configuration and make gated
55 settings read-only where possible.
56 - Keep public/open-source collaboration generous in both copy and
57 enforcement. Avoid copy that makes public repositories feel like a
58 second-class Free tier.
59 - Enterprise is a contact-sales stub in v1. It should collect interest
60 without promising contractual features.
61
62 ## Entitlement matrix
63
64 | Capability | Free | Team | Enterprise stub |
65 | --- | --- | --- | --- |
66 | Public org repositories | Included | Included | Contact sales |
67 | Basic private org repositories | Included | Included | Contact sales |
68 | Org members and invitations | Included | Billed by active member | Contact sales |
69 | Visible teams | Included | Included | Contact sales |
70 | Secret teams | Upgrade | Included | Contact sales |
71 | Basic branch protection | Included | Included | Contact sales |
72 | Advanced private-repo branch protection | Upgrade | Included | Contact sales |
73 | Required reviewers on private org repos | Upgrade | Included | Contact sales |
74 | CODEOWNERS review | Deferred | Deferred | Deferred |
75 | Org-level Actions secrets | Upgrade | Included | Contact sales |
76 | Org-level Actions variables | Upgrade | Included | Contact sales |
77 | Actions minutes | Low quota once metered | Higher quota once metered | Contact sales |
78 | Actions artifacts/storage | Low quota once metered | Higher quota once metered | Contact sales |
79 | Packages storage | Deferred until Packages is active | Deferred until Packages is active | Deferred |
80 | Pages/Wikis/Projects | Do not promise until shipped | Do not promise until shipped | Deferred |
81 | Audit log export | Deferred | Deferred | Later Enterprise feature |
82 | SAML/SCIM/managed users | Deferred | Deferred | Later Enterprise feature |
83 | Data residency/compliance | Deferred | Deferred | Later Enterprise feature |
84 | Billing support | Basic instance support | Billing support after runbook exists | Contact sales |
85
86 ## Current capability audit
87
88 Already present and safe to gate:
89
90 - Organizations with `plan` and `billing_email`.
91 - Organization members, owner role, and invitations.
92 - Teams, including `privacy='secret'`.
93 - Branch protection rules and required review counts.
94 - PR review and reviewer-request substrate.
95 - Org/repo Actions secrets and variables schema.
96
97 Present but missing enforcement or metering:
98
99 - Storage quota type exists, but quota persistence and enforcement are
100 incomplete.
101 - Actions minutes, artifacts, and object usage need accounting before
102 paid limits can be promised.
103 - Packages storage cannot be sold until the Packages sprint is active
104 and quota enforcement exists.
105
106 Deferred:
107
108 - SAML, SCIM, LDAP, enterprise account hierarchy, audit-log export, data
109 residency, compliance promises, and custom support SLAs.
110 - Copilot/AI features are intentionally outside shithub's paid-org
111 product.
112
113 ## Billing architecture
114
115 Stripe is the payment source of truth. shithub is the entitlement source
116 of truth.
117
118 The billing implementation should add a local billing domain that stores
119 only Stripe IDs and payment summaries, never card data. Webhooks update
120 local subscription state after signature verification. Policy and
121 request handlers read local billing/entitlement state and must not call
122 Stripe in hot paths.
123
124 Required local concepts:
125
126 - Stripe customer per billable organization.
127 - Subscription state per organization.
128 - Subscription item ID for seat quantity sync.
129 - Immutable webhook receipts with unique provider event IDs.
130 - Invoice/payment summaries for UI.
131 - Seat snapshots for auditability.
132 - Billing grace/lock state derived from processed subscription events.
133
134 PAYMENTS SP02 adds these as local database tables:
135
136 - `org_billing_states` stores the organization billing projection used
137 by entitlement checks.
138 - `billing_seat_snapshots` records active and billable seat counts over
139 time.
140 - `billing_invoices` stores invoice/payment summaries for billing UI.
141 - `billing_webhook_events` stores immutable provider event receipts for
142 idempotent webhook processing.
143
144 New organizations receive a Free billing state from a database trigger,
145 and the migration backfills existing organizations as Free. Subscription
146 snapshot writes also keep `orgs.plan` synchronized as the
147 human-facing summary.
148
149 ## Entitlement architecture
150
151 Paid feature checks must live behind a central entitlement package, not
152 as scattered `orgs.plan` checks in handlers.
153
154 `make lint-org-plan` enforces this boundary. Schema/sqlc plumbing may
155 store and scan the plan value, but product behavior should ask the
156 entitlement package whether a feature key is available.
157
158 Expected feature keys:
159
160 - `org.secret_teams`
161 - `org.advanced_branch_protection`
162 - `org.required_reviewers`
163 - `org.actions_org_secrets`
164 - `org.actions_org_variables`
165 - `org.private_collaboration_limit`
166 - `org.storage_quota`
167 - `org.actions_minutes_quota`
168
169 Authorization and entitlement are separate gates. A user must have both
170 the policy permission and the paid entitlement for gated writes. Denials
171 must preserve existing `policy.Maybe404` behavior where existence leaks
172 matter.
173
174 ## Downgrade behavior
175
176 Downgrades must preserve customer data. Moving from Team to Free should
177 not delete teams, secrets, variables, branch rules, or review settings.
178 Existing gated resources become read-only where possible. Users can
179 remove gated configuration, but cannot create or expand it until the
180 organization upgrades again.
181
182 ## Open questions for implementation
183
184 - Whether Free should limit private org collaborators before usage
185 metering exists, or whether the first paid gates are advanced controls
186 only.
187 - Whether required reviewers are gated only for private org repos. The
188 current lean is private-org-only.
189 - Whether org-level Actions secrets and variables should be Team-only
190 even for public repositories. The current lean is yes for org scope.
191 - Exact Free and Team quota numbers for Actions and storage. These must
192 come from real host-cost estimates before SP08.
193
194 ## Source references
195
196 - GitHub pricing: `https://github.com/pricing`
197 - GitHub plans docs:
198 `https://docs.github.com/en/get-started/learning-about-github/githubs-plans`
199 - Stripe Billing: `https://docs.stripe.com/billing`
200 - Stripe pricing models:
201 `https://docs.stripe.com/products-prices/pricing-models`