eleven / ocho Public
π€ Managed payments β the payout model for paid access levels
Design doc, 2026-07-22. Status: designed, not built (umbrella issue links the phases). Companion docs: docs/community-and-tiers.md (layer 3 β the tier machinery money assigns into), docs/tier-economics.md (the hosting price book; a different product, same Stripe account), docs/pricing-bands.md. Decisions here are Paul's (2026-07-22); the VAT/OSS findings are research summaries, not legal advice β a human review gates the go-live phase.
The design in one sentence
> Members pay the platform and the admin's share transfers structurally β > no Stripe account required, commission pay-what-you-want between 5.5% and > 11% all-in β while "bring your own Stripe" stays open to every space, with > a pay-what-you-want commission (suggested 5.5%) on top of the admin's own > fees.
Two providers, priced by who bears the risk
| | Managed (default) | BYO Stripe (open to every space) | |---|---|---| | Merchant of record | the platform | the space admin | | Stripe account | ours; admin gets an Express account (payouts + KYC only) | admin's own (OAuth-linked Standard, today's live path) | | 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 | | VAT on member subscriptions | ours (OSS from Ireland; Stripe Tax) | admin's | | Disputes/refunds | ours (payout holds; transfer reversals) | admin's | | Admin onboarding | minutes (Express account links: name, bank, KYC) | needs a real Stripe account |
Both commissions are the honor mechanism from pricing-bands.md applied to our own cut: a suggestion, a one-tap choice, no eligibility test. The two rails bound it differently because the costs differ:
- Managed clamps to [5.5, 11] because we bear real per-charge costs (processing, VAT handling, disputes). The 5.5 floor is roughly our cost line β on the β¬5.50 minimum ticket with an international card it dips a couple of points under, and that known loss is priced in rather than guarded against.
- BYO is unbounded down to zero because our marginal cost there is nil β the admin is the merchant, pays their own fees, runs their own books. Any commission they choose is honest margin; zero is a legitimate choice.
Why this split, in order of weight:
- Activation. BYO filters monetization to admins who already run a business. A Family or Community admin has no Stripe account and never will; Express onboarding is a bank account and a KYC form. Managed is the 95% case.
- "All-in, including payment fees" becomes structural. On a destination charge we own the charge and pay Stripe's processing fee from our own take; the admin's share is set by
transfer_datafrom their chosen commission, not reconciled after the fact. The refund-reconciliation and fee-prediction designs this supersedes are recorded below (Β§ Superseded) so they aren't reinvented. - The cuts price the risk transfer β and both are the admin's call. Managed bears processing + VAT + disputes, so its pay-what-you-want range floors at 5.5 (β our cost line); BYO bears all three itself, keeps its own books and negotiated rates, so its commission is open all the way to zero, suggested 5.5 (market-honest: Memberful charges 4.9% flat for the same shape; Substack takes 10 plus processing).
Money mechanics (managed)
- Checkout Sessions on the platform account (no
Stripe-Accountheader),mode=subscription,subscription_data[transfer_data][destination]= the space's Express account,[amount_percent]= 100 β the chosen commission (89β94.5). Stripe splits every invoice; processing fees land on the platform side by construction. - Level price floors: β¬5.50/month, β¬11/year (enforced at level pricing time, both providers). Stripe's fixed β¬0.25/charge makes all-in economics negative below ~β¬2.60/charge and thin below β¬5; the floors keep the worst-case (international card) take β₯ ~3 points. Same fee logic that made Business and Family annual-only (
tier-economics.md). - Payouts ride Stripe Express schedules; a rolling payout delay (Stripe's default) is the fraud/dispute buffer. Disputes: transfer reversal claws back the transferred share; the β¬15 dispute fee is ours β priced into the commission.
- VAT: the platform is seller of record for an electronically supplied service. Consumer stickers are VAT-inclusive (the pricing-bands posture), so our net per subscription varies by buyer country; OSS (one Irish registration) covers the EU, Stripe Tax computes per-invoice. Non-EU registrations (UK first) ratchet on thresholds. A human tax review gates the live flip β same bar as pricing-bands Phase 1.
Trust model (the two honest costs)
- Privacy centralization. Today each admin's Stripe sees only their own members' payment identity; managed payments concentrates every paying member of every space into one Stripe dashboard. Our own stores still hold only opaque ids (the billing.go rule), but the dashboard exposure is real and grows with the fleet. Named here deliberately; BYO remains the decentralized escape hatch, and that is part of why it stays.
- Merchant of record for content we cannot see. E2EE means we underwrite payments for communities whose content is structurally opaque to us. Mitigations: the existing report-to-admins/moderation surface, payout holds, and the standing right to off-board a space from payments (payouts stop; the space itself, being E2EE, was never ours to read). This asymmetry β we can stop paying out, we cannot inspect β is the design, not a gap in it.
Implementation shape
subscriptions.goalready has the seam:PayProvideris an interface and "adding a provider never touches the state machine."stripePlatform(managed) lands besidestripeConnect(BYO). NormalizedSubEvents feed the sameapplySubEvent.- Provider selection per space: managed is the default wherever platform creds exist;
stripe_connect_account(BYO) stays available to every space β no tier gate. A space that links its own Stripe chooses the BYO rail by that act. - Commission choices live in the space config:
managed_commission_pct(clamped [5.5, 11], default 11) and, phase 3, the BYO percent (suggested 5.5, floor 0). Changing a choice applies to new checkouts; existing subscriptions keep the split they were created with. - Express account id lives in the space config (
stripe_express_account), set by the onboarding flow (Account Links API;account.updatedwebhooks flip the payouts-ready bit). Until payouts-ready, levels can be drafted but not sold β never sell against an account that can't be paid. - Level prices: managed levels create their Stripe Price on the platform account (BYO keeps creating them on the admin's). The floors apply in the level-pricing path, before any Stripe call.
- Existing BYO spaces (paulca) are grandfathered: linked accounts keep working; the 10% β pay-what-you-want change (suggested 5.5) applies from its deploy β a cut reduction at the suggestion, so no notice period.
Lifetime access (single payment)
A level can price as interval: "once" β pay once, in for as long as the space exists (PR #1290; both rails). The copy says "as long as the space exists" deliberately: an admin can close a space, and we don't sell promises admins can't keep. Mechanics: mode=payment checkouts with the commission as a fixed amount (payment mode has no percent splits) β BYO takes its flat fee, managed applies the chosen PWYW commission to the transfer. The grant has no lifecycle β exempt from every renewal-shaped sweep β and the only exits are a refund/chargeback (charge.refunded / charge.dispute.created revoke immediately, with a payment-intent tombstone so redelivered grants can't re-buy a refunded level) or an admin removal. Floor: 11.00 one-time β the elevens' third coin (β¬5.50/month, β¬11/year, β¬11 once).
Rollout phases (mirrored in the umbrella issue)
- Provider core (dark):
stripePlatform+ destination-charge checkout + webhook parse + tests; config-gated off. - Express onboarding: account links flow, payouts-ready gating, admin UI (web + native surfaces per parity rule).
- Floors + BYO repricing: β¬5.50/β¬11 level-price floors both providers; BYO's application fee becomes the pay-what-you-want config (suggested 5.5, floor 0) with its admin picker; changelog.
- Tax + go-live: Stripe Tax on, OSS registration confirmed, human tax review, live platform creds, docs/status updates.
Superseded designs (recorded so they stay dead)
- Fee-refund reconciliation (charge 11%, refund the actual
balance_transaction.feeafterinvoice.paid): correct but only needed when the admin is MoR and we promise all-in β i.e. never, under this split. BYO makes no all-in promise; managed doesn't need reconciliation. - Fee prediction from the payment intent: impossible before the first charge (no card yet), asymmetric on renewals (application fees refund down, never up). Reconciliation was prediction with the error bar collapsed; destination charges remove the need for either.