إنتقل إلى المحتوى الرئيسي

06 — License enforcement, trial and subscription mechanics for Rasd Forms

Research date: 2026-08-15. Scope: how commercial JS component vendors enforce licenses, what developers complain about, billing/MoR platforms, UN procurement and data-protection constraints, and a recommended token + state-machine architecture for a free 7-day trial followed by a monthly-subscription token.

Summary

  1. The dominant model among JS component vendors is per-developer seat, perpetual-in-production, 12 months of updates, enforced by an offline-verifiable key that encodes an expiry date which is compared against the package's release/build date (MUI X, Handsontable, Kendo, DevExtreme, SurveyJS; AG Grid follows the same pattern per community reports) [2][4][7][9][12][19].
  2. Enforcement is almost universally soft: watermark + console warning + (sometimes) an on-page banner; the component keeps working ("End users can still use the component" — MUI X) [2][6][7][8][9]. Nobody hard-stops end users at runtime.
  3. Two vendors use distribution-based enforcement instead of runtime keys: Tiptap Pro (private npm registry, personal non-expiring token) and Bryntum (public -trial packages with watermark, licensed builds on npm.bryntum.com) [10][11][13]. Private registries generate real CI/CD friction (403s on Netlify, token leakage) [14].
  4. Highcharts is effectively an honor system (per-developer license, no key) and is free for non-profits under CC BY-NC 3.0; Syncfusion gives a free Community License to companies < $1M revenue / ≤5 devs [17][18].
  5. MUI X's key format is instructive and reproducible: md5(payload) + base64(payload), payload O=order,E=expiryTs,S=pro|premium,LM=perpetual|annual|subscription,PV=planVersion,Q=seats,AT=appType, statuses NotFound/Invalid/Valid/OutOfScope/ExpiredVersion/ExpiredAnnual/ExpiredAnnualGrace(30 days, dev only); no network requests — "designed to be public" [3][2].
  6. Developers' recurring complaints: keys "leak" in client bundles (SurveyJS #7646) [5]; renewed keys not taking effect / stale watermarks (MUI #20673) [6]; keys silently invalid after upgrading past the license window; mandatory-key roll-outs breaking builds (Telerik 2025 Q1 mandatory telerik-license.txt) [8][20]; private-registry auth failures in CI [14].
  7. Offline licensing best practice (Keygen): Ed25519-signed license files/tokens verified against a public key embedded in the SDK, with embedded expiry, offline duration, grace period, entitlements; clock tampering "can't really be prevented" offline — mitigate with a last-seen timestamp file and periodic online refresh [21][22].
  8. Ed25519 is now in WebCrypto in all engines (Safari 17, Firefox 129 Aug 2024, Chrome 137 May 2025, ~79% of users) but React Native needs a pure-JS verifier such as @noble/ed25519 (~5 KB) [23][24].
  9. Billing: Stripe Billing is a flat 0.7% (+2.9% + 30¢ processing) with a first-class Entitlements API (entitlements.active_entitlement_summary.updated webhook); Stripe Invoicing 0.4%/paid invoice (cap $2) supports send_invoice, Net-30, PO numbers — the fit for UN POs. MoR options: Paddle 5% + 50¢, Lemon Squeezy 5% + 50¢ (+0.5% subs; being migrated to "Stripe Managed Payments", public preview Feb 2026), Polar Starter 5% + 50¢ / Pro $20 mo 3.8% + 40¢ [25][26][27][28][29][30].
  10. UN agencies process personal data under the HLCM Principles (adopted 11 Oct 2018) that bind processing "on behalf of" UN organizations, are tax-exempt under the 1946 Convention, buy through UNGM registration, LTAs and POs, and rarely put a card into a self-serve checkout — so runtime telemetry from enumerator devices must be zero and invoice/PO purchasing must exist from day one [31][32][33].

1. How incumbents enforce licenses

1.1 Runtime key, offline-verified, release-date-bound (the mainstream)

MUI X Pro/PremiumLicenseInfo.setLicenseKey() from @mui/x-license, must run before first render. Pro $299/dev/yr, Premium $599/dev/yr; "perpetual in production", 12 months of updates; per concurrent developer contributing changes to front-end code. Missing/invalid/expired key → watermark + console warning "in both development and production. End users can still use the component". Verified locally: "checked without making any network requests — it's designed to be public". 30-day evaluation license for non-production [1][2]. Source shows the exact grammar (Summary #5) plus a 30-day dev-only grace after annual expiry and a "package release date > expiry ⇒ ExpiredVersion" rule for perpetual licenses [3].

AG Grid Enterprise — key via LicenseManager.setLicenseKey() (<35.1) or licenseKey prop on AgGridProvider (≥35.1). No key → watermark + console errors; local testing without key is explicitly allowed; production trials require a requested trial key. $999/dev perpetual with 1 year updates; Enterprise Bundle $1,498/dev [4][15]. Community threads show confusion around invalid keys after upgrades and sharing one key across developers (issues #1269, #1200), i.e., the key-per-release-window rule is a support burden [16].

HandsontablelicenseKey option; string 'non-commercial-and-evaluation' for non-commercial use. Validation "compares the build date of your Handsontable version against the creation date embedded in the key … does not trigger any connection to any server". Messages render below the table and in console for missing/invalid/expired [7].

SurveyJS — Form Library is MIT; Creator/Dashboard/PDF are commercial per developer, royalty-free, perpetual + optional renewal (Basic $569/€499, renew $229; PRO $1,029/€899, renew $409; Enterprise from $2,299). Since v1.9.115 setLicenseKey() is the only way to remove the alert banner; banner-free "as long as you are using a version released before your current subscription expires". No usage/MAU fees. Issue #7646 (Jan 9 2024): "any user could grab our license key at will" — the classic client-bundle objection [5][12][19].

Kendo UI / Telerik (2025 Q1)@progress/kendo-licensing, npx kendo-ui-license activate, key file ~/.telerik/telerik-license.txt or TELERIK_LICENSE env (renamed from kendo-ui-license.txt/KENDO_UI_LICENSE). From 2025 Q1 a key is mandatory for all products; unlicensed → console warning + page banner + component watermark; file "can be used for all versions published before its expiration date"; validation is a development/build-time concern — deployed builds keep working [8][20].

SyncfusionregisterLicense() from @syncfusion/ej2-base or npx syncfusion-license activate with SYNCFUSION_LICENSE; without it the app shows "This application was built using a trial version…". Introduced 2022 Vol 1; free Community License if < $1M revenue, ≤5 devs, ≤10 employees, < $3M outside capital [9][18].

DevExtreme (v23.2+) — on-screen message + console warning without key; 30-day trial; recommends add-devextreme-license in postinstall; "license mismatch" warning if the version was released after key expiry [19].

GoJS — key bound to domain and major.minor version, valid forever, works on subdomains and localhost; watermark otherwise. The cleanest per-application/domain example [17].

FusionCharts — evaluation builds are watermarked indefinitely; licensed use via FusionCharts.options.license({key, creditLabel:false}) in newer builds or file replacement in older ones (fetched page documents only replacement — activation-mechanism details not verified) [13].

1.2 Distribution-based enforcement

Tiptap Pro — Pro extensions live on https://registry.tiptap.dev/; personal _authToken that "does not expire", set as TIPTAP_PRO_TOKEN; a "dedicated user for CI/CD" is recommended; no runtime check or watermark documented. Third-party pricing summaries cite $49/$149/$999 per month tiers (not verified on the primary page) [10][11]. Issue #7053 (Oct 2025) shows a developer unable to install on Netlify (403 from the registry despite a working token) — private registries push licensing pain into CI [14].

Bryntum — public @bryntum/<product>-trial packages (aliased under the real name so only package.json changes on purchase) with a trial watermark; licensed packages on npm.bryntum.com / npm-us.bryntum.com behind npm login. EULA: 45-day trial, one trial per 18 months, "Designated Developer" licensing, support subscription auto-renews [10].

1.3 Honor system

Highcharts — per-developer Internal/SaaS/OEM licenses; free for personal/non-profit under CC BY-NC 3.0; free during development/testing; no key mechanism is documented anywhere in the shop FAQ or docs [17].

2. Comparison tables

2.1 Vendors

VendorUnit of salePrice (verified)EnforcementOffline?Trial
MUI Xper concurrent dev, annual updates, perpetual prodPro $299/yr, Premium $599/yrkey; watermark + console (dev+prod); component still worksyes, "designed to be public"30-day eval, no key needed in dev
AG Gridper dev, perpetual + 1 yr updates$999; bundle $1,498key; watermark + consoleyes (client-side)local dev free; trial key on request
Handsontableper dev (per docs/EULA)n/a on pagekey; message under grid + consoleyes, "no connection to any server"non-commercial-and-evaluation string
SurveyJSper dev, perpetual + optional renewal$569 / $1,029 / from $2,299key removes banner; banner otherwiseyesfree MIT Form Library; Creator shows banner
Kendo/Telerikper dev subscriptionn/akey file/env; banner + watermark + console; build-timeyesmandatory since 2025 Q1
Syncfusionper dev; free Community tiern/akey; trial banner textyesCommunity < $1M rev
DevExtremeper devn/akey; on-screen msg + consoleyes30 days
GoJSper domain + major.minorn/akey; watermarkyeslocalhost always OK
Tiptap Proper org plan (monthly)$49–$999/mo (3rd-party)private registry tokenn/a (install-time)trial via account
Bryntumper Designated Developern/atrial pkgs watermark; private registryn/a45 days, 1 per 18 mo
Highchartsper dev; free non-profitn/anone (honor)n/afree while developing

2.2 Billing / license-key platforms

PlatformFees (verified 2026)MoR (VAT handled)License-key APIInvoices/POs
Stripe Billing + Entitlements0.7% billing + 2.9% + 30¢; Invoicing 0.4% capped $2 (Starter)No (Stripe Tax add-on; "Stripe Managed Payments" MoR in public preview Feb 2026)No keys; Entitlements (Features, lookup_key, summary webhook, List Active Entitlements)Yes: send_invoice, days_until_due, PO number field, bank transfer
Paddle5% + 50¢YesNo"contact us" for invoicing
Lemon Squeezy5% + 50¢ (+0.5% subs, +1.5% intl/PayPal)Yes; acquired by Stripe 2024, migrating to Managed PaymentsYes: activate/validate/deactivate, instances, activation_limit, 60 req/minLimited
PolarStarter 5% + 50¢; Pro $20/mo 3.8% + 40¢; Growth $100 3.6% + 35¢; Scale $400 3.4% + 30¢; +1.5% intl; $15 disputeYesYes: license-key benefit, activation limits, usage quota, validate/activate/deactivateLimited
Whop2.7% + 30¢ (+1.5% non-US, +1% FX; 30% marketplace commission)Partial (creator-focused)Yes (basic)No — consumer/community oriented
ChargebeeStarter free ≤ $250K lifetime billing; Performance $599/mo, 0.75% overageNoNoStrong B2B invoicing/PO

3. Design space for the Rasd token

3.1 Signed offline-verifiable token

Keygen's guidance and MUI's implementation converge: sign a compact payload with an asymmetric key, embed the public key in the SDK, verify without network. Keygen recommends Ed25519 (ECDSA P-256 only for NIST-compliance needs) and lists the standard embedded fields: expiry, "duration a license is allowed to be offline", grace period, entitlements [21]. A JWT (RFC 7519) with alg: EdDSA is verifiable by any standard library and by WebCrypto in all current engines; on React Native (no WebCrypto Ed25519) bundle @noble/ed25519 (~5 KB, v1 audited by cure53 Feb 2022; v2 not independently audited) or jose [23][24]. MD5-hash keys like MUI's only detect corruption, not forgery — anyone can mint one; a signature is strictly better and equally cheap.

Recommended claims: iss=https://license.rasd.dev, sub=org_…, aud=rasd-forms, jti, iat, nbf, exp (token validity, not subscription end), plus rf (plan: trial|team|org|enterprise), ft (feature flags: builder, sync, themes, pdf…), apps (bundle IDs / domains, wildcard subdomains à la GoJS), seats, sub_until (paid-through date), grace_d (grace days after exp), off_d (max offline days), trial: true|false, kid in the header for rotation.

3.2 Periodic refresh with long offline grace

Field monitors can be offline for weeks; the builder is used online by admins. Therefore: tokens have exp = iat + 60 d, the SDK attempts a silent refresh whenever it is online and the token is > 7 days old (piggy-backing on the app's data sync), and honors a grace_d = 30 window after exp. Net effect: ≈ 90 days fully offline before any degradation, and a device that syncs monthly never notices licensing at all. Keygen frames this as "license file expiry" separate from "license expiry" [21]. Enterprise/air-gapped: issue 12-month tokens against annual invoices (Kendo/MUI already treat keys as valid for all versions released before expiry).

3.3 Clock tampering

Fully offline devices cannot be protected — "what the offline device says is the time … is the time" [22]. Cheap mitigations: (a) persist last_seen and server_time_at_refresh in the SDK's IndexedDB/SQLite store; if now < last_seen − 24 h, do not extend grace (freeze state, don't punish); (b) refuse tokens with nbf far in the future; (c) compute skew from the refresh response. Be lenient — low-end Android devices in the field frequently have wrong clocks and time zones [22].

3.4 Key rotation and revocation

Ship 2–3 public keys keyed by kid; publish JWKS at /.well-known/jwks.json for online refresh; rotate yearly. Revocation = short token life + refresh (a cancelled subscription simply stops refreshing) plus an optional revoked_jti list returned by the refresh endpoint. Never rely on a client-side blocklist for offline devices.

3.5 Soft vs hard enforcement

Every incumbent keeps the component working and degrades UX (watermark, banner, console). For a humanitarian data-collection tool a hard stop that blocks an enumerator mid-survey is unacceptable; the collector runtime must never lose data. Enforce on the developer-facing surfaces instead: builder watermark/banner, console warnings, disabled premium exports, npx rasd-forms license check failing CI when the token is expired beyond grace, and license status visible in the admin UI.

3.6 Trial mechanics and reset resistance

Vendors either allow key-less local dev forever (MUI, AG Grid, GoJS on localhost) with a permanent watermark, or hand out account-based trial keys (Bryntum: 45 days, once per 18 months). Device fingerprinting is fragile and privacy-hostile; Stripe's guidance is layered signals + disposable-email blocklists + "progressive friction" rather than a single hard gate [34]. Recommendation: (1) no token ⇒ localhost/dev-only mode with watermark, indefinitely (removes most of the incentive to reset trials); (2) 7-day trial token requires an account (verified email, work-domain preferred), issued via npx rasd-forms trial or the dashboard, trial:true, no refresh; (3) one trial per organization domain; (4) after trial: limited mode (watermark, builder read-only, sync capped) rather than hard-stop.

3.7 Telemetry / privacy expectations

UN HLCM Principles (adopted 11 Oct 2018) cover data processed "by, or on behalf of" UN organizations — purpose specification, proportionality/necessity, security, transparency, transfers, accountability [31]. Practical rule: enumerator devices make zero calls to Rasd servers; refresh calls originate from the developer/CI or the admin builder, carry only token + sdk_version + app_id, no IPs retained beyond security logs, no form content, no PII; publish a DPA and a data-flow diagram; document that all verification is offline. This is also a sales differentiator versus phone-home DRM.

3.8 Public-key exposure

MUI's stance ("designed to be public") is the right one: assume the token ships in the bundle. Bind it to apps (domains/bundle IDs) and to sub_until; the value proposition is refresh + support + updates, not secrecy. Provide RASD_LICENSE env/CI injection and a .rasdrc file, never ask developers to commit tokens (Tiptap's warning) [11].

4. Billing, VAT and UN procurement

  • Self-serve monthly: Stripe Billing (0.7%) with Products→Features via Entitlements; on entitlements.active_entitlement_summary.updated (payload capped at 10 entitlements; use entitlements.url for more) the license service upserts the org's entitlements and mints/refreshes tokens; on startup or webhook failure reconcile with List Active Entitlements [25][26]. Stripe Tax handles VAT/GST for card sales; if you prefer full MoR, Paddle or Polar are drop-ins at 5% + 50¢ (Polar 3.4–3.8% on paid plans) [27][28][29]. Avoid starting on Lemon Squeezy: it is mid-migration to Stripe Managed Payments (public preview Feb 2026) [30].
  • UN/NGO purchasing: register on UNGM; expect RFQs, POs, Net-30/60 invoices and multi-year LTAs; card checkouts are the exception [33]. UN entities are exempt from direct taxes under the 1946 Convention — invoices must support zero-tax/exempt lines and reverse-charge notes [32]. Stripe Invoicing (collection_method: send_invoice, days_until_due, PO number, bank-transfer) or Chargebee handle this; the license service must be able to mint annual tokens from a manual "invoice paid" event, not only from webhooks [26].
  • Legal text: keep runtime core (renderer, JSON schema, RTL/i18n) under MIT/Apache-2.0 for procurement friendliness; commercial modules (builder, sync engine, themes) under a proprietary EULA with per-organization/per-application terms, or FSL-1.1 (converts to Apache/MIT after 2 years) if source-available is desired for trust — FSL was designed for SaaS "competing use", so pair it with the EULA/token for libraries; BSL (4 years) and ELv2 (no conversion) are alternatives; none are OSI-approved [35].

License service (small Node/Deno API): POST /v1/trials (email → verify → trial token), POST /v1/tokens/refresh (old token → new token or revoked), GET /v1/orgs/:id/tokens (dashboard), GET /.well-known/jwks.json, webhook receivers for Stripe (entitlements.*, invoice.paid, customer.subscription.deleted) and a manual "PO paid" admin action; Postgres tables orgs, apps, subscriptions, entitlements, tokens(jti, kid, exp, revoked).

Token: JWT, EdDSA/Ed25519, kid, claims as in §3.1; sizes < 700 bytes.

SDK behaviour

NONE ──(no token)──▶ DEV_ONLY (localhost/debug: watermark, all features)
PROD w/o token ─▶ LIMITED
TRIAL (trial:true, ≤7 d) ─exp──▶ LIMITED
ACTIVE (sig ok, now<exp) ─online refresh──▶ ACTIVE
ACTIVE ─(exp passed, now<exp+grace_d)──▶ GRACE (full features, console warn, banner in builder)
GRACE ─(exp+grace_d passed)──▶ LIMITED (renderer keeps collecting & syncing local data;
builder read-only + watermark; premium widgets off)
any ─(bad signature / aud / apps mismatch)──▶ INVALID (treated as NONE)

Rules: refresh attempts are opportunistic (on app foreground, on sync success, at most 1/day); clock rollback freezes but never regresses state; state is stored alongside sync data (IndexedDB/SQLite) so a reinstall re-derives it; rasd.license.status() exposes the state and sub_until to the host app.

Implications & recommendations for Rasd Forms

  1. Sell per organization + application (bundle ID/domain list, seat count as a soft claim) on a monthly Stripe subscription, with an annual invoiced tier for UN agencies; do not meter submissions/MAU (SurveyJS/AG Grid customers explicitly value royalty-free runtime).
  2. Token = Ed25519 JWT verified offline; embed public keys, rotate via kid; verify with WebCrypto on web and @noble/ed25519 on RN.
  3. Token lifetime 60 d + 30 d grace, silent refresh piggy-backed on sync, so field devices tolerate ~90 days offline; 12-month tokens for invoiced/air-gapped customers.
  4. Never hard-stop the collector: degrade to LIMITED (builder watermark/read-only, premium off, CI check fails); keep collecting/syncing local data.
  5. 7-day trial is account-based (verified email; one per org domain); key-less DEV_ONLY mode is unlimited on localhost so nobody needs to "reset" a trial; no device fingerprinting.
  6. Zero telemetry from end-user devices; refresh only from dev/CI/admin contexts with minimal payload; publish DPA aligned with UN HLCM Principles.
  7. Handle clock rollback by freezing state; store last_seen/server time in the SDK store; be lenient with drift.
  8. Bill with Stripe Billing + Entitlements + Invoicing (+ Stripe Tax); keep an abstraction so Paddle/Polar (MoR) can be swapped in for VAT-averse regions; register on UNGM early and support POs, Net-30 and tax-exempt invoices.
  9. License text: MIT core + proprietary EULA (or FSL-1.1) for commercial modules; explicitly allow use in offline/humanitarian contexts and state that the token may appear in client bundles.
  10. Provide the tooling incumbents lack: npx rasd-forms license {trial|check|refresh}, RASD_LICENSE env/CI docs, clear console messages that name the state and sub_until, and a "renewed key not applied" troubleshooting page (MUI #20673) — most complaints are UX, not policy.

Sources (accessed 2026-08-15)

  1. MUI X Pricing — https://mui.com/pricing/
  2. MUI X Licensing docs — https://mui.com/x/introduction/licensing/
  3. MUI X verifyLicense.ts source — https://github.com/mui/mui-x/blob/master/packages/x-license/src/verifyLicense/verifyLicense.ts
  4. AG Grid React — Installing Your Licence Key — https://www.ag-grid.com/react-data-grid/license-install/
  5. SurveyJS issue #7646 "setLicenseKey will leak the license key?" — https://github.com/surveyjs/survey-library/issues/7646
  6. MUI X issue #20673 (renewed key not reflected) — https://github.com/mui/mui-x/issues/20673
  7. Handsontable License key docs — https://handsontable.com/docs/javascript-data-grid/license-key/
  8. KendoReact — Activating Your License Key — https://www.telerik.com/kendo-react-ui/components/my-license
  9. Syncfusion React Licensing overview — https://ej2.syncfusion.com/react/documentation/licensing/overview
  10. Bryntum trial packages / EULA (npm @bryntum/gantt-trial; license.pdf) — https://www.npmjs.com/package/@bryntum/gantt-trial ; https://www.bryntum.com/dist/scheduler/license.pdf
  11. Tiptap Pro Extensions guide — https://tiptap.dev/docs/guides/pro-extensions
  12. SurveyJS Licensing FAQ — https://surveyjs.io/faq/licensing
  13. FusionCharts — Upgrading from evaluation versions — https://www.fusioncharts.com/dev/upgrading/upgrading-from-evaluation-versions
  14. Tiptap issue #7053 (Netlify 403) — https://github.com/ueberdosis/tiptap/issues/7053
  15. AG Grid Licence & Pricing — https://www.ag-grid.com/license-pricing/
  16. AG Grid issues #1269 / #1200 (shared keys, key encryption) — https://github.com/ag-grid/ag-grid/issues/1269 ; https://github.com/ag-grid/ag-grid/issues/1200
  17. Highcharts shop FAQ / GoJS deployment & license keys — https://shop.highcharts.com/faq ; https://gojs.net/latest/intro/deployment.html
  18. Syncfusion Community License — https://www.syncfusion.com/products/communitylicense
  19. SurveyJS Pricing / DevExtreme Licensing — https://surveyjs.io/pricing ; https://js.devexpress.com/React/Documentation/Guide/Common/Licensing/
  20. Telerik blog — License Key Files in Telerik and Kendo UI Products 2025 — https://www.telerik.com/blogs/license-key-files-telerik-kendo-ui-products-2025-update
  21. Keygen — Offline licensing model — https://keygen.sh/docs/choosing-a-licensing-model/offline-licenses/
  22. Keygen discussion #25 — Offline licenses and clock tampering — https://github.com/orgs/keygen-sh/discussions/25
  23. Igalia — Ed25519 support lands in Chrome (137) — https://blogs.igalia.com/jfernandez/2025/08/25/ed25519-support-lands-in-chrome-what-it-means-for-developers-and-the-web/
  24. @noble/ed25519 README — https://github.com/paulmillr/noble-ed25519
  25. Stripe — Entitlements (API) — https://docs.stripe.com/billing/entitlements
  26. Stripe Billing 0.7% / Invoicing pricing — https://usagebox.com/articles/stripe-billing-fees-2026-the-07-percent-math ; https://support.stripe.com/questions/stripe-invoicing-pricing
  27. Paddle pricing — https://www.paddle.com/pricing
  28. Polar fees — https://polar.sh/docs/merchant-of-record/fees ; https://polar.sh/docs/features/benefits/license-keys
  29. Lemon Squeezy License API & pricing — https://docs.lemonsqueezy.com/api/license-api ; https://www.lemonsqueezy.com/pricing
  30. Lemon Squeezy — 2026 update: Stripe Managed Payments — https://www.lemonsqueezy.com/blog/2026-update
  31. UN CEB — Personal Data Protection and Privacy Principles (HLCM, 11 Oct 2018) — https://unsceb.org/privacy-principles
  32. Convention on the Privileges and Immunities of the United Nations (1946), tax exemption — https://en.wikipedia.org/wiki/Convention_on_the_Privileges_and_Immunities_of_the_United_Nations
  33. UN Procurement — Information for New Vendors / UNGM — https://www.un.org/procurement/vendors-info ; https://www.ungm.org/
  34. Stripe — Free trial abuse: tactics, signals, prevention — https://stripe.com/resources/more/free-trial-abuse-tactics-signals-and-prevention
  35. Functional Source License — https://fsl.software/ ; Whop pricing — https://whop.com/network/pricing/ ; Chargebee pricing — https://www.chargebee.com/pricing/