Do you charge customers, or pay partners? VBWD’s hub runs both directions at once — entitlement licensing in, Stripe-Connect-style commissions out — on one instance. Here’s how the two rails coexist.
Rewritten for redrobot.
Here is a question that quietly decides the ceiling of a lot of software businesses: when a sale happens on your platform, which direction does the money move? For most operators there is only one answer. Either money flows in because someone bought your product, or money flows out because you paid a partner who brought you that buyer. Pick one, build your billing stack around it, and you have unknowingly drawn a box around what your company is allowed to become.
What follows is a look at a platform that refuses to pick — and the design tricks that let a single running instance handle both money directions without turning into two systems duct-taped together. Some of it is shipping. Some of it is still being assembled. I will flag which is which as we go, because the interesting part is the mechanism, and mechanisms deserve honesty.
Two directions, one box
The platform in question is VBWD: source-available, self-hosted, built on Python and Flask with PostgreSQL underneath and a Vue 3 admin on top, all wrapped in Docker. Its defining choice is architectural rather than commercial. The core is deliberately ignorant. It knows about tariff plans, invoices, subscriptions, users, and an admin backoffice — but it does not know what you sell, and it does not know what a “commission” is. All of that meaning lives in a plugin layer bolted onto the generic spine.
That ignorance is exactly what makes the two-direction trick possible. Because the core does not hard-code a business model, a single instance can be configured as a hub: not just a product you log into, but the commercial center of a network. A hub keeps all the ordinary machinery and adds two things on top — the authority to issue signed proof that someone is entitled to something, and a ledger that decides who gets paid when a referred sale closes. Neither requires a second server or a second database. It is one instance wearing two hats, which the architecture is specifically shaped to allow.
Money in: entitlement licensing
The inbound direction is the comfortable one. A customer buys a license the same way they would buy any subscription — it is just a tariff plan — and in return the hub hands back a license token. Here is where it gets interesting. The hub acts as a license authority. It holds an Ed25519 signing key and signs every token, which means a downstream deployment can verify that token offline, with nothing more than the public key, without calling home on every single request.
Ed25519 is a deliberate pick, not a buzzword. The keys are short, verification is fast, and you can safely hand signatures to a customer’s own environment because your private signing key never leaves the hub. A leaked token cannot be edited into a higher tier, because the moment the payload changes, the signature stops verifying.
And the token is not a flat “paid / not paid” flag. It carries a features list, and that list is the thing that gates capability. One plan unlocks a set of features; a richer plan unlocks more; an expired or downgraded plan simply narrows the set. The enforcement point sits in the core security layer so it stays generic, while the meaning of each individual feature flag belongs to whichever plugin owns that capability. The shape reads cleanly:
customer buys a license plan
-> hub (license authority) signs a token with Ed25519
-> token embeds { features: [...], expiry, subject }
-> downstream verifies the signature offline
-> the features list decides which capabilities are live
For an operator this rail is the low-drama one: you are selling your own work, the compliance surface is ordinary subscription billing, and the cryptography does the anti-forgery work for free. If you want to see which capabilities are packaged as plugins — and therefore gateable this way — the plugin catalog is where they live.
Money out: Connect-style partner payouts
The outbound direction is where the hub stops behaving like a product and starts behaving like a marketplace ledger. Instead of selling directly, you let partners sell on your behalf and you pay them a commission. This follows the familiar Stripe-Connect pattern: partners onboard as connected accounts, referred sales get attributed back to whoever sent them, and commission accrues through a defined lifecycle before a single cent actually moves.
That lifecycle is the part worth slowing down on, because commission accounting punishes carelessness. A referred sale walks through four states:
- pending — the referred sale happened, but it is not safe to pay on yet. It could still be refunded, disputed, or clawed back.
- confirmed — the sale has settled and the commission is genuinely owed.
- reversed — the underlying sale was refunded or charged back, so the accrued commission is cancelled before it is ever paid.
- paid — the commission has actually landed in the partner’s connected account.
Every transition is designed to be idempotent, and that is not gold-plating. The same webhook or settlement event can and will arrive twice, and a retry must never double-pay a partner or double-count a reversal. Each state change is keyed so that replaying it is a harmless no-op.
The actual movement of money runs through a provider-agnostic port called IConnectProvider, so the accrual ledger does not marry itself to any one processor. Stripe is the first implementation behind that seam, but the seam is the point — a second provider can slot in later without rewriting the commission engine:
referred sale -> accrual (pending)
-> settlement -> confirmed
-> refund / chargeback -> reversed (no payout)
-> payout run -> IConnectProvider.pay(account) -> paid
Why one event can feed both directions
The two rails coexist because they touch different parts of the same generic spine. Licensing rides the tariff-plan and token-signing path; payouts ride the sale-attribution and settlement path. Neither owns the core, so switching one on does not entangle the other.
The satisfying case is a single sale feeding both directions at once. A partner refers a customer who buys a license plan. The inbound rail signs the token and gates the customer’s features. The outbound rail attributes that same sale to the referring partner, accrues commission in pending, and only promotes it to confirmed once the sale settles. If the customer refunds inside the window, the license entitlement lapses on one side and the commission flips to reversed on the other. One event, two rails, a consistent outcome. Because it all lives on one Postgres instance and one admin surface, the operator has a single place to reconcile everything: which licenses are live, which commissions are owed, which reversed, which paid. The documentation covers how the plugin layer wires these paths in without the core ever learning what a “license” or a “commission” means.
The honest part
The outbound rail is the one that will bite you if you mistake it for pure software. Running partner payouts means you inherit your payment processor’s onboarding and KYC obligations for every connected account, and you step into money-transmission and compliance territory. That is a legal posture, not a config toggle. VBWD hands you the mechanism — attribution, an idempotent accrual lifecycle, and a provider port to move funds — but it does not hand you the license to move that money or the compliance program around it. That layer stays yours.
The reversed state deserves a second mention as a deliberate defense. It exists so you never pay commission on money that later evaporates in a refund or chargeback. It makes that failure mode structural instead of a manual clawback scramble — but it cannot recover funds that have already left; it only stops you paying on money that never truly settled.
On cost: VBWD is source-available under BSL 1.1. Commercial use is free while annual VBWD-attributable sales stay below the value of 6.7 BTC per year; cross that and you need a commercial license. Source-available means the source is open, not that the licensing obligation disappears — it is not public-domain and it is never given away with no terms at all. The pricing page lays out the threshold and what crossing it actually means.
And the status, stated plainly: this is the platform’s designed monetization architecture. The signing authority and the Connect-style payout lifecycle are the intended shape. Parts are shipping and parts are still being built, so treat this as the direction and the seams that already exist — not a promise that every state transition is production-hardened today. The real takeaway is smaller and more durable than any feature checklist: you do not have to choose which way the money flows. Build the core to not care, and one instance can carry both.
Learn more about VBWD
VBWD is a self-hosted, source-available platform for building subscription products, marketplaces, and AI-powered apps. Explore it further:
- 🌐 Website and documentation: vbwd.cc — see the plugins, architecture, and developer docs.
- 💻 Source code and plugins on GitHub: github.com/VBWD-platform
- 🎥 Watch VBWD in action: demo video 1 and demo video 2
- 💼 Follow the project on LinkedIn: linkedin.com/company/vbwd
VBWD is source-available — get the SDK on GitHub.