Model OTC vs prescription products, geo-block by country, handle prescriptions, keep an audit trail and honour GDPR — the technical building blocks for a compliant EU online pharmacy, self-hosted.
Generic e-commerce ignores what makes pharmacy hard; VBWD’s shop engine provides the technical controls an EU online pharmacy needs — though the licence is still yours to obtain.
Selling paracetamol online looks, on the surface, like selling anything else: a product page, a cart, a payment button. Then a regulator asks where your prescription verification happens, which member states you ship to, whether your OTC and prescription-only lines are actually distinguishable in the database, and where health-related purchase data physically lives. At that point most general-purpose e-commerce stacks run out of answers.
This article is honest about one thing up front: no software makes a pharmacy compliant. Operating a legally-registered online pharmacy in the EU requires the appropriate national registration and licences, a responsible registered pharmacist, and legal review under your member state’s rules. What a shop engine can do is give you technical building blocks that map cleanly onto those obligations, so the compliance work is a configuration and process exercise rather than a fight with the software. VBWD’s shop engine is built to be that kind of foundation, not a certificate.
Why generic e-commerce fails for pharmacy
Off-the-shelf shop platforms model a “product” as a single flat shape: title, price, image, stock. Pharmacy products are not one shape. An OTC analgesic, a prescription-only antibiotic, and an age-restricted product each carry different mandatory attributes and different rules for who may buy them and from where.
Generic platforms also assume you want to sell to everyone who can reach the URL. Pharmacy is the opposite: EU rules for online medicine sales are national, set per country, so your default posture must be to restrict and then selectively permit. Bolting country logic onto a platform that assumes global reach tends to leave gaps.
Finally, most stacks treat order data as commercial data. A prescription upload, or the fact that someone bought a specific medicine, is health-related data under GDPR and deserves stricter handling than a T-shirt order. The architecture has to respect that from the start.
The building blocks, mapped to EU requirements
VBWD is a self-hosted, source-available platform: Python/Flask, PostgreSQL, Vue 3, Docker, with an agnostic core and everything domain-specific implemented as plugins. Shop, product types, discounts, invoicing, and payments are all plugins on that platform. Below, each capability is paired with the pharmacy obligation it supports.
Product types for OTC, prescription, and restricted lines
The shop engine models a product type as an additive cluster of custom fields registered through a product-type registry. Rather than forcing every product into one schema, you define a type per category and attach only the fields that category needs.
- OTC: standard commercial fields plus active ingredient and pack size.
- Prescription-only: the same, plus a prescription-required flag and fields for the verification workflow.
- Restricted: additional eligibility or age-gating attributes.
This gives you a database-level, queryable distinction between prescription and OTC products — the clear separation regulators expect — instead of a convention that lives only in a category name. You can read more about how the platform composes these clusters in the architecture overview.
Country access control for national rules
Because online-medicine rules differ by member state, jurisdiction control is a first-class need. The platform’s CMS supports country-based access, so you can restrict which markets see and reach given pages and product areas. Combined with a deny-by-default posture, this lets you serve only the countries where you hold the correct registration, rather than exposing your full catalogue to the entire EU and hoping.
Catalogue with a shared filter and pagination contract
The shop catalogue uses a shared filter and pagination contract, so browsing, filtering, and paging behave consistently across product types. In practice this means a customer can filter to only OTC products, or a pharmacist-facing view can filter to prescription lines awaiting verification, using the same predictable mechanism. The consistency matters when you later attach audit and reporting on top of it.
Age and eligibility gating
For age-restricted and eligibility-restricted products, the extra fields on a product type feed gating patterns at the point of sale. The gate is expressed as product data plus order-time checks, which keeps the rule attached to the product rather than hard-coded into a single checkout screen. You still design the exact eligibility policy — the engine gives you the place to attach it.
A prescription-handling workflow
Prescription handling is where the pieces combine. There is no single “prescription” button; instead you compose one from parts you already have:
- A product type flags the line as prescription-required.
- Order data carries the prescription’s state through fulfilment.
- Secure messaging handles uploading a prescription and the pharmacist’s verification exchange, keeping that sensitive material off email.
The registered pharmacist remains the decision-maker. The software’s job is to make sure a prescription-required item cannot progress to fulfilment without the verification step being recorded — a control you configure, not a legal guarantee the platform issues.
An audit trail via the event bus and signed webhooks
Verifiable records are central to pharmacy operations. VBWD’s core emits domain events on an event bus, and you can subscribe outbound signed webhooks to relay those events to an external audit log or an existing pharmacy management system. Because the webhooks are signed, the receiving system can verify authenticity. This gives you an append-only trail of who did what and when, feeding a system of record you control. See the features overview for the event and webhook surface.
Pricing, VAT, and invoicing
Medicines frequently sit under specific or reduced VAT rates that vary by country. The unified price model carries per-line tax so VAT is computed and shown per line item rather than as an opaque total, and the invoicing plugin produces the corresponding documents. That per-line transparency is what makes cross-border VAT handling auditable later.
Self-hosted, EU data residency, and GDPR
Because a purchase of a specific medicine — and any uploaded prescription — is health-related personal data, where that data lives is not a detail. VBWD is self-hosted, so you choose the hosting, including keeping data resident in the EU. There is no obligatory third-party SaaS in the transaction path holding your patients’ health data. This supports GDPR obligations around health data; it does not discharge them. You still need your lawful basis, your retention policy, your data-processing records, and your DPO arrangements where required.
Swappable payment providers
Payments are implemented as swappable adapters, so you can select providers that fit your market and your acquirer relationships rather than being locked to one processor. Details of the payment and billing surface are in the billing documentation.
CMS for mandatory legal pages and the common logo
Legally-operating online pharmacies in the EU must display mandatory information — including registered pharmacist and operator details — and link back from the EU common logo for online medicine sellers to the relevant national register entry. The platform’s CMS is where you author and maintain those legal pages and place the common-logo linkback, keeping the required disclosures under version control alongside the shop.
A worked configuration example
Suppose you are registered to sell OTC medicines in Germany and Austria only, with a prescription workflow for a limited prescription-only range. A rough shape of the configuration looks like this:
product-types:
otc:
fields: [active_ingredient, pack_size, vat_rate]
prescription:
fields: [active_ingredient, pack_size, vat_rate,
prescription_required: true,
prescription_status] # unverified | verified | rejected
age_restricted:
fields: [active_ingredient, pack_size, vat_rate,
min_age]
country-access:
default: deny
allow: [DE, AT]
workflow:
prescription_required:
block_fulfilment_until: prescription_status == verified
channel: secure_messaging # upload + pharmacist review
audit:
webhook:
events: [order.created, prescription.verified,
prescription.rejected, order.fulfilled]
signed: true
target: https://your-pharmacy-system.internal/audit
data:
hosting: self_hosted
residency: eu
This is illustrative, not a drop-in file: the exact field names, event names, and options follow the plugin configuration documented in the platform docs. The point is that each obligation — jurisdiction, product distinction, prescription control, audit, residency — has an explicit, reviewable home.
Honest limits
Read this part twice. VBWD is not certified, approved, or endorsed by any medicines regulator, and running your shop on it does not make your pharmacy legal. It gives you technical building blocks; it does not give you a licence.
- You must hold the appropriate national registration and licences for every country you sell into. These rules are national and differ per member state.
- You need a responsible registered pharmacist accountable for dispensing decisions.
- You must obtain independent legal and regulatory review before going live, and keep it current as rules change.
- The platform does not implement Falsified Medicines Directive serialization or verification against national medicines verification systems. Where the FMD context applies to your operation, that is a separate obligation you address with the appropriate systems.
- GDPR compliance for health data is a programme — lawful basis, retention, records, DPO — not a switch the software flips.
None of these are gaps in the software; they are the parts of pharmacy operation that are legal and human by design, and no shop engine should pretend otherwise.
Takeaway
A compliance-ready pharmacy shop is one where every regulatory obligation has a clear technical home: prescription and OTC products are distinct in the data, sales are geo-restricted to the countries you are registered in, prescription verification is a recorded control, health data stays on infrastructure you govern in the EU, and every significant action leaves a signed, auditable trace. VBWD’s shop engine gives you those homes on a self-hosted, source-available platform you can inspect and extend. The licences, the pharmacist, and the legal sign-off remain yours to hold — which is exactly as it should be.
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



