A sales platform for the digital world.
SaaS subscriptions, booking, CMS, software stores, an internal token economy, a first-class plugin system across three runtimes, and 20+ payment methods — one self-hosted backend, two Vue front-ends, infinite extensions.
VBWD is the missing layer between "I have a product" and "I'm taking real money". Subscriptions, accounts, invoices, taxes, payments, CMS pages, and a token economy — installed once, extended forever via plugins.
Tiered plans, add-ons, prorated upgrades, dunning, cancellation flows. Not a single payment provider — a marketplace of them.
Drop-in Python plugin SDK, typed Vue plugin SDK, event bus, DI container. Extend without forking the core.
Multi-tenant routing, brand-able admin, CMS pages, white-label payment selectors. One stack, many clients.
Built-in token bundles, usage metering, LLM billing. Sell AI features without writing the meter.
Every corner of VBWD is its own runtime with the same plugin contract. A new feature lights up by shipping a coordinated trio: a backend plugin that adds the API + data model, an fe-admin plugin that adds the configuration UI, and an fe-user plugin that adds the customer surface. Or any subset — they're independent.
/api/v1/*, SQLAlchemy 2.0, dependency-injector, event bus,
Alembic migrations. Plugins register Flask blueprints, models, event handlers,
line-item handlers, shipping providers, and admin permission scopes.
addRoute,
createStore, addComponent, addTranslations.
Topological dependency resolution; circular dependencies caught at install time.
${VAR_DIR}/plugins/ — backend writes, both frontends mount it read-only.
No localStorage drift, no per-browser inconsistency.
A single plugin entry can register code into all three runtimes at once. Each runtime exposes a typed surface so plugins can extend it without forks, monkey-patching, or "please rebuild the core" tickets.
/api/v1/<plugin>/*, mounted automatically when the plugin enables.subscription.created, payment.captured, …) on a typed bus.sdk.addRoute().sdk.createStore().DISCOVERED → REGISTERED → INITIALIZED → ENABLED ↔ DISABLED
(with an ERROR state for safe failure). Persistent across restarts via the
plugin_config table; the backend is the only writer.
get_blueprint() + get_url_prefix() auto-mount under /api/v1/<plugin>/* on enable, unmount on disable.
SQLAlchemy 2.0 entities tied to the plugin. Migrations applied on enable, optionally rolled back on uninstall.
register_event_handlers(bus) — listen to subscription, payment, checkout, security events. No polling.
Emit plugin events that other plugins consume. Cross-plugin coordination without direct imports.
Plug into checkout totals: discounts, taxes, shipping, token deductions. Each handler is a pure function over the cart.
Register concrete shipping cost calculators (flat-rate, weight-based, region-based) consumed by the order pipeline.
Contribute product / content categories with their own URL prefixes — picked up by routing rules at the edge.
Declare admin_permissions / user_permissions. Surfaces in the admin RBAC matrix; gates fe-* routes.
on_enable() — runs migrations, seeds data, registers handlers.on_disable() — unhooks handlers, halts background tasks.plugin_config; auto-rehydrated on app boot.get_config(key) / set_config(key, val) — namespaced KV store per plugin.PluginMetadata.Admin plugins are loaded by the host shell at boot. The shell keeps the chrome — login, layout, top-bar, theme — and yields every interior surface to plugins. A plugin can ship a single dashboard widget or a whole subsystem; the contract is the same.
Sidebar entries with icon, label, route, permission scope, and badge. Order is computed from priority + plugin install order.
Full-page Vue components mounted into the admin router. CRUD scaffolds + table / form / detail patterns provided by fe-core.
Drop-in cards on the home dashboard — KPIs, charts, recent activity. Self-fetching, plugin-namespaced data sources.
Plugin config screen auto-bound to get_config / set_config on the backend. JSON-schema-driven form generation.
Declarative v-permission on routes, menu, action buttons. Drives both UI hiding and server-side enforcement.
Locale dictionaries merged into the host i18n. New languages light up across every plugin's UI without per-plugin work.
${VAR_DIR}/plugins/fe-admin-plugins.json at boot. Toggling a plugin
on the backend immediately changes what the next admin login sees — no rebuild, no redeploy.
Active sessions, MRR, churn, top plans, recent activity. Widgets contributed by every enabled plugin.
List, search, edit, impersonate. RBAC matrix per role. Token-balance and invoice-history tabs in user detail.
Tiered plans with categories, pricing, trial, billing-period rules. Add-ons attach to plans or stand alone.
List, filter by state, manual upgrade / downgrade / cancel. Dunning view for past-due accounts.
List + detail, payment status, capture / refund actions, downloadable PDFs.
Per-provider configuration screens — keys, webhooks, test toggles, country availability.
Bundle catalogue, pricing, currency. Used by every metered plugin (LLM-Chat, Taro, …).
Outbound webhook subscriptions — pick events, set endpoint, view delivery log + retry queue.
Routing rules per domain / subdomain / path prefix — drives multi-tenant front-end config.
Tax rules per jurisdiction, currency selection, country-availability matrix used by checkout.
List backend / fe-admin / fe-user plugins, enable / disable, jump to the plugin's settings panel.
App config, email templates per locale, SMTP credentials, dunning schedules.
The user app is a single Vue 3 build that serves both the customer dashboard (account, plans, invoices, tokens) and any public surface a plugin contributes (CMS pages, shop catalogue, public chat, booking pages). Routing rules at the edge decide which audience hits which mount point.
IPlatformSDK exposes
addRoute · createStore · addComponent · addTranslations. The
PluginRegistry resolves dependencies topologically and refuses
to install on a missing peer or cycle.
One plugin trio (backend + fe-admin + fe-user) covers every CMS job a SaaS site needs. Marketing edits in the admin; the user-facing renderer picks it up on next request — no deploy, no shipping engineer.
Slug-routed pages with rich body, SEO fields, locale variants, draft/publish workflow. Per-page access level (public / authed / role-gated).
JSON / Markdown export per page, per category, or the whole site. Re-import into another instance to clone a content tree across deployments.
CSS custom properties drive every visual surface. Theme switcher per instance, per locale, or per landing — same components, different brand.
Hero, pricing table, FAQ, testimonials, gallery, plus widgets contributed by other plugins (booking form, shop grid, taro reading). Drop into any layout.
Multi-level menus, page or external links, per-locale. Menu changes are a CMS edit — not a frontend deploy.
Tag pages into categories for taxonomy + listings; gate categories or individual pages by user role / plan / token balance.
Block-based editor — hero, copy, image, columns, embed, plugin-contributed components. JSON-stored, render-time-composed.
Draft + publish + scheduled publish. Diff between versions; revert in one click. Full audit log of who changed what.
Per-page, per-block translations. Bulk translation export / import. The language switcher uses the page locale, not URL hacks.
Title, description, OG image, canonical, robots. Sitemap auto-generated; redirects table for retired pages.
On-the-fly resize / format conversion (WebP, AVIF). Width hints in the editor; srcset emitted to the browser.
Form widget — captures leads, posts to an event on the bus. Other plugins (email, mailchimp, ghrm) listen and act.
Multi-level navigation editor. Permission-aware: a CMS-page-only audience never sees admin links.
Subdomain / path-prefix / locale routing — same engine that powers multi-tenant. CMS pages bind to specific tenants.
cms_page · slug, locale, layout_id, status, seo, bodycms_layout · named layout, ordered widget slotscms_widget · type, props (JSON), order, layout_idcms_menu · tree of menu nodes, page or external linkcms_category · taxonomy for pages + productscms_image · upload + transform metadata
POST /api/v1/admin/cms/export dumps any page, category,
or the whole tree to JSON / Markdown with embedded asset refs.
POST /import rehydrates on a target instance — clone
an entire content tree across deployments in one request.
Pages join one or more cms_category nodes (taxonomy,
listings, breadcrumbs). Each page and category carries an
access_level: public · authed · role · plan · tokens>=N
— enforced server-side before the renderer ever runs.
9 providers · 20+ payment methods · one checkout flow.
Every payment provider in VBWD is a backend plugin implementing the same
PaymentProviderPlugin interface — create_payment_intent,
capture_payment, refund_payment, and a webhook handler.
fe-user contributes the matching checkout component. Adding a tenth provider is
one plugin, not a core change.
Cards, SCA / 3DS2, subscriptions, ACH, SEPA. Webhooks reconciled against the provider as source of truth.
Smart Buttons + redirect, Vault, Pay Later / BNPL, Apple Pay through PayPal, disputes flow.
Russia / CIS — cards, SberPay, Yandex.Kassa, e-wallets, bank transfers.
LatAm / Brazil — cards, boleto, account transfer, regional installments.
Mexico / LatAm — cards, OXXO cash voucher, SPEI bank transfer, monthly installments.
Korea — cards, virtual accounts, mobile-carrier billing, KRW-native flows.
Thailand — TrueMoney e-wallet integration, in-app QR confirmations.
Thailand — QR-code bank-transfer payments, real-time confirmations.
Google Pay tokens via the C2P2 plugin. Mobile-first checkout with one-tap completion.
Apple Pay tokens via the C2P2 plugin. Domain-association handled by the plugin.
Sister plugin — shipping cost calculator that plugs into the same line-item pipeline as payments.
Implement PaymentProviderPlugin, ship a fe-user checkout component. Two files; live in one enable.
Each one a complete feature; each one optional; each one composable.
Mainchat is the public-facing conversational surface — pre-sales questions, support intake, lead capture. It does not bill tokens; it is free for the visitor. Conversations land in the same admin inbox as authenticated chats, so support never has two queues.
lead.captured on the bus — email plugin, Mailchimp plugin, GHRM listen and act.Inside any thread, a user can send tokens to another user with one
tap — gift, tip, refund, peer-to-peer transfer. Same wallet primitive
(UserTokenBalance) the rest of the platform uses; the
chat surface is the UX.
Mainchat events drive token flows: lead.captured ⇒ auto-credit
the referrer · "priority response" purchase ⇒ token deduction ·
support tip ⇒ transfer to the operator's account. Events on the
same bus the platform already uses.
Every in-chat transfer creates two ledger entries (sender / recipient)
and emits tokens.transferred. Admin can reverse from the
same inbox where the conversation lives. Daily caps + velocity rules
apply.
The booking plugin turns any account into a bookable resource — consultations, classes, equipment rental, room reservations, telemedicine slots. It composes with subscriptions (a plan can include N bookings / month), payments (charge per slot), and the token economy (book by spending tokens).
Resources expose availability windows; slots are the bookable unit. Buffer time, lead time, capacity per slot, recurring patterns.
Beyond time slots — physical inventory (rooms, equipment) with stock counts, holds during checkout, automatic release on timeout.
Customer-side flow with policy enforcement (free up to N hours before, partial refund window, no-show fee).
Emits booking.created · confirmed · cancelled · noshow. Email plugin sends confirmations; calendar plugin syncs to Google / Outlook.
Plan defines monthly booking allowance; quota enforcement runs at booking time. Overflow can charge tokens or block.
Resource calendar, booking list, no-show register. Bulk reschedule when a resource goes offline.
The shop plugin gives VBWD a product catalogue alongside the subscription model. One-time purchases, downloadable products, license keys, physical goods. The checkout, the payment providers, the tax engine, the discount codes — all shared with subscriptions. Two billing models, one storefront.
Products with variants (size, license tier, region). SKU-level inventory, per-variant pricing, category taxonomy from the CMS.
Multi-item, multi-currency, per-region tax preview. Shared session with the rest of the user app — never "where did my cart go".
Order list with state machine (pending → paid → fulfilled → shipped → delivered). Refund and partial-refund flows on every state.
RMA flow — customer-initiated, admin-approved, refund auto-issued through the original payment provider.
For software products — generate, deliver, revoke. Customer can view their keys in the dashboard, regenerate on lost-key request.
Time-limited signed URLs for digital products. Per-customer download caps. Watermarking hook for plugin extension.
Composes with shipping provider plugins (flat-rate ships out of the box; weight-based or carrier-API plugins drop in).
order.created · paid · fulfilled · shipped · refunded · returned — fan out to fulfillment, accounting, CRM.
LLM-Chat is a deliberately thin plugin whose only job is to demonstrate how the platform's internal token wallet integrates with any external API service behind it (OpenAI, Anthropic, Mistral, a self-hosted endpoint — anything). Clone this plugin, replace "LLM" with "your-external-service", and you have a billing-ready feature in an afternoon.
@meter("chat.send", cost=10) deducts before the external call fires — no half-charged round-trips.plugins/llm-chat/config.json, never in the user UI. API key rotation is one admin action.Taro is a deliberately small AI tarot-reading plugin whose primary purpose is to show what the platform's subscription engine can configure: tiered plans, monthly feature grants, included token allowances, plan-gated spreads, add-on bundles, prorated upgrades. Marketing edits the plans in the admin; the plugin reads the rules at runtime. Nothing about pricing is hardcoded.
Free / Reader / Pro tiers, each defined entirely in the admin: monthly price, included readings, allowed spread types, refresh cadence.
"Pro = €19 + 30 readings/month"; sell extra token bundles for users who burn through their grant. Roll over or expire — admin chooses.
Celtic-cross spread + custom prompts unlocked only on Pro; Free tier limited to single-card draw. All toggled from the plan definition.
config.json mapping plan → feature flags.Models · events · services · DI · SOLID · security.
Every domain in VBWD has a small, named set of SQLAlchemy 2.0 entities. New plugins add their own; the core never grows by accretion. The list below is what the platform ships with on day one — what every plugin can rely on existing.
User, UserDetails, UserAccessLevel, RoleUserTokenBalance — the walletPasswordResetTokenFeatureUsage — quota trackingTarifPlan, TarifPlanCategorySubscription — state machine, renewal, dunningAddOn, AddOnSubscriptionTokenBundle, TokenBundlePurchaseInvoice, InvoiceLineItemPaymentMethod — provider + customer-instrumentTax, Country, Currencyplugin_config — enable / disable + per-plugin KVWebhook subscriptions + delivery logThe event bus is the platform's spinal cord. Every meaningful state change emits a typed domain event; plugins subscribe to what they care about. Email confirmations, analytics, Mailchimp sync, dunning, GHRM access grants — none of them are wired into the services that triggered them.
subscription.created · activated · cancelled · expired · dunningpayment.authorized · captured · failed · refunded · refund.reversedcheckout.initiated · completedsecurity.password_reset.request · execute · login.failedplugin.registered · initialized · enabled · disabledchat.tokens.consumed, booking.created, order.fulfilled, lead.captured
The core uses dependency-injector to wire repositories, services,
and infrastructure (database session, Redis client, event bus, secrets provider).
Every consumer asks for what it needs; nothing reaches for it through a global.
The container is configured once at app start and overrideable in tests.
One Container per app, declared as a class with typed providers — singletons, factories, configurations, resources.
Routes, services, plugins receive collaborators via constructor injection. @inject at the edges; pure constructors elsewhere.
In tests, providers are swapped: in-memory repositories, fake event bus, deterministic clock. No service knows it's been mocked.
AuthService, UserService, SubscriptionServiceInvoiceService, RefundService, TokenServicePluginService · enable / disable / configWebhookService, EmailServiceEventDispatcherUserRepository, SubscriptionRepository, InvoiceRepository, …BasePlugin, PaymentProviderPlugin, line-item handler, event subscriber.make test is the gate; CI re-runs on every push. No tests, no merge.core.utils or a base class — never copy-pasted. A bug fix happens once, in one place../deploy.sh <instance> from clean clone to live: <5 min.Bearer tokens with short TTL + refresh. Signed with a per-deploy secret; rotated without invalidating live sessions.
Roles + access levels. Plugins declare their own permission scopes; the matrix is editable from the admin UI.
Public endpoints rate-limited per IP and per user. Login + password-reset flows have stricter caps + lockouts.
Time-limited single-use tokens. Same response shape on success and on unknown email — no enumeration leak.
Outbound webhooks signed with HMAC; inbound (from payment providers) verified before any state change.
Order creation, payment capture, refund — all idempotent against an idempotency-key column. Retries are safe.
Every privileged action recorded — who, when, what, from where. Plugins extend the schema with their own audit entries.
Provider keys via env vars or vault references — never in code, never in plugin_config. Fail-closed on default secrets.
login.failed events feed velocity-based blocks.47 public repos under VBWD-platform. BSL 1.1 — self-host for free, license needed only at production scale.
The runtime that boots before any feature loads — auth, sessions, plans,
invoices, events, the plugin loader. Read the code, run the test suite, file
an issue. Everything below is one git clone away.
Recipes, dev-install scripts, integration test harness. Start here to spin up the whole stack on a laptop in under five minutes.
The API — auth, billing, CMS, plugin host, event bus, DI container. Postgres + Redis. Drop-in plugins via standard Python imports.
The user-facing SPA — dashboard, checkout, plan picker, invoices, language switcher. Plugins inject their own routes + stores at boot.
The back-office SPA — plans, users, invoices, plugin settings, content moderation. Same plugin contract as fe-user; same hot-reload story.
Each plugin trio — backend + fe-admin + fe-user — is a complete feature you can ship as-is or fork. Mix and match: a hotel ships booking + cms; a SaaS ships subscription + meinchat; a creator marketplace ships shop + discount. The core never changes.
Drop-in CMS with theme switcher, page-level access control, and a widget registry that other plugins extend.
Calendars + bookable resources. Doctors, hotels, classrooms — same engine, different config. Includes admin moderation + user self-service.
Storefront catalogue + warehouse inventory + checkout flow. Pairs with discount for coupons and shipping_flat_rate for fulfilment.
Nicknames, address book, image attachments, peer-to-peer token transfer. Admin moderation: ban, audit, inspect any conversation.
Tiered plans, add-ons, prorated upgrades, dunning, cancellation. The billing backbone every paying instance depends on.
vbwd-plugin-<name>,
vbwd-fe-user-plugin-<name>,
vbwd-fe-admin-plugin-<name> — three repos per feature, each
with its own tests and CI.
Talk to us. Buy a license. Build a business on VBWD.
If you run a digital agency, a dev shop, or you consult on billing and identity infrastructure, VBWD is a product you can resell. You sell the license + the implementation; we provide the platform, the updates, and tier-3 support. Your client's logo on the dashboard, your name on the contract.
A sales platform for the digital world. One self-hosted backend, two Vue front-ends, one plugin contract, twenty-plus payment methods, an internal token economy, a CMS, a shop, a booking engine, and an extensible AI surface — installed once, extended forever.
./recipes/dev-install-ce.sh