Two-sided services marketplace: clients post orders, specialists respond, both sides leave reviews, and promotion is paid through Stripe.
Challenge
Clients need a trustworthy way to find a specialist, specialists need a steady flow of orders. The platform had to build trust on both sides and earn without charging for access.
Result
Separate client and specialist accounts, orders with categories and files, a searchable catalogue, two-way ratings and paid promotion. The interface runs in three languages.
Key features
Client & specialist accounts
Orders with attachments
Specialist catalogue & search
Two-way reviews & ratings
Paid promotion (Stripe)
Media uploads
Three languages
Role-based access
How it's built
A two-sided services marketplace: customers post a job, verified specialists respond with offers, and both sides rate each other afterwards. These are the decisions that shaped it.
3
User roles
4
Order states
3
Subscription tiers
UA·RU·EN
Languages
Two sides, modeled apart
A customer and a specialist are not one user with a role flag. They share almost no data: a specialist owns a profile, portfolio, subscription and rating; a customer owns orders. We modeled them as separate entities behind one session-based auth layer.
Permissions stay unambiguous — an endpoint belongs to one side, never to "a user who might be either". The public profile is split from the account record too, keeping constantly-written data like rating and subscription off the row authentication depends on.
The marketplace loop
Four states carry the transaction. A customer publishes an OPEN order — category, city, deadline, attachments. Specialists submit responses, which are offers against it. The customer accepts one, moving the order to IN_PROGRESS, then COMPLETED or CANCELLED.
Responses are their own records rather than a direct assignment, so a customer compares several specialists instead of being matched to one.
Both sides of the loop, as the product explains it to its own users
Finding the right specialist
Discovery runs on what and where. Orders and profiles both bind to a category and a city, so a plumber in Lviv never surfaces for a job in Odesa.
There is no separate search engine. At this catalogue size, indexed PostgreSQL queries over category, city and rating are faster to ship and cheaper to run than adding Meilisearch, and they keep results consistent with the data. Subscription tier feeds into ranking — which is what makes paid placement worth buying without letting it override relevance.
Search is built on the two axes that matter: service and city
Keeping the deal on the platform
The hardest commercial problem for a services marketplace is two parties meeting once and then dealing off-platform. Contact details a customer marks confidential go only to the specialist they actually choose — not to everyone who responds. That single rule keeps the incentive to stay inside the system alive past the first message.
Reputation that cuts both ways
Reviews run in both directions. A one-sided rating protects only the buyer, but here the specialist carries just as much risk — no-shows, scope disputes, non-payment. Visible history on both sides makes the platform safe to work on, not only to buy from.
Monetization without a paywall on access
Posting an order and responding to one are free. Specialists pay for reach instead, through subscription tiers and sponsored placement billed with Stripe. Charging per lead would tax exactly the behaviour the marketplace wants more of.
Subscription state is driven by Stripe webhooks — ACTIVE, PAST_DUE, UNPAID, CANCELED — and access checks read that live status, so a failed payment narrows reach instead of leaving a paid feature open.
Three subscription tiers, billed through Stripe
What production demanded
Notifications are events, not calls: each action emits one and handlers turn it into an in-app record and an email, so business logic never learns how to send mail. Complaints run a real state machine worked from an admin panel — without a moderation path a services marketplace fills with disputes it cannot resolve. Rate limiting, HTTP hardening, email verification and Cloudinary-hosted media were in from the first deploy.
The result
A live services marketplace running the full loop — post, respond, hire, deliver, review, pay — with subscription monetization, moderation and three languages, in production at services-helper.com.