PROTOTYPEClickable mockup · simulates the finished app◃ Product overview
Operator Console
ProductionOP
Billing & subscriptions
The platform's own revenue engine: the versioned 14-SKU pricing catalog, tenant subscriptions with the price-lock guarantee, involuntary dunning enforcement, the Bankgirot import queue, pro-services billing and FX policy. Tenant-side billing lives in each tenant's admin.
Versions are immutable — price changes publish a new version. Existing subscriptions keep their locked version.
billing_type
Mode
tenant_type
Price (EUR/yr)
License range
Subsystems
Status
club_basic
self-service
CLUB
490
—
6 / 14
current
club_plus
self-service
CLUB
990
—
9 / 14
current
venue
self-service
VENUE
1 990
—
8 / 14
current
brasserie
self-service
BRASSERIE
1 490
—
7 / 14
current
national_xs
contract
FEDERATION
4 900
0–999
14 / 14
current
national_s
contract
FEDERATION
9 800
1 000–2 999
14 / 14
current
national_m
contract
FEDERATION
19 500
3 000–9 999
14 / 14
current
national_l
contract
FEDERATION
39 000
≥ 10 000
14 / 14
current
confederation
contract
CONFEDERATION
custom
—
14 / 14
current
Showing 9 of 14 tiers (i18n display names in en/fr/es/sv on the detail view, incl. Stripe price IDs). National tier auto-classification: 0–999 → XS · 1 000–2 999 → S · 3 000–9 999 → M · ≥ 10 000 → L. Public read-only endpoints serve the 7 self-service tiers and per-tenant-type deep links with included/excluded subsystems (5 min cache). A nightly sync-check compares this table with the marketing site's tier data and raises a SEV2 platform event on divergence.
Publish new version
New catalog version
Version history
Version
Published
Tiers
Note
v2026.01
2026-01-02
14
Initial public catalog (market-analysis A2)
v2025.06
2025-06-15
14
Pilot pricing — superseded
View states
Loading
Loading catalog…
Empty
🏷️
No catalog seeded.
Run the idempotent seed script to create v2026.01.
Error
Could not load pricing catalog.
Network error — icon + text + colour, never colour alone.
Report — locked ARR by pricing_version (price-lock guarantee)
pricing_version
Active subscriptions
Locked ARR
Tenant-type mix
v2026.01
61
€214 300
48 club · 6 venue · 4 federation · 3 other
v2025.06
31
€98 100
27 club · 2 venue · 2 federation
Price-lock: the price of the locked pricing_version applies for as long as the subscription stays active — renewals never re-price. Published policy pages: /price-lock-guarantee and /currency-policy (4 languages). Report cached 5 min.
Subscriptions
Tenant
Tier
pricing_version
Status
Auto-renew
Next renewal
Svenska Bouleförbundet
national_s
v2025.06
active
yes
2027-06-01
·
Nordvik BK
club_plus
v2026.01
active
yes
2027-01-08
·
Boulodrome Sjöstad
venue
v2026.01
active
yes
2027-02-14
·
Ystad Boule
club_basic
v2026.01
past_due
yes
retry 2/3 · then dunning
·
Brasseri Cochonnet
brasserie
v2026.01
cancelled (period end)
no
—
·
Lifecycle: upgrade within locked version (downgrades 422), cancel (immediate requires sys_finance + fresh auth), idempotent renew, soft-delete blocked while invoices are unpaid — all audited. The hourly auto-renewal job creates invoices with the unchanged pricing_version; retry 1h/2h/4h then dunning; a >25 h silent job raises SEV2 subscription_renewal_drift.
Stripe webhook customer.subscription.updated syncs tenant_type on drift and writes tenant.tier.synced_from_stripe; the hourly drift-check job flags mismatches as billing_health=warning + SEV2. Tenant admins see their own tier, included subsystems and an upgrade-quote ROI calculator in their admin app — actual changes happen here.
banner_only→final_warning→read_only→pre_deletion→deletedbanner → 6 months read-only → +12 months data deletion
Tenant
Stage
Opened
Trigger
Next transition
Ystad Boule
final_warning
2026-06-02
invoice.payment_failed ×3
read_only 2026-07-12
PC Levante (ES)
banner_only
2026-06-25
contract invoice 30d overdue
final_warning 2026-07-09
BC Alpenrand (DE)
read_only
2026-02-11
invoice.payment_failed
pre_deletion 2026-08-11
Stripe invoice.payment_failed opens a case; invoice.paid closes it while ≤ final_warning. Contract invoices 30 days overdue open cases too. Every stage transition emails all tenant admins. No auto-reactivation after read_only — a manual waive is required. Voluntary cancellation during a case closes it cleanly.
Tenant-visible banner (preview — shown to ALL tenant users)
⚠ Payment is missing for your Petanque Life subscription. The account will be placed in read-only mode on 2026-07-12 if the invoice is not paid. Contact your federation administrator.
Manual waive (governance-audited)
Waive dunning case — Ystad Boule
State — no active cases
✓
No tenants in dunning.
Cases open automatically from failed payments and overdue contract invoices.
Unmatched transfers (cross-tenant queue)
Received
Amount
Reason
Counterpart / reference
Status
2026-07-01
4 500,00 SEK
no_matching_invoice
NORDEA · "medlemsavg 26"
open
·
2026-06-30
450,00 SEK
invalid_ocr_checksum
OCR 3100064009
open
·
2026-06-28
+300,00 SEK over
amount_overpaid
LF-2026-0611 · Vretby PK
open
·
2026-06-27
900,00 SEK
no_ocr
SEB · no reference
ignored
·
Reasons: no_ocr · invalid_ocr_checksum (Luhn mod-10) · no_matching_invoice · amount_overpaid (payment recorded + refund follow-up). Matching creates a completed bank_transfer payment and updates the invoice cross-tenant.
Import runs (SHA-256 idempotent)
File
Fetched
Format
Rows
Matched
Status
BGI-20260701-0610.txt
2026-07-01 06:10
BGMax
38
37
partial
pain002-20260630.xml
2026-06-30 06:05
ISO 20022
22
22
success
BGI-20260629-0610.txt
2026-06-29 06:10
BGMax
0
0
failed (parse)
Follow-ups (flagged, not yet live): SFTP fetcher against Swedbank's inbox with Key Vault credentials · move-on-processed to processed/ & failed/ · tenant-scoped queues for federations · parse-failure alerting (the 2026-06-29 run above would page).
Tenant
Engagement
Rate
Hours this month
Status
Invoicing
FFPJP (FR)
Data migration assistance
€150/h
22,25 h
active
€3 337.50 · 1 Jul run
Norges Forbund
Custom ranking rules workshop
€150/h
6,0 h
active
preview: €900 on 1 Aug
Svenska Bouleförbundet
Onboarding support (closed)
€150/h
—
completed
€8 100 total
Time entries in quarter-hour precision, DRAFT → SUBMITTED → INVOICED/VOIDED, max 24 h per consultant per day. The idempotent monthly job invoices SUBMITTED entries on the 1st. Revenue category pro_services_consulting — never included in subscription ARR. Customers see their own SUBMITTED/INVOICED entries (consultant identity hidden, DRAFT never exposed).
New engagement
Pro-services engagement
Manual FX rates (finance.fx.manage)
Pair
Rate
As of
Source
EUR/SEK
11,42
2026-07-01
manual
EUR/NOK
11,88
2026-07-01
manual
EUR/GBP
0,847
2026-07-01
manual
Convert rounds to 0.01 (ROUND_HALF_EVEN) and returns rate_used for audit. Missing rate → 422 fx_rate_unavailable. Sources ecb-daily/stripe-fx reserved for automation. Hedging & real-time feeds out of scope.
ECB quarterly fixing (invoicing in local currency)
Quarter
Fixed on
EUR/SEK
EUR/NOK
EUR/DKK
EUR/GBP
Q3 2026
2026-07-01
11,42
11,88
7,46
0,847
Q2 2026
2026-04-01
11,36
11,71
7,46
0,852
Q1 2026
2026-01-02
11,29
11,63
7,45
0,861
Fixing on the first banking day of Jan/Apr/Jul/Oct. Supported: EUR, SEK, NOK, DKK, GBP, USD, CHF. Every invoice stores ecb_fixing_rate + ecb_fixing_date for reproducibility.
Affiliate payment links (hybrid signup)
Organisation
Country
Currency
Amount
State
Expiry
Boule Café Aarhus
DK
DKK
11 200 DKK/yr
pending sys_support approval
—
Petanca Club Valencia
ES
EUR
1 490 EUR/yr
link sent
expires 2026-07-14
Boule Basel
CH
CHF
1 450 CHF/yr
paid → provisioned
—
Stripe Payment Links gated by sys_support approval; 14-day expiry; currency classified by country (SE→SEK, NO→NOK, DK→DKK, GB→GBP, CH→CHF, other→EUR). The webhook drives tenant provisioning.
Bot protection on public billing endpoints
99.2 %
Turnstile pass rate (7d)
41
Honeypot triggers (7d)
312
Rate-limit 429s (7d)
0
Spike alerts (>10× baseline)
Cloudflare Turnstile (invisible ~95 % of the time, GDPR-friendly, fail-open 5 s) + hidden honeypot fields (422 on fill) + per-endpoint Redis rate limits on all public POST endpoints (auth, contract requests, newsletter, contact, feedback, club applications). Structured audit log + Prometheus counters; alert on spikes.
Esc
↵ opens the first hit · Esc closes · 🔒 = locked function (still shown — with an explanation)