← All projects

Virem

A multivendor marketplace on headless WooCommerce, and the security lesson in it.

Virem screenshot
2021–2022
Ran
2
Surfaces
0
Tests
01

The problem

A marketplace is two products. Shoppers need a fast catalogue and a checkout that works on a patchy connection; sellers need onboarding, listings and orders. Building both from scratch for a launch with no traffic yet is how marketplaces die before anyone visits them.

02

What I built

Two Next.js front ends against a headless WooCommerce install with Dokan for multivendor: a storefront with catalogue, per-vendor stores, cart, customer accounts and order history, and a separate seller dashboard for listings, orders and store settings.

Both were built out on commercial React templates rather than from nothing, which is the decision that made a two-surface marketplace possible at all at that size. The integration work, the auth, the vendor provisioning and the checkout are mine; the component library and the page furniture were bought.

03

Decisions I'd defend

Vendor onboarding is one chain rather than three forms. Registering creates the WordPress user, exchanges the credentials for a token, then calls Dokan to provision the store, so a seller signs up once and lands in a working dashboard instead of signing up and then waiting on an admin.

Delivery pricing is a hardcoded table of local neighbourhoods rather than a shipping engine. For a marketplace serving one city, a lookup that a non-technical operator can read and correct beats a rules engine nobody can audit.

Buying the templates. There was no design capacity and two surfaces to ship, and the parts that actually differentiate a marketplace are the vendor flow and the catalogue integration, not the button styles.

04

What I would do differently

The WooCommerce API credentials were kept in client-side code, which meant they were readable by anyone who opened devtools, with write access to customers and orders. That is the mistake I would fix first and the reason I no longer link the repository. The correct shape is a server route that holds the credentials and exposes only the operations the browser is allowed to perform.

Card payments were wired up and then commented out before launch, so the shipped build accepted cash on delivery only. Leaving a dead branch behind a live-looking option is worse than removing the option.

There were no tests, on a codebase handling orders.

05

Where it is now

Shut down. The storefront build still resolves but the WordPress backend behind it is gone, so it is a shell.