eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1# πŸ€– Managed payments β€” the payout model for paid access levels
2
3Design doc, 2026-07-22. Status: **designed, not built** (umbrella issue links
4the phases). Companion docs: `docs/community-and-tiers.md` (layer 3 β€” the tier
5machinery money assigns into), `docs/tier-economics.md` (the hosting price
6book; a different product, same Stripe account), `docs/pricing-bands.md`.
7Decisions here are Paul's (2026-07-22); the VAT/OSS findings are research
8summaries, not legal advice β€” a human review gates the go-live phase.
9
10## The design in one sentence
11
12> **Members pay the platform and the admin's share transfers structurally β€”
13> no Stripe account required, commission pay-what-you-want between 5.5% and
14> 11% all-in β€” while "bring your own Stripe" stays open to every space, with
15> a pay-what-you-want commission (suggested 5.5%) on top of the admin's own
16> fees.**
17
18## Two providers, priced by who bears the risk
19
20| | Managed (default) | BYO Stripe (open to every space) |
21|---|---|---|
22| Merchant of record | the platform | the space admin |
23| Stripe account | ours; admin gets an **Express** account (payouts + KYC only) | admin's own (OAuth-linked Standard, today's live path) |
24| Commission | **pay-what-you-want, 5.5–11%, suggested 11 β€” all-in** (card processing fees come out of our points, whatever the choice) | **pay-what-you-want, suggested 5.5%** + the admin's own Stripe fees |
25| VAT on member subscriptions | ours (OSS from Ireland; Stripe Tax) | admin's |
26| Disputes/refunds | ours (payout holds; transfer reversals) | admin's |
27| Admin onboarding | minutes (Express account links: name, bank, KYC) | needs a real Stripe account |
28
29Both commissions are the honor mechanism from `pricing-bands.md` applied to
30our own cut: a suggestion, a one-tap choice, no eligibility test. The two
31rails bound it differently because the costs differ:
32
33- **Managed clamps to [5.5, 11]** because we bear real per-charge costs
34 (processing, VAT handling, disputes). The 5.5 floor is roughly our cost
35 line β€” on the €5.50 minimum ticket with an international card it dips a
36 couple of points under, and that known loss is priced in rather than
37 guarded against.
38- **BYO is unbounded down to zero** because our marginal cost there is nil β€”
39 the admin is the merchant, pays their own fees, runs their own books. Any
40 commission they choose is honest margin; zero is a legitimate choice.
41
42Why this split, in order of weight:
43
441. **Activation.** BYO filters monetization to admins who already run a
45 business. A Family or Community admin has no Stripe account and never
46 will; Express onboarding is a bank account and a KYC form. Managed is the
47 95% case.
482. **"All-in, including payment fees" becomes structural.** On a
49 destination charge we own the charge and pay Stripe's processing fee from
50 our own take; the admin's share is set by `transfer_data` from their
51 chosen commission, not reconciled after the fact. The
52 refund-reconciliation and fee-prediction designs this supersedes are
53 recorded below (Β§ Superseded) so they aren't reinvented.
543. **The cuts price the risk transfer β€” and both are the admin's call.**
55 Managed bears processing + VAT + disputes, so its pay-what-you-want range
56 floors at 5.5 (β‰ˆ our cost line); BYO bears all three itself, keeps its
57 own books and negotiated rates, so its commission is open all the way to
58 zero, suggested 5.5 (market-honest: Memberful charges 4.9% flat for the
59 same shape; Substack takes 10 *plus* processing).
60
61## Money mechanics (managed)
62
63- Checkout Sessions on the **platform account** (no `Stripe-Account` header),
64 `mode=subscription`, `subscription_data[transfer_data][destination]` = the
65 space's Express account, `[amount_percent]` = 100 βˆ’ the chosen commission
66 (89–94.5). Stripe splits every invoice; processing fees land on the
67 platform side by construction.
68- **Level price floors: €5.50/month, €11/year** (enforced at level pricing
69 time, both providers). Stripe's fixed €0.25/charge makes all-in economics
70 negative below ~€2.60/charge and thin below €5; the floors keep the
71 worst-case (international card) take β‰₯ ~3 points. Same fee logic that made
72 Business and Family annual-only (`tier-economics.md`).
73- Payouts ride Stripe Express schedules; a rolling payout delay (Stripe's
74 default) is the fraud/dispute buffer. Disputes: transfer reversal claws
75 back the transferred share; the €15 dispute fee is ours β€” priced into the
76 commission.
77- VAT: the platform is seller of record for an electronically supplied
78 service. Consumer stickers are VAT-inclusive (the pricing-bands posture),
79 so our net per subscription varies by buyer country; OSS (one Irish
80 registration) covers the EU, Stripe Tax computes per-invoice. Non-EU
81 registrations (UK first) ratchet on thresholds. **A human tax review gates
82 the live flip** β€” same bar as pricing-bands Phase 1.
83
84## Trust model (the two honest costs)
85
86- **Privacy centralization.** Today each admin's Stripe sees only their own
87 members' payment identity; managed payments concentrates every paying
88 member of every space into one Stripe dashboard. Our own stores still hold
89 only opaque ids (the billing.go rule), but the dashboard exposure is real
90 and grows with the fleet. Named here deliberately; BYO remains the
91 decentralized escape hatch, and that is part of why it stays.
92- **Merchant of record for content we cannot see.** E2EE means we underwrite
93 payments for communities whose content is structurally opaque to us.
94 Mitigations: the existing report-to-admins/moderation surface, payout
95 holds, and the standing right to off-board a space from *payments*
96 (payouts stop; the space itself, being E2EE, was never ours to read).
97 This asymmetry β€” we can stop paying out, we cannot inspect β€” is the
98 design, not a gap in it.
99
100## Implementation shape
101
102- `subscriptions.go` already has the seam: `PayProvider` is an interface and
103 "adding a provider never touches the state machine." `stripePlatform`
104 (managed) lands beside `stripeConnect` (BYO). Normalized `SubEvent`s feed
105 the same `applySubEvent`.
106- Provider selection per space: managed is the default wherever platform
107 creds exist; `stripe_connect_account` (BYO) stays available to every
108 space β€” no tier gate. A space that links its own Stripe chooses the BYO
109 rail by that act.
110- Commission choices live in the space config: `managed_commission_pct`
111 (clamped [5.5, 11], default 11) and, phase 3, the BYO percent (suggested
112 5.5, floor 0). Changing a choice applies to new checkouts; existing
113 subscriptions keep the split they were created with.
114- Express account id lives in the space config (`stripe_express_account`),
115 set by the onboarding flow (Account Links API; `account.updated` webhooks
116 flip the payouts-ready bit). Until payouts-ready, levels can be drafted
117 but not sold β€” never sell against an account that can't be paid.
118- Level prices: managed levels create their Stripe Price on the platform
119 account (BYO keeps creating them on the admin's). The floors apply in the
120 level-pricing path, before any Stripe call.
121- Existing BYO spaces (paulca) are grandfathered: linked accounts keep
122 working; the 10% β†’ pay-what-you-want change (suggested 5.5) applies from
123 its deploy β€” a cut *reduction* at the suggestion, so no notice period.
124
125## Lifetime access (single payment)
126
127A level can price as **`interval: "once"`** β€” pay once, in for as long as the
128space exists (PR #1290; both rails). The copy says "as long as the space
129exists" deliberately: an admin can close a space, and we don't sell promises
130admins can't keep. Mechanics: `mode=payment` checkouts with the commission as
131a fixed amount (payment mode has no percent splits) β€” BYO takes its flat fee,
132managed applies the chosen PWYW commission to the transfer. The grant has no
133lifecycle β€” exempt from every renewal-shaped sweep β€” and the only exits are a
134refund/chargeback (`charge.refunded` / `charge.dispute.created` revoke
135immediately, with a payment-intent tombstone so redelivered grants can't
136re-buy a refunded level) or an admin removal. **Floor: 11.00 one-time** β€”
137the elevens' third coin (€5.50/month, €11/year, €11 once).
138
139## Rollout phases (mirrored in the umbrella issue)
140
1411. **Provider core (dark):** `stripePlatform` + destination-charge checkout
142 + webhook parse + tests; config-gated off.
1432. **Express onboarding:** account links flow, payouts-ready gating, admin
144 UI (web + native surfaces per parity rule).
1453. **Floors + BYO repricing:** €5.50/€11 level-price floors both
146 providers; BYO's application fee becomes the pay-what-you-want config
147 (suggested 5.5, floor 0) with its admin picker; changelog.
1484. **Tax + go-live:** Stripe Tax on, OSS registration confirmed, human tax
149 review, live platform creds, docs/status updates.
150
151## Superseded designs (recorded so they stay dead)
152
153- **Fee-refund reconciliation** (charge 11%, refund the actual
154 `balance_transaction.fee` after `invoice.paid`): correct but only needed
155 when the admin is MoR and we promise all-in β€” i.e. never, under this
156 split. BYO makes no all-in promise; managed doesn't need reconciliation.
157- **Fee prediction from the payment intent**: impossible before the first
158 charge (no card yet), asymmetric on renewals (application fees refund
159 down, never up). Reconciliation was prediction with the error bar
160 collapsed; destination charges remove the need for either.
161